Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Aug 2011 07:17:38 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r225101 - user/adrian/if_ath_tx/sys/dev/ath
Message-ID:  <201108230717.p7N7Hcn4089783@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue Aug 23 07:17:37 2011
New Revision: 225101
URL: http://svn.freebsd.org/changeset/base/225101

Log:
  Sync this code a little more with what's in the Linux/atheros
  reference drivers.
  
  It doesn't yet fix aggregation throughput issues, but it provides
  some handy statistics for tracking what's going on.
  
  * add an ath_txq (hardware) counter tracking how many aggregate
    frames are pending.
  
  * Use this instead of the overall counter (axq_depth)
  
  * Add it to the txagg sysctl
  
  And another temporary tinker:
  
  * Delay scheduling the TID in ath_tx_swq() if the TID has some
    hardware queued frames. This doesn't seem to (yet) be doing
    what I would like it to be doing.
  
  The MAC is still not being kept totally busy, especially when
  TX'ing UDP traffic from a local iperf process. I'll add some
  more statistics and see what's going on.

Modified:
  user/adrian/if_ath_tx/sys/dev/ath/if_ath.c
  user/adrian/if_ath_tx/sys/dev/ath/if_ath_sysctl.c
  user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
  user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath.c	Tue Aug 23 07:00:51 2011	(r225100)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath.c	Tue Aug 23 07:17:37 2011	(r225101)
@@ -2512,7 +2512,9 @@ ath_txqmove(struct ath_txq *dst, struct 
 	dst->axq_link = src->axq_link;
 	src->axq_link = NULL;
 	dst->axq_depth += src->axq_depth;
+	dst->axq_aggr_depth += src->axq_aggr_depth;
 	src->axq_depth = 0;
+	src->axq_aggr_depth = 0;
 }
 
 /*
@@ -3915,6 +3917,7 @@ ath_txq_init(struct ath_softc *sc, struc
 	txq->axq_qnum = qnum;
 	txq->axq_ac = 0;
 	txq->axq_depth = 0;
+	txq->axq_aggr_depth = 0;
 	txq->axq_intrcnt = 0;
 	txq->axq_link = NULL;
 	txq->axq_softc = sc;
@@ -4293,6 +4296,8 @@ ath_tx_processq(struct ath_softc *sc, st
 		if (txq->axq_depth == 0)
 #endif
 			txq->axq_link = NULL;
+		if (bf->bf_state.bfs_aggr)
+			txq->axq_aggr_depth--;
 		ATH_TXQ_UNLOCK(txq);
 
 		ni = bf->bf_node;
@@ -4549,6 +4554,8 @@ ath_tx_draintxq(struct ath_softc *sc, st
 			break;
 		}
 		ATH_TXQ_REMOVE(txq, bf, bf_list);
+		if (bf->bf_state.bfs_aggr)
+			txq->axq_aggr_depth--;
 		ATH_TXQ_UNLOCK(txq);
 #ifdef ATH_DEBUG
 		if (sc->sc_debug & ATH_DEBUG_RESET) {

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_sysctl.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_sysctl.c	Tue Aug 23 07:00:51 2011	(r225100)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_sysctl.c	Tue Aug 23 07:17:37 2011	(r225101)
@@ -329,8 +329,10 @@ ath_sysctl_txagg(SYSCTL_HANDLER_ARGS)
 
 	for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
 		if (ATH_TXQ_SETUP(sc, i)) {
-			printf("HW TXQ %d: axq_depth=%d\n",
-			    i, sc->sc_txq[i].axq_depth);
+			printf("HW TXQ %d: axq_depth=%d, axq_aggr_depth=%d\n",
+			    i,
+			    sc->sc_txq[i].axq_depth,
+			    sc->sc_txq[i].axq_aggr_depth);
 		}
 	}
 

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Tue Aug 23 07:00:51 2011	(r225100)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Tue Aug 23 07:17:37 2011	(r225101)
@@ -568,6 +568,8 @@ ath_tx_handoff_hw(struct ath_softc *sc, 
 			    (caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
 		}
 #endif /* IEEE80211_SUPPORT_TDMA */
+		if (bf->bf_state.bfs_aggr)
+			txq->axq_aggr_depth++;
 		txq->axq_link = &bf->bf_lastds->ds_link;
 		ath_hal_txstart(ah, txq->axq_qnum);
 	}
@@ -1946,11 +1948,18 @@ ath_tx_swq(struct ath_softc *sc, struct 
 	/* Queue frame to the tail of the software queue */
 	ATH_TXQ_LOCK(atid);
 	ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
-	ATH_TXQ_UNLOCK(atid);
 
-	ATH_TXQ_LOCK(txq);
-	ath_tx_tid_sched(sc, an, tid);
-	ATH_TXQ_UNLOCK(txq);
+	/*
+	 * Don't queue frames if the TID has a handful
+	 * of hardware queued frames already.
+	 */
+	if (atid->hwq_depth < sc->sc_tid_hwq_hi) {
+		ATH_TXQ_UNLOCK(atid);
+		ATH_TXQ_LOCK(txq);
+		ath_tx_tid_sched(sc, an, tid);
+		ATH_TXQ_UNLOCK(txq);
+	} else
+		ATH_TXQ_UNLOCK(atid);
 }
 
 /*
@@ -3038,18 +3047,17 @@ ath_tx_tid_hw_queue_aggr(struct ath_soft
 		/* aggregates are "one" buffer */
 		ATH_TXQ_LOCK(atid);
 		atid->hwq_depth++;
-		if (atid->hwq_depth >= ATH_AGGR_SCHED_LOW) {
-			ATH_TXQ_UNLOCK(atid);
-			break;
-		}
 		ATH_TXQ_UNLOCK(atid);
 
 		/*
 		 * Break out if ath_tx_form_aggr() indicated
 		 * there can't be any further progress (eg BAW is full.)
 		 * Checking for an empty txq is done above.
+		 *
+		 * XXX locking on txq here?
 		 */
-		if (status == ATH_AGGR_BAW_CLOSED)
+		if (txq->axq_aggr_depth >= sc->sc_hwq_limit ||
+		    status == ATH_AGGR_BAW_CLOSED)
 			break;
 	}
 }
@@ -3149,7 +3157,7 @@ ath_txq_sched(struct ath_softc *sc, stru
 	 * XXX normal ones.
 	 */
 	ATH_TXQ_LOCK(txq);
-	if (txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+	if (txq->axq_aggr_depth >= sc->sc_hwq_limit) {
 		ATH_TXQ_UNLOCK(txq);
 		return;
 	}
@@ -3191,7 +3199,7 @@ ath_txq_sched(struct ath_softc *sc, stru
 			ath_tx_tid_unsched(sc, atid->an, atid->tid);
 
 		/* Give the software queue time to aggregate more packets */
-		if (txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+		if (txq->axq_aggr_depth >= sc->sc_hwq_limit) {
 			//ATH_TXQ_UNLOCK(txq);
 			break;
 		}

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h	Tue Aug 23 07:00:51 2011	(r225100)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h	Tue Aug 23 07:17:37 2011	(r225101)
@@ -271,6 +271,7 @@ struct ath_txq {
 	u_int			axq_flags;
 #define	ATH_TXQ_PUTPENDING	0x0001		/* ath_hal_puttxbuf pending */
 	u_int			axq_depth;	/* queue depth (stat only) */
+	u_int			axq_aggr_depth;	/* how many aggregates are queued */
 	u_int			axq_intrcnt;	/* interrupt count */
 	u_int32_t		*axq_link;	/* link ptr in last TX desc */
 	TAILQ_HEAD(axq_q_s, ath_buf)	axq_q;		/* transmit queue */



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