diff options
author | cheloha <cheloha@cvs.openbsd.org> | 2020-04-06 02:44:32 +0000 |
---|---|---|
committer | cheloha <cheloha@cvs.openbsd.org> | 2020-04-06 02:44:32 +0000 |
commit | 2060ccf0a19bb2432fe57149c593f243cd14a32f (patch) | |
tree | d54233b1012f6fa2ba91614476024ab45b001e9e /sys/kern | |
parent | 247456ed6b97f6b93168cbd8b406ff778627a278 (diff) |
futex(2): FUTEX_WAIT: rwsleep_nsec(9) at least one nanosecond
mpi@ and I added a warning log to *sleep_nsec(9) last year to smoke
out division-to-zero bugs when converting kernel code from *sleep(9)
to the new interfaces. It whines if you tell it to sleep for zero
nanoseconds.
Now that rwsleep_nsec(9) is exposed to userspace via futex(2), though,
it is possible to get a legitimate zero-nanosecond timeout from the
user. This can cause a lot of logging, which apparently can cause
hiccups and hangs in Mesa.
As a quick fix we can round the timeout up to one nanosecond and
silence the warning. No logs, no delays, no hiccups or hangs.
--
Aside: it is unclear what we are supposed to do in the FUTEX_WAIT
zero-nanosecond timeout case: block for a tick or return ETIMEDOUT
immediately. The Linux futex(2) manpage does not mention the case.
It'd be nice to knew what the proper behavior is.
--
Prompted by matthieu@. Input from kettenis@ and deraadt@.
Tested by matthieu@, ajacoutot@.
In snaps since Mar 27 2020.
ok ajacoutot@, deraadt@, kettenis@.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/sys_futex.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/kern/sys_futex.c b/sys/kern/sys_futex.c index 140bb2b773e..2f77cc92764 100644 --- a/sys/kern/sys_futex.c +++ b/sys/kern/sys_futex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_futex.c,v 1.15 2020/03/20 17:17:31 cheloha Exp $ */ +/* $OpenBSD: sys_futex.c,v 1.16 2020/04/06 02:44:31 cheloha Exp $ */ /* * Copyright (c) 2016-2017 Martin Pieuchot @@ -244,7 +244,7 @@ futex_wait(uint32_t *uaddr, uint32_t val, const struct timespec *timeout, #endif if (ts.tv_sec < 0 || !timespecisvalid(&ts)) return EINVAL; - nsecs = MIN(TIMESPEC_TO_NSEC(&ts), MAXTSLP); + nsecs = MAX(1, MIN(TIMESPEC_TO_NSEC(&ts), MAXTSLP)); } f = futex_get(uaddr, flags | FT_CREATE); |