In both do_rw_wrlock() and do_rw_rdlock() after r304808, do not

obliterate possible error from sleep with errors from
umtxq_check_susp(), when looping to clear URWLOCK_{READ,WRITE}_WAITERS.

Noted and reviewed by:	vangyzen
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2016-08-25 19:15:02 +00:00
parent d64004f09e
commit 0f2d97838d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=304812

View File

@ -2609,7 +2609,7 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, struct _umtx
uint32_t flags, wrflags; uint32_t flags, wrflags;
int32_t state, oldstate; int32_t state, oldstate;
int32_t blocked_readers; int32_t blocked_readers;
int error, rv; int error, error1, rv;
uq = td->td_umtxq; uq = td->td_umtxq;
error = fueword32(&rwlock->rw_flags, &flags); error = fueword32(&rwlock->rw_flags, &flags);
@ -2758,9 +2758,12 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, struct _umtx
if (oldstate == state) if (oldstate == state)
break; break;
state = oldstate; state = oldstate;
error = umtxq_check_susp(td); error1 = umtxq_check_susp(td);
if (error != 0) if (error1 != 0) {
if (error == 0)
error = error1;
break; break;
}
} }
} }
@ -2783,7 +2786,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, struct _umtx_time *timeo
int32_t state, oldstate; int32_t state, oldstate;
int32_t blocked_writers; int32_t blocked_writers;
int32_t blocked_readers; int32_t blocked_readers;
int error, rv; int error, error1, rv;
uq = td->td_umtxq; uq = td->td_umtxq;
error = fueword32(&rwlock->rw_flags, &flags); error = fueword32(&rwlock->rw_flags, &flags);
@ -2929,14 +2932,17 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, struct _umtx_time *timeo
if (oldstate == state) if (oldstate == state)
break; break;
state = oldstate; state = oldstate;
error = umtxq_check_susp(td); error1 = umtxq_check_susp(td);
/* /*
* We are leaving the URWLOCK_WRITE_WAITERS * We are leaving the URWLOCK_WRITE_WAITERS
* behind, but this should not harm the * behind, but this should not harm the
* correctness. * correctness.
*/ */
if (error != 0) if (error1 != 0) {
if (error == 0)
error = error1;
break; break;
}
} }
rv = fueword32(&rwlock->rw_blocked_readers, rv = fueword32(&rwlock->rw_blocked_readers,
&blocked_readers); &blocked_readers);