summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_rwlock.c
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2019-11-30 11:19:17 +0000
committervisa <visa@openbsd.org>2019-11-30 11:19:17 +0000
commitde60e9182e3ea7b387cda2ea58c0a4cb67e2fb14 (patch)
tree0d9cc081abbdfb023b4de31f99779e04103d947a /sys/kern/kern_rwlock.c
parentNot being able to create a resolver is not a fatal condition in unwind, (diff)
downloadwireguard-openbsd-de60e9182e3ea7b387cda2ea58c0a4cb67e2fb14.tar.xz
wireguard-openbsd-de60e9182e3ea7b387cda2ea58c0a4cb67e2fb14.zip
Move kernel locking inside the sleep machinery. This enables calling
rwsleep(9) with PCATCH and rw_enter(9) with RW_INTR without the kernel lock. In addition, now tsleep(9) with PCATCH should be safe to use without the kernel lock if the sleep is purely time-based. Tested by anton@, cheloha@, chris@ OK anton@, cheloha@
Diffstat (limited to 'sys/kern/kern_rwlock.c')
-rw-r--r--sys/kern/kern_rwlock.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index a78cba7b6d6..686803f3317 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_rwlock.c,v 1.43 2019/11/29 12:41:33 mpi Exp $ */
+/* $OpenBSD: kern_rwlock.c,v 1.44 2019/11/30 11:19:17 visa Exp $ */
/*
* Copyright (c) 2002, 2003 Artur Grabowski <art@openbsd.org>
@@ -231,7 +231,7 @@ rw_enter(struct rwlock *rwl, int flags)
*/
unsigned int spin = (_kernel_lock_held()) ? 0 : RW_SPINS;
#endif
- int error;
+ int error, prio;
#ifdef WITNESS
int lop_flags;
@@ -273,9 +273,12 @@ retry:
if (flags & RW_NOSLEEP)
return (EBUSY);
- sleep_setup(&sls, rwl, op->wait_prio, rwl->rwl_name);
+ prio = op->wait_prio;
if (flags & RW_INTR)
- sleep_setup_signal(&sls, op->wait_prio | PCATCH);
+ prio |= PCATCH;
+ sleep_setup(&sls, rwl, prio, rwl->rwl_name);
+ if (flags & RW_INTR)
+ sleep_setup_signal(&sls);
do_sleep = !rw_cas(&rwl->rwl_owner, o, set);