From owner-p4-projects@FreeBSD.ORG Mon Jul 12 20:00:12 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1C1BB1065672; Mon, 12 Jul 2010 20:00:12 +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 D3407106566B for ; Mon, 12 Jul 2010 20:00:11 +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 B21ED8FC14 for ; Mon, 12 Jul 2010 20:00:11 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o6CK0BR8091538 for ; Mon, 12 Jul 2010 20:00:11 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o6CK0B63091536 for perforce@freebsd.org; Mon, 12 Jul 2010 20:00:11 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 12 Jul 2010 20:00:11 GMT Message-Id: <201007122000.o6CK0B63091536@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 Precedence: bulk Cc: Subject: PERFORCE change 180844 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Jul 2010 20:00:12 -0000 http://p4web.freebsd.org/@@180844?ac=10 Change 180844 by hselasky@hselasky_laptop001 on 2010/07/12 19:59:47 USB WLAN: - fix races by doing proper refcounting Affected files ... .. //depot/projects/usb/src/sys/dev/usb/wlan/if_rum.c#29 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_run.c#14 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_uath.c#22 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_upgt.c#22 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_ural.c#23 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_urtw.c#16 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_zyd.c#29 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_rum.c#29 (text+ko) ==== @@ -709,9 +709,6 @@ IEEE80211_UNLOCK(ic); - /* XXX temporary workaround for race in IEEE802.11 layer */ - usb_pause_mtx(NULL, hz / 16); - RUM_LOCK(sc); usb_callout_stop(&rvp->ratectl_ch); @@ -725,7 +722,7 @@ break; case IEEE80211_S_RUN: - ni = vap->iv_bss; + ni = ieee80211_ref_node(vap->iv_bss); if (vap->iv_opmode != IEEE80211_M_MONITOR) { rum_update_slot(ic->ic_ifp); @@ -749,6 +746,8 @@ tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) rum_ratectl_start(sc, ni); + + ieee80211_free_node(ni); break; default: break; @@ -2229,7 +2228,7 @@ struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = ic->ic_ifp; struct rum_softc *sc = ifp->if_softc; - struct ieee80211_node *ni = vap->iv_bss; + struct ieee80211_node *ni; int ok, fail; int sum, retrycnt; @@ -2243,8 +2242,10 @@ sum = ok+fail; retrycnt = (le32toh(sc->sta[5]) & 0xffff) + fail; + ni = ieee80211_ref_node(vap->iv_bss); ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt); (void) ieee80211_ratectl_rate(ni, NULL, 0); + ieee80211_free_node(ni); ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_run.c#14 (text+ko) ==== @@ -1694,7 +1694,6 @@ struct ieee80211com *ic = vap->iv_ic; const struct ieee80211_txparam *tp; struct run_softc *sc = ic->ic_ifp->if_softc; - struct run_node *rn = (void *)vap->iv_bss; uint8_t rate, ridx; int error; @@ -1708,13 +1707,20 @@ tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + struct ieee80211_node *ni; + struct run_node *rn; + rate = ic->ic_sup_rates[ic->ic_curmode]. rs_rates[tp->ucastrate] & IEEE80211_RATE_VAL; for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) if (rt2860_rates[ridx].rate == rate) break; + + ni = ieee80211_ref_node(vap->iv_bss); + rn = (void *)ni; rn->fix_ridx = ridx; DPRINTF("rate=%d, fix_ridx=%d\n", rate, rn->fix_ridx); + ieee80211_free_node(ni); } #if 0 @@ -1782,7 +1788,8 @@ case IEEE80211_S_RUN: - ni = vap->iv_bss; + ni = ieee80211_ref_node(vap->iv_bss); + if(!(sc->runbmap & bid)){ if(sc->running++) restart_ratectl = 1; @@ -1837,6 +1844,7 @@ (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? RT2860_LED_LINK_2GHZ : RT2860_LED_LINK_5GHZ)); + ieee80211_free_node(ni); break; default: DPRINTFN(6, "undefined case\n"); @@ -1966,6 +1974,7 @@ ni = ieee80211_find_vap_node(&ic->ic_sta, vap, cmdq->mac); else ni = vap->iv_bss; + associd = (ni != NULL) ? ni->ni_associd : 0; /* map net80211 cipher to RT2860 security mode */ ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_uath.c#22 (text+ko) ==== @@ -1968,9 +1968,11 @@ const struct ieee80211_rateset *rs; struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ieee80211_node *ni = vap->iv_bss; + struct ieee80211_node *ni; struct uath_cmd_create_connection create; + ni = ieee80211_ref_node(vap->iv_bss); + bzero(&create, sizeof create); create.connid = htobe32(connid); create.bssid = htobe32(0); @@ -1990,6 +1992,8 @@ else create.connattr.wlanmode = htobe32(WLAN_MODE_11b); + ieee80211_free_node(ni); + return uath_cmd_write(sc, WDCMSG_CREATE_CONNECTION, &create, sizeof create, 0); } @@ -2017,14 +2021,19 @@ { struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ieee80211_node *ni = vap->iv_bss; + struct ieee80211_node *ni; struct uath_cmd_set_associd associd; + ni = ieee80211_ref_node(vap->iv_bss); + bzero(&associd, sizeof associd); associd.defaultrateix = htobe32(1); /* XXX */ associd.associd = htobe32(ni->ni_associd); associd.timoffset = htobe32(0x3b); /* XXX */ IEEE80211_ADDR_COPY(associd.bssid, ni->ni_bssid); + + ieee80211_free_node(ni); + return uath_cmd_write(sc, WDCMSG_WRITE_ASSOCID, &associd, sizeof associd, 0); } @@ -2065,7 +2074,7 @@ { enum ieee80211_state ostate = vap->iv_state; int error; - struct ieee80211_node *ni = vap->iv_bss; + struct ieee80211_node *ni; struct ieee80211com *ic = vap->iv_ic; struct uath_softc *sc = ic->ic_ifp->if_softc; struct uath_vap *uvp = UATH_VAP(vap); @@ -2076,9 +2085,6 @@ IEEE80211_UNLOCK(ic); - /* XXX temporary workaround for race in IEEE802.11 layer */ - usb_pause_mtx(NULL, hz / 16); - UATH_LOCK(sc); callout_stop(&sc->stat_ch); callout_stop(&sc->watchdog_ch); @@ -2095,32 +2101,44 @@ break; case IEEE80211_S_AUTH: + ni = ieee80211_ref_node(vap->iv_bss); + /* XXX good place? set RTS threshold */ uath_config(sc, CFG_USER_RTS_THRESHOLD, vap->iv_rtsthreshold); /* XXX bad place */ error = uath_set_keys(sc, vap); if (error != 0) { + ieee80211_free_node(ni); device_printf(sc->sc_dev, "could not set crypto keys, error %d\n", error); break; } if (uath_switch_channel(sc, ni->ni_chan) != 0) { + ieee80211_free_node(ni); device_printf(sc->sc_dev, "could not switch channel\n"); break; } if (uath_create_connection(sc, UATH_ID_BSS) != 0) { + ieee80211_free_node(ni); device_printf(sc->sc_dev, "could not create connection\n"); break; } + + ieee80211_free_node(ni); break; case IEEE80211_S_ASSOC: + ni = ieee80211_ref_node(vap->iv_bss); + if (uath_set_rates(sc, &ni->ni_rates) != 0) { + ieee80211_free_node(ni); device_printf(sc->sc_dev, "could not set negotiated rate set\n"); break; } + + ieee80211_free_node(ni); break; case IEEE80211_S_RUN: @@ -2130,6 +2148,8 @@ break; } + ni = ieee80211_ref_node(vap->iv_bss); + /* * Tx rate is controlled by firmware, report the maximum * negotiated rate in ifconfig output. @@ -2137,6 +2157,8 @@ ni->ni_txrate = ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates-1]; if (uath_write_associd(sc) != 0) { + + ieee80211_free_node(ni); device_printf(sc->sc_dev, "could not write association id\n"); break; @@ -2150,7 +2172,10 @@ /* start statistics timer */ callout_reset(&sc->stat_ch, hz, uath_stat, sc); + + ieee80211_free_node(ni); break; + default: break; } ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_upgt.c#22 (text+ko) ==== @@ -652,7 +652,7 @@ struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ieee80211_node *ni = vap->iv_bss; + struct ieee80211_node *ni; struct upgt_data *data_cmd; struct upgt_lmac_mem *mem; struct upgt_lmac_filter *filter; @@ -707,6 +707,8 @@ filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3); break; case IEEE80211_S_RUN: + ni = ieee80211_ref_node(vap->iv_bss); + /* XXX monitor mode isn't tested yet. */ if (vap->iv_opmode == IEEE80211_M_MONITOR) { filter->type = htole16(UPGT_FILTER_TYPE_MONITOR); @@ -730,6 +732,8 @@ filter->rxhw = htole32(sc->sc_eeprom_hwrx); filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3); } + + ieee80211_free_node(ni); break; default: device_printf(sc->sc_dev, @@ -1056,9 +1060,6 @@ IEEE80211_UNLOCK(ic); - /* XXX temporary workaround for race in IEEE802.11 layer */ - usb_pause_mtx(NULL, hz / 16); - UPGT_LOCK(sc); callout_stop(&sc->sc_led_ch); callout_stop(&sc->sc_watchdog_ch); ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_ural.c#23 (text+ko) ==== @@ -695,9 +695,6 @@ IEEE80211_UNLOCK(ic); - /* XXX temporary workaround for race in IEEE802.11 layer */ - usb_pause_mtx(NULL, hz / 16); - RAL_LOCK(sc); usb_callout_stop(&uvp->ratectl_ch); @@ -713,7 +710,7 @@ break; case IEEE80211_S_RUN: - ni = vap->iv_bss; + ni = ieee80211_ref_node(vap->iv_bss); if (vap->iv_opmode != IEEE80211_M_MONITOR) { ural_update_slot(ic->ic_ifp); @@ -729,6 +726,7 @@ if (m == NULL) { device_printf(sc->sc_dev, "could not allocate beacon\n"); + ieee80211_free_node(ni); RAL_UNLOCK(sc); IEEE80211_LOCK(ic); return (-1); @@ -737,6 +735,7 @@ if (ural_tx_bcn(sc, m, ni) != 0) { device_printf(sc->sc_dev, "could not send beacon\n"); + ieee80211_free_node(ni); RAL_UNLOCK(sc); IEEE80211_LOCK(ic); return (-1); @@ -757,6 +756,7 @@ if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) ural_ratectl_start(sc, ni); + ieee80211_free_node(ni); break; default: @@ -2239,7 +2239,7 @@ struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = ic->ic_ifp; struct ural_softc *sc = ifp->if_softc; - struct ieee80211_node *ni = vap->iv_bss; + struct ieee80211_node *ni; int ok, fail; int sum, retrycnt; @@ -2253,8 +2253,10 @@ sum = ok+fail; retrycnt = sc->sta[8] + fail; + ni = ieee80211_ref_node(vap->iv_bss); ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt); (void) ieee80211_ratectl_rate(ni, NULL, 0); + ieee80211_free_node(ni); ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_urtw.c#16 (text+ko) ==== @@ -1830,7 +1830,7 @@ static int urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { - struct ieee80211_node *ni = vap->iv_bss; + struct ieee80211_node *ni; struct ieee80211com *ic = vap->iv_ic; struct urtw_softc *sc = ic->ic_ifp->if_softc; struct urtw_vap *uvp = URTW_VAP(vap); @@ -1844,9 +1844,6 @@ IEEE80211_UNLOCK(ic); - /* XXX temporary workaround for race in IEEE802.11 layer */ - usb_pause_mtx(NULL, hz / 16); - URTW_LOCK(sc); usb_callout_stop(&sc->sc_led_ch); callout_stop(&sc->sc_watchdog_ch); @@ -1858,6 +1855,8 @@ case IEEE80211_S_ASSOC: break; case IEEE80211_S_RUN: + ni = ieee80211_ref_node(vap->iv_bss); + /* setting bssid. */ urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]); urtw_write16_m(sc, URTW_BSSID + 4, @@ -1872,6 +1871,8 @@ if (error != 0) device_printf(sc->sc_dev, "could not control LED (%d)\n", error); + + ieee80211_free_node(ni); break; default: break; ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_zyd.c#29 (text+ko) ==== @@ -580,30 +580,34 @@ IEEE80211_UNLOCK(ic); - /* XXX temporary workaround for race in IEEE802.11 layer */ - usb_pause_mtx(NULL, hz / 16); - ZYD_LOCK(sc); switch (nstate) { case IEEE80211_S_AUTH: zyd_set_chan(sc, ic->ic_curchan); break; case IEEE80211_S_RUN: - ni = vap->iv_bss; - if (vap->iv_opmode == IEEE80211_M_MONITOR) + ni = ieee80211_ref_node(vap->iv_bss); + if (vap->iv_opmode == IEEE80211_M_MONITOR) { + ieee80211_free_node(ni); break; + } /* turn link LED on */ error = zyd_set_led(sc, ZYD_LED1, 1); - if (error != 0) + if (error != 0) { + ieee80211_free_node(ni); break; + } /* make data LED blink upon Tx */ zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1); IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); zyd_set_bssid(sc, sc->sc_bssid); + + ieee80211_free_node(ni); break; + default: break; }