From owner-svn-src-user@FreeBSD.ORG Tue Aug 23 07:17:38 2011 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5543A106564A; Tue, 23 Aug 2011 07:17:38 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 44DBA8FC12; Tue, 23 Aug 2011 07:17:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p7N7Hc18089788; Tue, 23 Aug 2011 07:17:38 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p7N7Hcn4089783; Tue, 23 Aug 2011 07:17:38 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201108230717.p7N7Hcn4089783@svn.freebsd.org> From: Adrian Chadd Date: Tue, 23 Aug 2011 07:17:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225101 - user/adrian/if_ath_tx/sys/dev/ath X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Aug 2011 07:17:38 -0000 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 */