From e57b2b1830d2cc813e2e17d1eda15dba5b212969 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Sun, 26 Nov 2017 21:10:47 +0000 Subject: [PATCH] rw: fix runlock_hard when new readers show up When waiters/writer spinner flags are set no new readers can show up unless they already have a different rw rock read locked. The change in r326195 failed to take that into account - in presence of new readers it would spin until they all drain, which would be lead to trouble if e.g. they go off cpu and can get scheduled because of this thread. Reported by: pho --- sys/kern/kern_rwlock.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index 6ccc5e460e52..dd9823515a72 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -769,6 +769,11 @@ __rw_runlock_hard(struct rwlock *rw, struct thread *td, uintptr_t v turnstile_chain_lock(&rw->lock_object); v = RW_READ_VALUE(rw); retry_ts: + if (__predict_false(RW_READERS(v) > 1)) { + turnstile_chain_unlock(&rw->lock_object); + continue; + } + v &= (RW_LOCK_WAITERS | RW_LOCK_WRITE_SPINNER); MPASS(v & RW_LOCK_WAITERS);