Questions about locking; turnstiles and sleeping threads

John Baldwin jhb at freebsd.org
Fri Nov 14 23:19:32 UTC 2014


On Thursday, November 13, 2014 09:32:14 AM Adrian Chadd wrote:
> On 13 November 2014 06:48, John Baldwin <jhb at freebsd.org> wrote:
> > On Thursday, November 13, 2014 4:52:50 am Adrian Chadd wrote:
> >> Hm, the more I dig into this, the more I realise it's not a 1:45am
> >> question to ask.
> >> 
> >> Specifically, callout_stop_safe() takes 'safe', which says "are we
> >> waiting around for this callout to finish if it started". Ie,
> >> callout_drain() is callout_stop_safe(c, 1) ; callout_stop() is
> >> callout_stop_safe(c, 0).
> >> 
> >> If safe is 1, then it'll potentially put the current thread to sleep
> >> in order to wait for it to synchronise with the callout that's
> >> running. It's sleeping with cc_lock which is the per-callwheel lock
> >> and it's doing that with whatever other locks are held. That's the
> >> situation which is tripping things up.
> >> 
> >> The manpage says that no locks should be held that the callout may
> >> block on, which isn't the case here at all - I'm trying to grab a lock
> >> in another thread that the caller _into_ the callout subsystem holds.
> >> The manpage doesn't mention anything about this. Sniffle.
> > 
> > It should just say "no sleepable locks at all".  And yes, callout_stop()
> > is
> > perfectly fine to call with locks held.  It is only callout_drain() that
> > should not be called, same as with bus_teardown_intr() and
> > taskqueue_drain() (other routines that can sleep while ensuring that an
> > asynchronous task run by another thread is stopped).
> 
> so, we should add WITNESS_WARN() to those as well?

Sure.  For bus_teardown_intr() the right place to do it is in the
intr_event_*() that eventually gets called in kern_intr.c.

-- 
John Baldwin


More information about the freebsd-arch mailing list