Questions about locking; turnstiles and sleeping threads

Adrian Chadd adrian at freebsd.org
Thu Nov 13 02:13:57 UTC 2014


Hi,

I have a bit of an odd case here.

I'm getting panics in the net80211/ath code, "sleeping thread (X) owns
non-sleepable lock."

show alllocks just showed one lock held - the net80211 comlock. It's a
recursive mutex, that's supposed to be sleepable.

The two threads in question look like this:

thread X: net80211_newstate_cb (grabs IEEE80211_LOCK())
    ath_newstate
    callout_drain - which grabs the ATH_LOCK as part of the callout
drain side of things
    that enters sleepq_wait() and goes to sleep, waiting for
whatever's running the callout to
    finish

thread Y:
    rx_path in if_ath_rx_edma
    ath_rx_pkt -> sta_input -> ath_recv_mgmt -> sta_recv_mgmt (grabs
IEEE80211_LOCK()) -> panics

Thread Y doesn't hold any other locks. It's just trying to grab the
IEEE80211_LOCK that is being held by thread X. But thread X is asleep
waiting for whatever callout to finish so it can continue. The code in
propagate_priority() sees that thread X is sleeping and panics.

So, what's really going on? I don't mind (well, "don't mind") having
to take another deep dive through all of this to sort it out so it
doesn't tickle the callout / turnstile code in this particular
fashion, but I'd first like to ensure that it's not some corner case
that isn't handled by the check in propagate_priority().

Thanks,


-adrian


More information about the freebsd-arch mailing list