After busied the lock, re-read state word before checking waiters flag,
otherwise, the waiters bit may not be set and a wakeup is lost. Submitted by: justin.teller at gmail dot com MFC after: 3 days
This commit is contained in:
parent
e70f20b0e8
commit
676e6574a1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=203414
@ -2526,6 +2526,12 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, int timo)
|
|||||||
umtxq_busy(&uq->uq_key);
|
umtxq_busy(&uq->uq_key);
|
||||||
umtxq_unlock(&uq->uq_key);
|
umtxq_unlock(&uq->uq_key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* re-read the state, in case it changed between the try-lock above
|
||||||
|
* and the check below
|
||||||
|
*/
|
||||||
|
state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
|
||||||
|
|
||||||
/* set read contention bit */
|
/* set read contention bit */
|
||||||
while ((state & wrflags) && !(state & URWLOCK_READ_WAITERS)) {
|
while ((state & wrflags) && !(state & URWLOCK_READ_WAITERS)) {
|
||||||
oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_READ_WAITERS);
|
oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_READ_WAITERS);
|
||||||
@ -2658,6 +2664,12 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
|
|||||||
umtxq_busy(&uq->uq_key);
|
umtxq_busy(&uq->uq_key);
|
||||||
umtxq_unlock(&uq->uq_key);
|
umtxq_unlock(&uq->uq_key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* re-read the state, in case it changed between the try-lock above
|
||||||
|
* and the check below
|
||||||
|
*/
|
||||||
|
state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
|
||||||
|
|
||||||
while (((state & URWLOCK_WRITE_OWNER) || URWLOCK_READER_COUNT(state) != 0) &&
|
while (((state & URWLOCK_WRITE_OWNER) || URWLOCK_READER_COUNT(state) != 0) &&
|
||||||
(state & URWLOCK_WRITE_WAITERS) == 0) {
|
(state & URWLOCK_WRITE_WAITERS) == 0) {
|
||||||
oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_WAITERS);
|
oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_WAITERS);
|
||||||
|
Loading…
Reference in New Issue
Block a user