diff options
author | attilio <attilio@FreeBSD.org> | 2010-01-18 14:43:44 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2010-01-18 14:43:44 +0000 |
commit | 5fcd322a258801641a2695545efcab9501a0cd37 (patch) | |
tree | 29709102e329809b88986c1b346983ccccdbc4eb /share | |
parent | 6cec00d040aa95e296cf0160e205596abfcc3f61 (diff) | |
download | FreeBSD-src-5fcd322a258801641a2695545efcab9501a0cd37.zip FreeBSD-src-5fcd322a258801641a2695545efcab9501a0cd37.tar.gz |
MFC r200447,201703,201709-201710:
In current code, threads performing an interruptible sleep
will leave the waiters flag on forcing the owner to do a wakeup even
when the waiter queue is empty.
That operation may lead to a deadlock in the case of doing a fake wakeup
on the "preferred" 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.
Add a sleepqueue interface which does report the actual number of waiters
on a specified queue of a waitchannel and track if at least one sleepfail
waiter is present or not. In presence of this or empty "preferred" queue,
wakeup both waiters queues.
Discussed with: kib
Tested by: Pete French <petefrench at ticketswitch dot com>,
Justin Head <justin at encarnate dot com>
Diffstat (limited to 'share')
-rw-r--r-- | share/man/man9/sleepqueue.9 | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/share/man/man9/sleepqueue.9 b/share/man/man9/sleepqueue.9 index 144bdc0..d1d17cd 100644 --- a/share/man/man9/sleepqueue.9 +++ b/share/man/man9/sleepqueue.9 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 12, 2009 +.Dd January 18, 2010 .Dt SLEEPQUEUE 9 .Os .Sh NAME @@ -41,6 +41,7 @@ .Nm sleepq_remove , .Nm sleepq_signal , .Nm sleepq_set_timeout , +.Nm sleepq_sleepcnt , .Nm sleepq_timedwait , .Nm sleepq_timedwait_sig , .Nm sleepq_wait , @@ -77,6 +78,8 @@ .Fn sleepq_signal "void *wchan" "int flags" "int pri" "int queue" .Ft void .Fn sleepq_set_timeout "void *wchan" "int timo" +.Ft u_int +.Fn sleepq_sleepcnt "void *wchan" "int queue" .Ft int .Fn sleepq_timedwait "void *wchan" .Ft int @@ -355,6 +358,14 @@ One possible use is waking up a specific thread from a widely shared sleep channel. .Pp The +.Fn sleepq_sleepcnt +function offer a simple way to retrieve the number of threads sleeping for +the specified +.Fa queue , +given a +.Fa wchan . +.Pp +The .Fn sleepq_abort , .Fn sleepq_broadcast , and |