svn commit: r226499 - user/adrian/if_ath_tx/sys/dev/ath

Adrian Chadd adrian at FreeBSD.org
Tue Oct 18 07:54:23 UTC 2011


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
 


More information about the svn-src-user mailing list