Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Mar 2012 17:39:19 +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: r233673 - head/sys/dev/ath
Message-ID:  <201203291739.q2THdJqo003506@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Thu Mar 29 17:39:18 2012
New Revision: 233673
URL: http://svn.freebsd.org/changeset/base/233673

Log:
  Defer the rescheduling of TID -> TXQ frames in some instances.
  
  Right now ath_txq_sched() is mainly called from the TX ath_tx_processq()
  routine, which is (mostly) done as part of the taskqueue.  It shouldn't
  be called outside the taskqueue.
  
  But now that I'm about to flip back on BAR TX, I'm going to start
  stressing the ath_tx_tid_pause() and ath_tx_tid_resume() paths.
  What I don't want to have happen is a reschedule of the TID traffic
  _during_ the completion of TX frames.
  
  Ideally I'd like to have a way to flag back up to the processing code
  that the current hardware queue should be rechecked for software TID
  queue frames.  But for now, this should suffice for the BAR TX case.
  
  I may eventually delete this code once I've brought some further
  sanity to the general TX queue/completion path.

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

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Thu Mar 29 17:04:04 2012	(r233672)
+++ head/sys/dev/ath/if_ath.c	Thu Mar 29 17:39:18 2012	(r233673)
@@ -191,6 +191,7 @@ static void	ath_tx_cleanup(struct ath_so
 static void	ath_tx_proc_q0(void *, int);
 static void	ath_tx_proc_q0123(void *, int);
 static void	ath_tx_proc(void *, int);
+static void	ath_txq_sched_tasklet(void *, int);
 static int	ath_chan_set(struct ath_softc *, struct ieee80211_channel *);
 static void	ath_draintxq(struct ath_softc *, ATH_RESET_TYPE reset_type);
 static void	ath_stoprecv(struct ath_softc *, int);
@@ -398,6 +399,7 @@ ath_attach(u_int16_t devid, struct ath_s
 	TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc);
 	TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc);
 	TASK_INIT(&sc->sc_resettask,0, ath_reset_proc, sc);
+	TASK_INIT(&sc->sc_txqtask,0, ath_txq_sched_tasklet, sc);
 
 	/*
 	 * Allocate hardware transmit queues: one queue for
@@ -5132,6 +5134,38 @@ ath_tx_proc(void *arg, int npending)
 #undef	TXQACTIVE
 
 /*
+ * Deferred processing of TXQ rescheduling.
+ */
+static void
+ath_txq_sched_tasklet(void *arg, int npending)
+{
+	struct ath_softc *sc = arg;
+	int i;
+
+	/* XXX is skipping ok? */
+	ATH_PCU_LOCK(sc);
+#if 0
+	if (sc->sc_inreset_cnt > 0) {
+		device_printf(sc->sc_dev,
+		    "%s: sc_inreset_cnt > 0; skipping\n", __func__);
+		ATH_PCU_UNLOCK(sc);
+		return;
+	}
+#endif
+	sc->sc_txproc_cnt++;
+	ATH_PCU_UNLOCK(sc);
+
+	for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
+		if (ATH_TXQ_SETUP(sc, i))
+			ath_txq_sched(sc, &sc->sc_txq[i]);
+	}
+
+	ATH_PCU_LOCK(sc);
+	sc->sc_txproc_cnt--;
+	ATH_PCU_UNLOCK(sc);
+}
+
+/*
  * Return a buffer to the pool and update the 'busy' flag on the
  * previous 'tail' entry.
  *

Modified: head/sys/dev/ath/if_ath_tx.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx.c	Thu Mar 29 17:04:04 2012	(r233672)
+++ head/sys/dev/ath/if_ath_tx.c	Thu Mar 29 17:39:18 2012	(r233673)
@@ -2623,7 +2623,8 @@ 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]);
+	//ath_txq_sched(sc, sc->sc_ac2q[tid->ac]);
+	taskqueue_enqueue(sc->sc_tq, &sc->sc_txqtask);
 }
 
 /*

Modified: head/sys/dev/ath/if_athvar.h
==============================================================================
--- head/sys/dev/ath/if_athvar.h	Thu Mar 29 17:04:04 2012	(r233672)
+++ head/sys/dev/ath/if_athvar.h	Thu Mar 29 17:39:18 2012	(r233673)
@@ -490,6 +490,7 @@ struct ath_softc {
 	struct ath_txq		sc_txq[HAL_NUM_TX_QUEUES];
 	struct ath_txq		*sc_ac2q[5];	/* WME AC -> h/w q map */ 
 	struct task		sc_txtask;	/* tx int processing */
+	struct task		sc_txqtask;	/* tx proc processing */
 	int			sc_wd_timer;	/* count down for wd timer */
 	struct callout		sc_wd_ch;	/* tx watchdog timer */
 	struct ath_tx_radiotap_header sc_tx_th;



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