svn commit: r225101 - user/adrian/if_ath_tx/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Tue Aug 23 07:17:38 UTC 2011
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 */
More information about the svn-src-user
mailing list