From owner-svn-src-user@FreeBSD.ORG Tue Oct 18 07:54:23 2011 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 341C1106566C; Tue, 18 Oct 2011 07:54:23 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 196D98FC0A; Tue, 18 Oct 2011 07:54:23 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9I7sMun062597; Tue, 18 Oct 2011 07:54:22 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9I7sM1R062595; Tue, 18 Oct 2011 07:54:22 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201110180754.p9I7sM1R062595@svn.freebsd.org> From: Adrian Chadd Date: Tue, 18 Oct 2011 07:54:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226499 - user/adrian/if_ath_tx/sys/dev/ath X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Oct 2011 07:54:23 -0000 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