From owner-p4-projects@FreeBSD.ORG Thu May 31 22:12:32 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id BA10C16A469; Thu, 31 May 2007 22:12:32 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 8CC9916A400 for ; Thu, 31 May 2007 22:12:32 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 7AF3413C44C for ; Thu, 31 May 2007 22:12:32 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l4VMCWfj061297 for ; Thu, 31 May 2007 22:12:32 GMT (envelope-from thompsa@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l4VMCWrK061291 for perforce@freebsd.org; Thu, 31 May 2007 22:12:32 GMT (envelope-from thompsa@freebsd.org) Date: Thu, 31 May 2007 22:12:32 GMT Message-Id: <200705312212.l4VMCWrK061291@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to thompsa@freebsd.org using -f From: Andrew Thompson To: Perforce Change Reviews Cc: Subject: PERFORCE change 120683 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: Thu, 31 May 2007 22:12:33 -0000 http://perforce.freebsd.org/chv.cgi?CH=120683 Change 120683 by thompsa@thompsa_heff on 2007/05/31 22:11:35 Add a simple scan command ring so that sc_scanop does not get clobbered if the taskqueue hasnt fired before the next call. (testing this new code showed it happened often) Affected files ... .. //depot/projects/wifi/sys/dev/iwi/if_iwi.c#35 edit .. //depot/projects/wifi/sys/dev/iwi/if_iwivar.h#15 edit Differences ... ==== //depot/projects/wifi/sys/dev/iwi/if_iwi.c#35 (text+ko) ==== @@ -171,6 +171,7 @@ static void iwi_scan_mindwell(struct ieee80211com *); static void iwi_assoc(struct ieee80211com *ic); static void iwi_ops(void *, int); +static int iwi_scan_cmd(struct iwi_softc *, int); static int iwi_auth_and_assoc(struct iwi_softc *); static int iwi_disassociate(struct iwi_softc *, int quiet); static void iwi_down(void *, int); @@ -257,8 +258,8 @@ sc->sc_dev = dev; - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF); + IWI_LOCK_INIT(sc); + IWI_SCAN_LOCK_INIT(sc); sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx); @@ -481,7 +482,8 @@ if (sc->sc_unr != NULL) delete_unrhdr(sc->sc_unr); - mtx_destroy(&sc->sc_mtx); + IWI_LOCK_DESTROY(sc); + IWI_SCAN_LOCK_DESTROY(sc); return 0; } @@ -3439,7 +3441,20 @@ struct iwi_softc *sc = arg; struct ieee80211com *ic = &sc->sc_ic; IWI_LOCK_DECL; - + int cmd; + +again: + IWI_SCAN_LOCK(sc); + cmd = sc->sc_scanop[sc->sc_scan_cur]; + if (cmd == 0) { + /* No more commands to process */ + IWI_SCAN_UNLOCK(sc); + return; + } + sc->sc_scanop[sc->sc_scan_cur] = 0; /* free the slot */ + sc->sc_scan_cur = (sc->sc_scan_cur + 1) % IWI_SCAN_OPS; + IWI_SCAN_UNLOCK(sc); + IWI_LOCK(sc); while ((ic->ic_state != IEEE80211_S_INIT) && (sc->flags & IWI_FLAG_BUSY)) { msleep(sc, &sc->sc_mtx, 0, "iwicmd", hz/10); @@ -3448,7 +3463,7 @@ if (ic->ic_state == IEEE80211_S_INIT) goto done; - switch (sc->sc_scanop) { + switch (cmd) { case IWI_ASSOC: iwi_auth_and_assoc(sc); break; @@ -3466,8 +3481,7 @@ if (!(sc->flags & IWI_FLAG_CHANNEL_SCAN)) { DPRINTF(("%s: ic_scan_curchan while not scanning\n", __func__)); - IWI_UNLOCK(sc); - return; + goto done; } if (iwi_scanchan(sc, sc->sc_maxdwell, sc->sc_scanop)) ieee80211_cancel_scan(ic); @@ -3476,16 +3490,34 @@ } done: IWI_UNLOCK(sc); + + /* Take another pass */ + goto again; } +static int +iwi_scan_cmd(struct iwi_softc *sc, int cmd) +{ + IWI_SCAN_LOCK(sc); + if (sc->sc_scanop[sc->sc_scan_next] != 0) { + IWI_SCAN_UNLOCK(sc); + DPRINTF(("%s: scan command %d dropped\n", __func__, cmd)); + return (EBUSY); + } + + sc->sc_scanop[sc->sc_scan_next] = cmd; + sc->sc_scan_next = (sc->sc_scan_next + 1) % IWI_SCAN_OPS; + taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); + IWI_SCAN_UNLOCK(sc); +} + static void iwi_scan_start(struct ieee80211com *ic) { struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - sc->sc_scanop = IWI_SCAN_START; - taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); + iwi_scan_cmd(sc, IWI_SCAN_START); } static void @@ -3503,9 +3535,8 @@ struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - sc->sc_scanop = IWI_SCAN_CURCHAN; sc->sc_maxdwell = maxdwell; - taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); + iwi_scan_cmd(sc, IWI_SCAN_CURCHAN); } static void @@ -3514,9 +3545,8 @@ struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - sc->sc_scanop = IWI_SCAN_ALLCHAN; sc->sc_maxdwell = maxdwell; - taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); + iwi_scan_cmd(sc, IWI_SCAN_ALLCHAN); } static void @@ -3531,8 +3561,7 @@ struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - sc->sc_scanop = IWI_SCAN_END; - taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); + iwi_scan_cmd(sc, IWI_SCAN_END); } static void @@ -3541,6 +3570,5 @@ struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - sc->sc_scanop = IWI_ASSOC; - taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); + iwi_scan_cmd(sc, IWI_ASSOC); } ==== //depot/projects/wifi/sys/dev/iwi/if_iwivar.h#15 (text+ko) ==== @@ -123,6 +123,8 @@ device_t sc_dev; struct mtx sc_mtx; + struct mtx sc_scanlock; + char sc_scanname[12]; /* e.g. "iwi0_scan" */ uint8_t sc_mcast[IEEE80211_ADDR_LEN]; struct unrhdr *sc_unr; struct taskqueue *sc_tq; /* private task queue */ @@ -212,7 +214,10 @@ #define IWI_ASSOC (1 << 3) #define IWI_SCAN_CURCHAN (1 << 4) #define IWI_SCAN_ALLCHAN (1 << 5) - int sc_scanop; /* op for scan task to do */ +#define IWI_SCAN_OPS 5 + int sc_scanop[IWI_SCAN_OPS]; + int sc_scan_cur; /* current queued scan task */ + int sc_scan_next; /* last queued scan task */ unsigned long sc_maxdwell; /* max dwell time for curchan */ struct bpf_if *sc_drvbpf; @@ -235,6 +240,10 @@ * NB.: This models the only instance of async locking in iwi_init_locked * and must be kept in sync. */ +#define IWI_LOCK_INIT(sc) \ + mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \ + MTX_NETWORK_LOCK, MTX_DEF) +#define IWI_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx) #define IWI_LOCK_DECL int __waslocked = 0 #define IWI_LOCK_CHECK(sc) do { \ if (!mtx_owned(&(sc)->sc_mtx)) \ @@ -248,3 +257,11 @@ if (!__waslocked) \ mtx_unlock(&(sc)->sc_mtx); \ } while (0) +#define IWI_SCAN_LOCK_INIT(sc) do { \ + snprintf((sc)->sc_scanname, sizeof((sc)->sc_scanname), "%s_scan", \ + device_get_nameunit((sc)->sc_dev)); \ + mtx_init(&(sc)->sc_scanlock, (sc)->sc_scanname, NULL, MTX_DEF); \ +} while (0) +#define IWI_SCAN_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_scanlock) +#define IWI_SCAN_LOCK(sc) mtx_lock(&(sc)->sc_scanlock) +#define IWI_SCAN_UNLOCK(sc) mtx_unlock(&(sc)->sc_scanlock)