summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheloha <cheloha@cvs.openbsd.org>2020-12-24 01:16:15 +0000
committercheloha <cheloha@cvs.openbsd.org>2020-12-24 01:16:15 +0000
commit85548d280ccb7aabc8952779a93f84ba97e7b3fe (patch)
tree29042be1028dd82c07c86225eab2e3ebbda99e71
parent519d2e3ecc2dce33b639b70ad3334db0f16f4f6a (diff)
tsleep(9): add global "nowake" channel for threads avoiding wakeup(9)
It would be convenient if there were a channel a thread could sleep on to indicate they do not want any wakeup(9) broadcasts. The easiest way to do this is to add an "int nowake" to kern_synch.c and extern it in sys/systm.h. You use it like this: #include <sys/systm.h> tsleep_nsec(&nowait, ...); There is now no need to handroll a local dead channel, e.g. int chan; tsleep_nsec(&chan, ...); which expands the stack. Local dead channels will be replaced with &nowake in later patches. One possible problem with this "one global channel" approach is sleep queue congestion. If you have lots of threads sleeping on &nowake you might slow down a wakeup(9) on a different channel that hashes into the same queue. Unsure how much of problem this actually is, if at all. NetBSD and FreeBSD have a "pause" interface in the kernel that chooses a suitable channel automatically. To keep things simple and avoid adding a new interface we will start with this global channel. Discussed with mpi@, claudio@, kettenis@, and deraadt@. Basically designed by kettenis@, who vetoed my other proposals. Bugs caught by deraadt@, tb@, and patrick@.
-rw-r--r--sys/kern/kern_synch.c10
-rw-r--r--sys/sys/systm.h4
2 files changed, 12 insertions, 2 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index c41f35e54ba..e266de8ef5d 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_synch.c,v 1.172 2020/12/07 16:55:29 mpi Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.173 2020/12/24 01:16:14 cheloha Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@@ -87,6 +87,11 @@ sleep_queue_init(void)
TAILQ_INIT(&slpque[i]);
}
+/*
+ * Global sleep channel for threads that do not want to
+ * receive wakeup(9) broadcasts.
+ */
+int nowake;
/*
* During autoconfiguration or after a panic, a sleep will simply
@@ -119,6 +124,7 @@ tsleep(const volatile void *ident, int priority, const char *wmesg, int timo)
#endif
KASSERT((priority & ~(PRIMASK | PCATCH)) == 0);
+ KASSERT(ident != &nowake || ISSET(priority, PCATCH) || timo != 0);
#ifdef MULTIPROCESSOR
KASSERT(timo || _kernel_lock_held());
@@ -213,6 +219,7 @@ msleep(const volatile void *ident, struct mutex *mtx, int priority,
#endif
KASSERT((priority & ~(PRIMASK | PCATCH | PNORELOCK)) == 0);
+ KASSERT(ident != &nowake || ISSET(priority, PCATCH) || timo != 0);
KASSERT(mtx != NULL);
if (priority & PCATCH)
@@ -301,6 +308,7 @@ rwsleep(const volatile void *ident, struct rwlock *rwl, int priority,
int error, status;
KASSERT((priority & ~(PRIMASK | PCATCH | PNORELOCK)) == 0);
+ KASSERT(ident != &nowake || ISSET(priority, PCATCH) || timo != 0);
rw_assert_anylock(rwl);
status = rw_status(rwl);
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index c98203833b3..49556975a7d 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: systm.h,v 1.148 2020/08/26 03:29:07 visa Exp $ */
+/* $OpenBSD: systm.h,v 1.149 2020/12/24 01:16:14 cheloha Exp $ */
/* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */
/*-
@@ -107,6 +107,8 @@ extern struct vnode *rootvp; /* vnode equivalent to above */
extern dev_t swapdev; /* swapping device */
extern struct vnode *swapdev_vp;/* vnode equivalent to above */
+extern int nowake; /* dead wakeup(9) channel */
+
struct proc;
struct process;
#define curproc curcpu()->ci_curproc