Date: Tue, 18 Oct 2011 07:54:22 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r226499 - user/adrian/if_ath_tx/sys/dev/ath Message-ID: <201110180754.p9I7sM1R062595@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Tue Oct 18 07:54:22 2011 New Revision: 226499 URL: http://svn.freebsd.org/changeset/base/226499 Log: Stick ath_start() and ath_tx_proc() behind the ath sc lock. This is to prevent ath_start() being preempted by a taskqueue or by the reset process. This is primarily to avoid having a reset or flush operation occur during active TX / TX completion, and having TX DMA be restarted when it's disabled. Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/if_ath.c Tue Oct 18 07:39:27 2011 (r226498) +++ user/adrian/if_ath_tx/sys/dev/ath/if_ath.c Tue Oct 18 07:54:22 2011 (r226499) @@ -131,6 +131,7 @@ static void ath_init(void *); static void ath_stop_locked(struct ifnet *); static void ath_stop(struct ifnet *); static void ath_start(struct ifnet *); +static void ath_start_locked(struct ifnet *); static int ath_reset_vap(struct ieee80211vap *, u_long); static int ath_media_change(struct ifnet *); static void ath_watchdog(void *); @@ -1887,7 +1888,7 @@ ath_reset_locked(struct ifnet *ifp, ATH_ } ath_hal_intrset(ah, sc->sc_imask); - ath_start(ifp); /* restart xmit */ + ath_start_locked(ifp); /* restart xmit */ return 0; } @@ -2027,12 +2028,25 @@ static void ath_start(struct ifnet *ifp) { struct ath_softc *sc = ifp->if_softc; + + /* TODO: Ensure this isn't locked first! */ + ATH_LOCK(sc); + ath_start_locked(ifp); + ATH_UNLOCK(sc); +} + +static void +ath_start_locked(struct ifnet *ifp) +{ + struct ath_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct ath_buf *bf; struct mbuf *m, *next; ath_bufhead frags; int tx = 0; + ATH_LOCK_ASSERT(sc); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) return; for (;;) { @@ -4164,7 +4178,7 @@ rx_next: ieee80211_ff_age_all(ic, 100); #endif if (!IFQ_IS_EMPTY(&ifp->if_snd)) - ath_start(ifp); + ath_start_locked(ifp); } #undef PA2DESC } @@ -4660,7 +4674,6 @@ ath_tx_proc_q0(void *arg, int npending) ATH_LOCK(sc); txqs = sc->sc_txq_active; sc->sc_txq_active &= ~txqs; - ATH_UNLOCK(sc); if (TXQACTIVE(txqs, 0) && ath_tx_processq(sc, &sc->sc_txq[0], 1)) /* XXX why is lastrx updated in tx code? */ @@ -4673,7 +4686,8 @@ ath_tx_proc_q0(void *arg, int npending) if (sc->sc_softled) ath_led_event(sc, sc->sc_txrix); - ath_start(ifp); + ath_start_locked(ifp); + ATH_UNLOCK(sc); } /* @@ -4691,7 +4705,6 @@ ath_tx_proc_q0123(void *arg, int npendin ATH_LOCK(sc); txqs = sc->sc_txq_active; sc->sc_txq_active &= ~txqs; - ATH_UNLOCK(sc); /* * Process each active queue. @@ -4716,7 +4729,8 @@ ath_tx_proc_q0123(void *arg, int npendin if (sc->sc_softled) ath_led_event(sc, sc->sc_txrix); - ath_start(ifp); + ath_start_locked(ifp); + ATH_UNLOCK(sc); } /* @@ -4733,7 +4747,6 @@ ath_tx_proc(void *arg, int npending) ATH_LOCK(sc); txqs = sc->sc_txq_active; sc->sc_txq_active &= ~txqs; - ATH_UNLOCK(sc); /* * Process each active queue. @@ -4751,7 +4764,8 @@ ath_tx_proc(void *arg, int npending) if (sc->sc_softled) ath_led_event(sc, sc->sc_txrix); - ath_start(ifp); + ath_start_locked(ifp); + ATH_UNLOCK(sc); } #undef TXQACTIVE
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110180754.p9I7sM1R062595>