diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 71287c4ba6fc..135f7c76afa6 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2526,6 +2526,12 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, int timo) umtxq_busy(&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 */ while ((state & wrflags) && !(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_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) && (state & URWLOCK_WRITE_WAITERS) == 0) { oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_WAITERS);