panic: sleeping thread owns a mutex

M. Warner Losh imp at bsdimp.com
Mon Apr 28 20:34:12 PDT 2003


In message: <20030428.205301.112263174.imp at bsdimp.com>
            "M. Warner Losh" <imp at bsdimp.com> writes:
: In message: <0HE200DATX6MIM at mta5.snfc21.pbi.net>
:             Jeffrey Hsu <hsu at FreeBSD.org> writes:
: : Now, what about the race between the WI_UNLOCK() and the mtx_destroy() in
: : wi_detach() and any other WI_LOCK(), say in wi_start()?
: 
: Nothing that I can see.  Maybe we need to take out the if lock before
: taking out the wi_lock and require that the if_detach interface be
: locked...  But I haven't thought about it too much so there's likely
: issues with it.

Hmmmm, sounds like:

foo_detach(device_t dev)
{
	sc = device_get_softc(dev);
	if_lock(sc->ifp);		// if)lock not exported now
	FOO_LOCK(sc);
	sc->dead = 1;
	// stuff
	FOO_UNLOCK(sc);
[1]	ifmedia_removeall(&sc->sc_media);
	ieee80211_ifdetach(sc->ifp);	// NOTE: ifdetach called with
					   ifp locked, would be required.
	bus_teardown_intr(..);
[2]	wi_free(dev);
#if __FreeBSD_version >= 500000
	mtx_destroy(&sc->sc_mtx);
#endif
}

We have the foo_intr race between [1] and [2], but that's taken care
of with dead.  wi_start is called from the network output routines,
potentially, so I think that taking out the interface lock will be the
right thing.

However, this might be a lock order reversal form the init code.
(if_watchdog suffers from this reversal too, potentially).  Reversing
the order in foo_detach would not be a good solution, because we'd a
cross-threading locking issue (lock(a), lock(b), unlock(a) is bad).

But I'll freely admit that my understanding of the if_net locking
isn't perfect. :-)

Warner


More information about the freebsd-current mailing list