]> git.lizzy.rs Git - plan9front.git/commit
ether82563: avoid deadlock due to icansleep() trying to acquire Rbpool.Lock
authorcinap_lenrek <cinap_lenrek@gmx.de>
Thu, 25 Jul 2013 23:51:03 +0000 (01:51 +0200)
committercinap_lenrek <cinap_lenrek@gmx.de>
Thu, 25 Jul 2013 23:51:03 +0000 (01:51 +0200)
commitac52599eef2ab79a64c30a8046a51b62501ca9ab
tree3857c15103a82a5a61fc0219b3590eeb040cba7d
parent2759b81decc991f756044942459ecc8ba92b32fd
ether82563: avoid deadlock due to icansleep() trying to acquire Rbpool.Lock

icansleep() violates the lock ordering due to the following cases:

rbfree(): ilock(Rbpool.Lock) -> wakeup(): spli(), lock(Rbpool.Rendez)
sleep(): splhi(), lock(Rbpool.Rendez) -> icansleep(): ilock(Rbpool.Lock)

erik fixed this moving the wakeup() out of the ilock() in rbfree(),
but i think it is an error to try acquiering a ilock in sleeps wait
condition function in general.

so this is what we do:

in the icansleep() function, we check for the *real* event we care about;
that is, if theres a buffer available in the Rbpool. this is to handle
the case when rbfree() makes a buffer available *before* it sees us
setting p->starve = 1.

p->starve is now just used to gate rbfree() from calling wakeup() as
an optimization.

this might cause spurious wakeups but they are not a problem. missed
wakeups is the thing we have to prevent.
sys/src/9/pc/ether82563.c