Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Jan 2013 00:14:34 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r245927 - head/sys/dev/ath
Message-ID:  <201301260014.r0Q0EYpU076094@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sat Jan 26 00:14:34 2013
New Revision: 245927
URL: http://svnweb.freebsd.org/changeset/base/245927

Log:
  Migrate the TX sending code out from under the ath0 taskq and into
  the separate ath0 TX taskq.
  
  Whilst here, make sure that the TX software scheduler is also
  running out of the TX task, rather than the ath0 taskqueue.
  
  Make sure that the tx taskqueue is blocked/unblocked as necessary.
  
  This allows for a little more parallelism on multi-core machines,
  as well as (eventually) supporting a higher task priority for TX
  tasks, allowing said TX task to preempt an already running RX or
  TX completion task.
  
  Tested:
  
  * AR5416, AR9280 hostap and STA modes

Modified:
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_ath_misc.h
  head/sys/dev/ath/if_ath_tx.c
  head/sys/dev/ath/if_ath_tx_edma.c

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Sat Jan 26 00:11:39 2013	(r245926)
+++ head/sys/dev/ath/if_ath.c	Sat Jan 26 00:14:34 2013	(r245927)
@@ -436,6 +436,16 @@ ath_attach(u_int16_t devid, struct ath_s
 	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
 		"%s taskq", ifp->if_xname);
 
+	/*
+	 * This taskqueue doesn't get any higher priority
+	 * than the ath(4) taskqueue (PI_NET) so TX won't
+	 * pre-empt RX and other task priorities.
+	 *
+	 * This may not be optimal - the previous behaviour
+	 * was to direct-dispatch frames via the sending
+	 * task context, rather than (always) software
+	 * queuing.
+	 */
 	sc->sc_tx_tq = taskqueue_create("ath_tx_taskq", M_NOWAIT,
 		taskqueue_thread_enqueue, &sc->sc_tx_tq);
 	taskqueue_start_threads(&sc->sc_tx_tq, 1, PI_NET,
@@ -2135,6 +2145,7 @@ ath_txrx_start(struct ath_softc *sc)
 {
 
 	taskqueue_unblock(sc->sc_tq);
+	taskqueue_unblock(sc->sc_tx_tq);
 }
 
 /*
@@ -2235,6 +2246,7 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T
 
 	/* Try to (stop any further TX/RX from occuring */
 	taskqueue_block(sc->sc_tq);
+	taskqueue_block(sc->sc_tx_tq);
 
 	ATH_PCU_LOCK(sc);
 	ath_hal_intrset(ah, 0);		/* disable interrupts */
@@ -3033,6 +3045,7 @@ ath_key_update_begin(struct ieee80211vap
 
 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
 	taskqueue_block(sc->sc_tq);
+	taskqueue_block(sc->sc_tx_tq);
 	IF_LOCK(&ifp->if_snd);		/* NB: doesn't block mgmt frames */
 }
 
@@ -3045,6 +3058,7 @@ ath_key_update_end(struct ieee80211vap *
 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
 	IF_UNLOCK(&ifp->if_snd);
 	taskqueue_unblock(sc->sc_tq);
+	taskqueue_unblock(sc->sc_tx_tq);
 }
 
 static void
@@ -4218,9 +4232,7 @@ ath_tx_processq(struct ath_softc *sc, st
 
 	/* Kick the TXQ scheduler */
 	if (dosched) {
-		ATH_TX_LOCK(sc);
-		ath_txq_sched(sc, txq);
-		ATH_TX_UNLOCK(sc);
+		taskqueue_enqueue(sc->sc_tx_tq, &sc->sc_txqtask);
 	}
 
 	ATH_KTR(sc, ATH_KTR_TXCOMP, 1,
@@ -4718,6 +4730,7 @@ ath_chan_set(struct ath_softc *sc, struc
 
 	/* (Try to) stop TX/RX from occuring */
 	taskqueue_block(sc->sc_tq);
+	taskqueue_block(sc->sc_tx_tq);
 
 	ATH_PCU_LOCK(sc);
 	ath_hal_intrset(ah, 0);		/* Stop new RX/TX completion */
@@ -5107,6 +5120,7 @@ ath_newstate(struct ieee80211vap *vap, e
 		sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
 		sc->sc_beacons = 0;
 		taskqueue_unblock(sc->sc_tq);
+		taskqueue_unblock(sc->sc_tx_tq);
 	}
 
 	ni = ieee80211_ref_node(vap->iv_bss);
@@ -5272,6 +5286,7 @@ ath_newstate(struct ieee80211vap *vap, e
 			    "%s: calibration disabled\n", __func__);
 		}
 		taskqueue_unblock(sc->sc_tq);
+		taskqueue_unblock(sc->sc_tx_tq);
 	} else if (nstate == IEEE80211_S_INIT) {
 		/*
 		 * If there are no vaps left in RUN state then
@@ -5285,6 +5300,7 @@ ath_newstate(struct ieee80211vap *vap, e
 			/* disable interrupts  */
 			ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL);
 			taskqueue_block(sc->sc_tq);
+			taskqueue_block(sc->sc_tx_tq);
 			sc->sc_beacons = 0;
 		}
 #ifdef IEEE80211_SUPPORT_TDMA

Modified: head/sys/dev/ath/if_ath_misc.h
==============================================================================
--- head/sys/dev/ath/if_ath_misc.h	Sat Jan 26 00:11:39 2013	(r245926)
+++ head/sys/dev/ath/if_ath_misc.h	Sat Jan 26 00:14:34 2013	(r245927)
@@ -125,7 +125,7 @@ ath_tx_kick(struct ath_softc *sc)
 {
 
 	/* XXX eventually try sc_tx_tq? */
-	taskqueue_enqueue(sc->sc_tq, &sc->sc_txpkttask);
+	taskqueue_enqueue(sc->sc_tx_tq, &sc->sc_txpkttask);
 }
 
 #endif

Modified: head/sys/dev/ath/if_ath_tx.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx.c	Sat Jan 26 00:11:39 2013	(r245926)
+++ head/sys/dev/ath/if_ath_tx.c	Sat Jan 26 00:14:34 2013	(r245927)
@@ -3001,7 +3001,7 @@ ath_tx_tid_resume(struct ath_softc *sc, 
 	ath_tx_tid_sched(sc, tid);
 	/* Punt some frames to the hardware if needed */
 	//ath_txq_sched(sc, sc->sc_ac2q[tid->ac]);
-	taskqueue_enqueue(sc->sc_tq, &sc->sc_txqtask);
+	taskqueue_enqueue(sc->sc_tx_tq, &sc->sc_txqtask);
 }
 
 /*

Modified: head/sys/dev/ath/if_ath_tx_edma.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx_edma.c	Sat Jan 26 00:11:39 2013	(r245926)
+++ head/sys/dev/ath/if_ath_tx_edma.c	Sat Jan 26 00:14:34 2013	(r245927)
@@ -655,7 +655,7 @@ ath_edma_tx_processq(struct ath_softc *s
 	 * the txq task for _one_ TXQ.  This should be fixed.
 	 */
 	if (dosched)
-		taskqueue_enqueue(sc->sc_tq, &sc->sc_txqtask);
+		taskqueue_enqueue(sc->sc_tx_tq, &sc->sc_txqtask);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201301260014.r0Q0EYpU076094>