From owner-p4-projects@FreeBSD.ORG Tue Feb 10 17:40:38 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7F118106567A; Tue, 10 Feb 2009 17:40:37 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 26BB61065672 for ; Tue, 10 Feb 2009 17:40:37 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 13F1D8FC2E for ; Tue, 10 Feb 2009 17:40:37 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n1AHeaia040809 for ; Tue, 10 Feb 2009 17:40:36 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n1AHeWnQ040806 for perforce@freebsd.org; Tue, 10 Feb 2009 17:40:32 GMT (envelope-from hselasky@FreeBSD.org) Date: Tue, 10 Feb 2009 17:40:32 GMT Message-Id: <200902101740.n1AHeWnQ040806@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 157497 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Feb 2009 17:40:40 -0000 http://perforce.freebsd.org/chv.cgi?CH=157497 Change 157497 by hselasky@hselasky_laptop001 on 2009/02/10 17:39:48 USB WLAN: Fix more races and panics after that Andrew Thompson re-ported the WLAN drivers from the old USB stack. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#31 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#31 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#33 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zydreg.h#7 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#31 (text+ko) ==== @@ -126,6 +126,7 @@ static usb2_proc_callback_t rum_amrr_task; static usb2_proc_callback_t rum_init_task; static usb2_proc_callback_t rum_stop_task; +static usb2_proc_callback_t rum_flush_task; static struct ieee80211vap *rum_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, @@ -611,9 +612,31 @@ } static void +rum_flush_task(struct usb2_proc_msg *pm) +{ + struct rum_task *task = (struct rum_task *)pm; + struct rum_softc *sc = task->sc; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct rum_vap *rvp = RUM_VAP(vap); + + /* callout it stopped */ + usb2_callout_stop(&rvp->amrr_ch); +} + +static void rum_vap_delete(struct ieee80211vap *vap) { struct rum_vap *rvp = RUM_VAP(vap); + struct rum_softc *sc = rvp->sc; + + RUM_LOCK(sc); + /* wait for any pending tasks to complete */ + rum_queue_command(sc, rum_flush_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); + RUM_UNLOCK(sc); usb2_callout_drain(&rvp->amrr_ch); ieee80211_amrr_cleanup(&rvp->amrr); @@ -701,9 +724,16 @@ ostate = vap->iv_state; + /* callout it stopped */ + usb2_callout_stop(&rvp->amrr_ch); + switch (sc->sc_state) { case IEEE80211_S_INIT: if (ostate == IEEE80211_S_RUN) { + /* + * BUG: this code is not executed like it + * should --hps + */ /* abort TSF synchronization */ tmp = rum_read(sc, RT2573_TXRX_CSR9); rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); @@ -759,8 +789,6 @@ ieee80211_state_name[nstate]); RUM_LOCK(sc); - usb2_callout_stop(&rvp->amrr_ch); - /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; @@ -2183,7 +2211,9 @@ ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni); - usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); + /* XXX WLAN race --hps */ + if (sc->sc_state != IEEE80211_S_INIT) + usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); } static void @@ -2192,8 +2222,15 @@ struct rum_vap *rvp = arg; struct rum_softc *sc = rvp->sc; + /* XXX WLAN race --hps */ + if (sc->sc_state == IEEE80211_S_INIT) + return; + rum_queue_command(sc, rum_amrr_task, &rvp->amrr_task[0].hdr, &rvp->amrr_task[1].hdr); + + /* to avoid sync-issues we need to reset the callout here */ + usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); } static void @@ -2204,7 +2241,6 @@ struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct rum_vap *rvp = RUM_VAP(vap); struct ieee80211_node *ni = vap->iv_bss; int ok, fail; @@ -2215,13 +2251,15 @@ (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */ fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */ + /* XXX WLAN race --hps */ + if (sc->sc_state == IEEE80211_S_INIT) + return; + ieee80211_amrr_tx_update(&RUM_NODE(ni)->amn, ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail); (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn); ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ - - usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); } /* ARGUSED */ @@ -2388,9 +2426,10 @@ task->sc = sc; /* - * Init and stop must be synchronous! + * Init, stop and flush must be synchronous! */ - if ((fn == rum_init_task) || (fn == rum_stop_task)) + if ((fn == rum_init_task) || (fn == rum_stop_task) || + (fn == rum_flush_task)) usb2_proc_mwait(&sc->sc_tq, t0, t1); } ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#31 (text+ko) ==== @@ -105,6 +105,7 @@ static usb2_proc_callback_t ural_amrr_task; static usb2_proc_callback_t ural_init_task; static usb2_proc_callback_t ural_stop_task; +static usb2_proc_callback_t ural_flush_task; static struct ieee80211vap *ural_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, @@ -597,9 +598,31 @@ } static void +ural_flush_task(struct usb2_proc_msg *pm) +{ + struct ural_task *task = (struct ural_task *)pm; + struct ural_softc *sc = task->sc; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ural_vap *uvp = URAL_VAP(vap); + + /* callout it stopped */ + usb2_callout_stop(&uvp->amrr_ch); +} + +static void ural_vap_delete(struct ieee80211vap *vap) { struct ural_vap *uvp = URAL_VAP(vap); + struct ural_softc *sc = uvp->sc; + + RAL_LOCK(sc); + /* wait for any pending tasks to complete */ + ural_queue_command(sc, ural_flush_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); + RAL_UNLOCK(sc); usb2_callout_drain(&uvp->amrr_ch); ieee80211_amrr_cleanup(&uvp->amrr); @@ -687,9 +710,16 @@ ostate = vap->iv_state; + /* callout is stopped */ + usb2_callout_stop(&uvp->amrr_ch); + switch (sc->sc_state) { case IEEE80211_S_INIT: if (ostate == IEEE80211_S_RUN) { + /* + * BUG: this code is not executed like it + * should --hps + */ /* abort TSF synchronization */ ural_write(sc, RAL_TXRX_CSR19, 0); @@ -793,8 +823,6 @@ ieee80211_state_name[nstate]); RAL_LOCK(sc); - usb2_callout_stop(&uvp->amrr_ch); - /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; @@ -2269,7 +2297,9 @@ ieee80211_amrr_node_init(&uvp->amrr, &URAL_NODE(ni)->amn, ni); - usb2_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp); + /* XXX WLAN race --hps */ + if (sc->sc_state != IEEE80211_S_INIT) + usb2_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp); } static void @@ -2278,8 +2308,15 @@ struct ural_vap *uvp = arg; struct ural_softc *sc = uvp->sc; + /* XXX WLAN race --hps */ + if (sc->sc_state == IEEE80211_S_INIT) + return; + ural_queue_command(sc, ural_amrr_task, &uvp->amrr_task[0].hdr, &uvp->amrr_task[1].hdr); + + /* to avoid sync-issues we need to reset the callout here */ + usb2_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp); } static void @@ -2290,7 +2327,6 @@ struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ural_vap *uvp = URAL_VAP(vap); struct ieee80211_node *ni = vap->iv_bss; int ok, fail; @@ -2301,13 +2337,15 @@ sc->sta[8]; /* TX ok w/ retry */ fail = sc->sta[9]; /* TX retry-fail count */ + /* XXX WLAN race --hps */ + if (sc->sc_state == IEEE80211_S_INIT) + return; + ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn, ok+fail, ok, sc->sta[8] + fail); (void) ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn); ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ - - usb2_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp); } static void @@ -2335,9 +2373,9 @@ task->sc = sc; /* - * Init and stop must be synchronous! + * Init, stop and flush must be synchronous! */ - if ((fn == ural_init_task) || (fn == ural_stop_task)) + if ((fn == ural_init_task) || (fn == ural_stop_task) || + (fn == ural_stop_task)) usb2_proc_mwait(&sc->sc_tq, t0, t1); } - ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#33 (text+ko) ==== @@ -91,6 +91,7 @@ static usb2_proc_callback_t zyd_multitask; static usb2_proc_callback_t zyd_init_task; static usb2_proc_callback_t zyd_stop_task; +static usb2_proc_callback_t zyd_flush_task; static struct ieee80211vap *zyd_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, @@ -469,6 +470,7 @@ const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { + struct zyd_softc *sc = ic->ic_ifp->if_softc; struct zyd_vap *zvp; struct ieee80211vap *vap; @@ -487,6 +489,7 @@ zvp->newstate = vap->iv_newstate; vap->iv_newstate = zyd_newstate; + zvp->sc = sc; ieee80211_amrr_init(&zvp->amrr, vap, IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, @@ -500,10 +503,24 @@ } static void +zyd_flush_task(struct usb2_proc_msg *_pm) +{ + /* nothing to do */ +} + +static void zyd_vap_delete(struct ieee80211vap *vap) { struct zyd_vap *zvp = ZYD_VAP(vap); + struct zyd_softc *sc = zvp->sc; + ZYD_LOCK(sc); + /* wait for any pending tasks to complete */ + zyd_queue_command(sc, zyd_flush_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); + ZYD_UNLOCK(sc); + ieee80211_amrr_cleanup(&zvp->amrr); ieee80211_vap_detach(vap); free(zvp, M_80211_VAP); @@ -3092,7 +3109,8 @@ /* * Init and stop must be synchronous! */ - if ((fn == zyd_init_task) || (fn == zyd_stop_task)) + if ((fn == zyd_init_task) || (fn == zyd_stop_task) || + (fn == zyd_flush_task)) usb2_proc_mwait(&sc->sc_tq, t0, t1); } ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zydreg.h#7 (text+ko) ==== @@ -1247,6 +1247,7 @@ struct ieee80211vap vap; int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int); + struct zyd_softc *sc; struct ieee80211_amrr amrr; }; #define ZYD_VAP(vap) ((struct zyd_vap *)(vap))