summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheloha <cheloha@cvs.openbsd.org>2020-04-06 02:44:32 +0000
committercheloha <cheloha@cvs.openbsd.org>2020-04-06 02:44:32 +0000
commit2060ccf0a19bb2432fe57149c593f243cd14a32f (patch)
treed54233b1012f6fa2ba91614476024ab45b001e9e
parent247456ed6b97f6b93168cbd8b406ff778627a278 (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@.
-rw-r--r--sys/kern/sys_futex.c4
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);