Date: Wed, 12 Nov 2014 21:26:13 -0500 From: Alexander Kabaev <kabaev@gmail.com> To: Adrian Chadd <adrian@freebsd.org> Cc: "freebsd-arch@freebsd.org" <freebsd-arch@freebsd.org> Subject: Re: Questions about locking; turnstiles and sleeping threads Message-ID: <20141112212613.21037929@kan> In-Reply-To: <CAJ-VmomrauhCMoF_dZfMWWhZp0EgwfE9RmxL5Pc37PhLSzZ6Qg@mail.gmail.com> References: <CAJ-VmomrauhCMoF_dZfMWWhZp0EgwfE9RmxL5Pc37PhLSzZ6Qg@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] On Wed, 12 Nov 2014 18:13:55 -0800 Adrian Chadd <adrian@freebsd.org> wrote: > 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 > _______________________________________________ Hi, mutexes are blocking and not sleepable primitives, so doing any unbounded sleep with mutex locked, such as one you are attempting by calling callout_drain is illegal. In other words, you are getting an expected assert and the code in question is wrong. -- Alexander Kabaev [-- Attachment #2 --] -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iD8DBQFUZBbKQ6z1jMm+XZYRAlweAJwNJIf8jm8HQineNZpI5O0mF9prVACeKWUM a/Fbvs0x7U/dY6itBVE7w2E= =bOf1 -----END PGP SIGNATURE-----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20141112212613.21037929>
