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
This commit is contained in:
Mateusz Guzik 2017-11-26 21:10:47 +00:00
parent 41eeef87ca
commit e57b2b1830

View File

@ -769,6 +769,11 @@ __rw_runlock_hard(struct rwlock *rw, struct thread *td, uintptr_t v
turnstile_chain_lock(&rw->lock_object); turnstile_chain_lock(&rw->lock_object);
v = RW_READ_VALUE(rw); v = RW_READ_VALUE(rw);
retry_ts: retry_ts:
if (__predict_false(RW_READERS(v) > 1)) {
turnstile_chain_unlock(&rw->lock_object);
continue;
}
v &= (RW_LOCK_WAITERS | RW_LOCK_WRITE_SPINNER); v &= (RW_LOCK_WAITERS | RW_LOCK_WRITE_SPINNER);
MPASS(v & RW_LOCK_WAITERS); MPASS(v & RW_LOCK_WAITERS);