svn commit: r200447 - in head: share/man/man9 sys/kern sys/sys
Attilio Rao
attilio at freebsd.org
Mon Dec 14 09:02:56 PST 2009
2009/12/14 John Baldwin <jhb at freebsd.org>:
> On Saturday 12 December 2009 4:31:07 pm Attilio Rao wrote:
>> Author: attilio
>> Date: Sat Dec 12 21:31:07 2009
>> New Revision: 200447
>> URL: http://svn.freebsd.org/changeset/base/200447
>>
>> Log:
>> In current code, threads performing an interruptible sleep (on both
>> sxlock, via the sx_{s, x}lock_sig() interface, or plain lockmgr), will
>> leave the waiters flag on forcing the owner to do a wakeup even when if
>> the waiter queue is empty.
>> That operation may lead to a deadlock in the case of doing a fake wakeup
>> on the "preferred" (based on the wakeup algorithm) queue while the other
>> queue has real waiters on it, because nobody is going to wakeup the 2nd
>> queue waiters and they will sleep indefinitively.
>>
>> A similar bug, is present, for lockmgr in the case the waiters are
>> sleeping with LK_SLEEPFAIL on. In this case, even if the waiters queue
>> is not empty, the waiters won't progress after being awake but they will
>> just fail, still not taking care of the 2nd queue waiters (as instead the
>> lock owned doing the wakeup would expect).
>>
>> In order to fix this bug in a cheap way (without adding too much locking
>> and complicating too much the semantic) add a sleepqueue interface which
>> does report the actual number of waiters on a specified queue of a
>> waitchannel (sleepq_sleepcnt()) and use it in order to determine if the
>> exclusive waiters (or shared waiters) are actually present on the lockmgr
>> (or sx) before to give them precedence in the wakeup algorithm.
>> This fix alone, however doesn't solve the LK_SLEEPFAIL bug. In order to
>> cope with it, add the tracking of how many exclusive LK_SLEEPFAIL waiters
>> a lockmgr has and if all the waiters on the exclusive waiters queue are
>> LK_SLEEPFAIL just wake both queues.
>>
>> The sleepq_sleepcnt() introduction and ABI breakage require
>> __FreeBSD_version bumping.
>
> Hmm, do you need an actual count of waiters or would a 'sleepq_empty()'
> (similar to turnstile_empty()) method be sufficient?
I need the count in order to fix properly LK_SLEEPFAIL case (the idea
is: track exclusive waiters with LK_SLEEPFAIL on; if the number is
equal to the actual sleepers on the queue then wake up both queues,
otherwise nobody is going to take care of the shared waiters queue).
Attilio
--
Peace can only be achieved by understanding - A. Einstein
More information about the svn-src-head
mailing list