Drain task q items when transitioning to INIT state; this closes a

race seen on smp laptops when suspending where the rx task can be
entered after the interface is detach'd.

NB: use of taskqueue_drain while holding the softc mutex is problematic

Submitted by:	ambrisko
MFC after:	1 month
This commit is contained in:
Sam Leffler 2007-05-29 16:13:59 +00:00
parent 89c1ee78f3
commit 58769f5837
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=170104

View File

@ -4592,14 +4592,19 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
ath_hal_setledstate(ah, leds[nstate]); /* set LED */
if (nstate == IEEE80211_S_INIT) {
/*
* Shutdown host/driver operation:
* o disable interrupts so we don't rx frames
* o clean any pending items on the task q
* o notify the rate control algorithm
*/
sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
/*
* NB: disable interrupts so we don't rx frames.
*/
ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL);
/*
* Notify the rate control algorithm.
*/
/* XXX can't use taskqueue_drain 'cuz we're holding sc_mtx */
taskqueue_drain(sc->sc_tq, &sc->sc_rxtask);
taskqueue_drain(sc->sc_tq, &sc->sc_rxorntask);
taskqueue_drain(sc->sc_tq, &sc->sc_bmisstask);
taskqueue_drain(sc->sc_tq, &sc->sc_bstucktask);
ath_rate_newstate(sc, nstate);
goto done;
}