On Sunday 31 August 2008 09:31:17 pm Tor Egge wrote: > > sleepq_resume_thread() contains an ownership handover of sq if the resumed > thread is the last one blocked on the wait channel. After the handover, sq is > no longer protected by the sleep queue chain lock and should no longer be > accessed by sleepq_broadcast(). > > Normally, when sleepq_broadcast() incorrectly accesses sq after the handover, > it will find the sq->sq_blocked queue to be empty, and the code appears to > work. > > If the last correctly woken thread manages to go to sleep again very quickly on > another wait channel, sleepq_broadcast() might incorrectly determine that the > sq->sq_blocked queue isn't empty, and start doing the wrong thing. > > A similar (but probably much more difficult to trigger) issue is present with > regards to thread_lock() and turnstiles. > > The caller of thread_lock() might have performed sufficient locking to ensure > that the thread to be locked doesn't go away, but any turnstile spin lock > pointed to by td->td_lock isn't protected. Making turnstiles type stable > (setting UMA_ZONE_NOFREE flag for turnstile_zone) should fix that issue. Good find! I think the better fix is to not rely on type stability, but to have sleepq_resume_thread() indicate to the caller that it has claimed the sleepqueue instead. I think this race is only possible with thread_lock() btw. -- John BaldwinReceived on Tue Sep 02 2008 - 13:34:58 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:34 UTC