Date: Tue, 13 Oct 2009 13:47:30 +0000 (UTC) From: Attilio Rao <attilio@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r198032 - in stable/7/sys: . contrib/pf kern Message-ID: <200910131347.n9DDlUcE007223@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: attilio Date: Tue Oct 13 13:47:30 2009 New Revision: 198032 URL: http://svn.freebsd.org/changeset/base/198032 Log: MFC r197476: In function do_rw_wrlock, when a writer got an error and before returning, check if there are readers blocked by us via URWLOCK_WRITE_WAITERS flag, and resume the readers. The error must be EAGAIN, otherwise there must have memory problem, and nobody can rescue the buggy application. Approved by: davidxu Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/kern/kern_umtx.c Modified: stable/7/sys/kern/kern_umtx.c ============================================================================== --- stable/7/sys/kern/kern_umtx.c Tue Oct 13 13:08:05 2009 (r198031) +++ stable/7/sys/kern/kern_umtx.c Tue Oct 13 13:47:30 2009 (r198032) @@ -2556,6 +2556,7 @@ do_rw_wrlock(struct thread *td, struct u uint32_t flags; int32_t state, oldstate; int32_t blocked_writers; + int32_t blocked_readers; int error; uq = td->td_umtxq; @@ -2564,6 +2565,7 @@ do_rw_wrlock(struct thread *td, struct u if (error != 0) return (error); + blocked_readers = 0; for (;;) { state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); while (!(state & URWLOCK_WRITE_OWNER) && URWLOCK_READER_COUNT(state) == 0) { @@ -2575,8 +2577,18 @@ do_rw_wrlock(struct thread *td, struct u state = oldstate; } - if (error) + if (error) { + if (!(state & (URWLOCK_WRITE_OWNER|URWLOCK_WRITE_WAITERS)) && + blocked_readers != 0) { + umtxq_lock(&uq->uq_key); + umtxq_busy(&uq->uq_key); + umtxq_signal_queue(&uq->uq_key, INT_MAX, UMTX_SHARED_QUEUE); + umtxq_unbusy(&uq->uq_key); + umtxq_unlock(&uq->uq_key); + } + break; + } /* grab monitor lock */ umtxq_lock(&uq->uq_key); @@ -2627,7 +2639,9 @@ sleep: break; state = oldstate; } - } + blocked_readers = fuword32(&rwlock->rw_blocked_readers); + } else + blocked_readers = 0; umtxq_lock(&uq->uq_key); umtxq_unbusy(&uq->uq_key);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910131347.n9DDlUcE007223>