cvs commit: src/sys/kern kern_rwlock.c src/sys/sys rwlock.h

Jeff Roberson jroberson at chesapeake.net
Tue Apr 1 18:10:01 PDT 2008


On Wed, 2 Apr 2008, Attilio Rao wrote:

> 2008/4/2, Max Laier <max at love2party.net>:
>> On Wednesday 02 April 2008 00:52:45 Jeff Roberson wrote:
>> > On Wed, 2 Apr 2008, Max Laier wrote:
>> >> On Tuesday 01 April 2008 22:31:55 Attilio Rao wrote:
>> >>> attilio     2008-04-01 20:31:55 UTC
>> >>>
>> >>>   FreeBSD src repository
>> >>>
>> >>>   Modified files:
>> >>>     sys/kern             kern_rwlock.c
>> >>>     sys/sys              rwlock.h
>> >>>   Log:
>> >>>   Add rw_try_rlock() and rw_try_wlock() to rwlocks.
>> >>>   These functions try the specified operation (rlocking and
>> >>> wlocking) and true is returned if the operation completes, false
>> >>> otherwise.
>> >>
>> >> hmmm ... I'm certainly missing something here, but what's a possible
>> >> usecase for these?  It seems there is not much you can do if you
>> >> can't obtain a rw_lock.  I can understand the need for sx_try_* where
>> >> you want to avoid sleeping, but I can't figure out the need for it on
>> >> a locking primitive that will only spin or wait (not 100% sure about
>> >> the terminology here).  This is especially strange for rw_try_wlock,
>> >> unless you plan to sleep manually on fail.  But then again you'd have
>> >> a good chance that you have to do it over and over again if timing is
>> >> unfortunate.
>> >
>> > I asked for it.  We have a try operation for mtx already.  I was
>> > experimenting with converting some code to use rwlocks from mtx and it
>> > required it.  The specific case is in the softdep code where it uses
>> > trylock to avoid deadlocking.  With trylock you can violate the
>> > lockorder.
>>
>>
>> Makes sense, thanks!  A little follow-up, though about something I'm
>>  wondering about for quite some time now.  Take the following scenario:
>>
>>  Thread A:  rw_rlock(RW) ... mtx_lock(MTX) ... UNLOCK
>>  Thread B:  mtx_lock(MTX) ... rw_rlock(RW) ... UNLOCK
>>  Thread C:  rw_wlock(RW) ... UNLOCK
>
> This can't deadlock simply because rw_rlock() is not mutually exclusive.

It can deadlock if there is a writer waiting in queue depending on whether 
we prefer readers or writers.  I think we should consider the 
reader/writer perference an implementation detail to prevent code like 
this from cropping up.

Readers are only allowed to proceed with a read lock if they already own a 
read lock, not just if the lock is already read locked.  This changed in 
current recently.  So a single recursive read acqusition can't deadlock 
but get multiple threads and a writer involved with writer preference and 
you can.

Jeff

>
>>  Can this deadlock?  How?
>>
>>  If thread C did: rw_wlock(RW) ... mtx_lock(MTX) ... UNLOCK or the other
>>  way around, I can see that it will[1] deadlock, but with the wlock
>>  without a lock order wrt the MTX, I can't see it.  Plus, can we teach
>>  WITNESS to keep quite about thread A and B unless we also see a lock
>>  order with the wlock and the mutex?
>
> You mean skipping possible LORs for shared instances of double-sided primitives?
>
> Thanks,
> Attilio
>
>
> -- 
> Peace can only be achieved by understanding - A. Einstein
>


More information about the cvs-src mailing list