summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2020-03-02 13:55:15 +0000
committerbluhm <bluhm@openbsd.org>2020-03-02 13:55:15 +0000
commit9467af2c6de3b99bb8540c86153464a4f9026d41 (patch)
tree74a78e8e745626c40ec6e5c783a3415ba24aa75e
parentAccidently some tests were never running. Make regress target names (diff)
downloadwireguard-openbsd-9467af2c6de3b99bb8540c86153464a4f9026d41.tar.xz
wireguard-openbsd-9467af2c6de3b99bb8540c86153464a4f9026d41.zip
msleep() and rwsleep() allow to release the lock when going to
sleep. If sleep_setup_signal() detects that the process has been stopped, it calls mi_switch() instead of sleeping. Then the lock was not released and other processes got stuck. Move the mtx_leave() and rw_exit() before sleep_setup_signal() to prevent that a stopped process holds a short term kernel lock. input kettenis@; OK visa@ tedu@
-rw-r--r--sys/kern/kern_synch.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 2f1a754aaf3..2360b5ff7dd 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_synch.c,v 1.162 2020/01/30 08:51:27 mpi Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.163 2020/03/02 13:55:15 bluhm Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@@ -259,7 +259,6 @@ msleep(const volatile void *ident, struct mutex *mtx, int priority,
sleep_setup(&sls, ident, priority, wmesg);
sleep_setup_timeout(&sls, timo);
- sleep_setup_signal(&sls);
/* XXX - We need to make sure that the mutex doesn't
* unblock splsched. This can be made a bit more
@@ -268,6 +267,8 @@ msleep(const volatile void *ident, struct mutex *mtx, int priority,
spl = MUTEX_OLDIPL(mtx);
MUTEX_OLDIPL(mtx) = splsched();
mtx_leave(mtx);
+ /* signal may stop the process, release mutex before that */
+ sleep_setup_signal(&sls);
error = sleep_finish_all(&sls, 1);
@@ -320,9 +321,10 @@ rwsleep(const volatile void *ident, struct rwlock *rwl, int priority,
sleep_setup(&sls, ident, priority, wmesg);
sleep_setup_timeout(&sls, timo);
- sleep_setup_signal(&sls);
rw_exit(rwl);
+ /* signal may stop the process, release rwlock before that */
+ sleep_setup_signal(&sls);
error = sleep_finish_all(&sls, 1);