svn commit: r237038 - head/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Thu Jun 14 00:51:54 UTC 2012
Author: adrian
Date: Thu Jun 14 00:51:53 2012
New Revision: 237038
URL: http://svn.freebsd.org/changeset/base/237038
Log:
Implement a global (all non-mgmt traffic) TX ath_buf limitation when
ath_start() is called.
This (defaults to 10 frames) gives for a little headway in the TX ath_buf
allocation, so buffer cloning is still possible.
This requires a lot omre experimenting and tuning.
It also doesn't stop a node/TID from consuming all of the available
ath_buf's, especially when the node is going through high packet loss
or only talking at a low TX rate. It also doesn't stop a paused TID
from taking all of the ath_bufs. I'll look at fixing that up in subsequent
commits.
PR: kern/168170
Modified:
head/sys/dev/ath/if_ath.c
head/sys/dev/ath/if_ath_sysctl.c
head/sys/dev/ath/if_athvar.h
Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c Wed Jun 13 22:53:56 2012 (r237037)
+++ head/sys/dev/ath/if_ath.c Thu Jun 14 00:51:53 2012 (r237038)
@@ -2239,8 +2239,22 @@ _ath_getbuf_locked(struct ath_softc *sc,
if (bf != NULL && (bf->bf_flags & ATH_BUF_BUSY) == 0) {
if (btype == ATH_BUFTYPE_MGMT)
TAILQ_REMOVE(&sc->sc_txbuf_mgmt, bf, bf_list);
- else
+ else {
TAILQ_REMOVE(&sc->sc_txbuf, bf, bf_list);
+ sc->sc_txbuf_cnt--;
+
+ /*
+ * This shuldn't happen; however just to be
+ * safe print a warning and fudge the txbuf
+ * count.
+ */
+ if (sc->sc_txbuf_cnt < 0) {
+ device_printf(sc->sc_dev,
+ "%s: sc_txbuf_cnt < 0?\n",
+ __func__);
+ sc->sc_txbuf_cnt = 0;
+ }
+ }
} else
bf = NULL;
@@ -2367,6 +2381,7 @@ ath_start(struct ifnet *ifp)
"%s: sc_inreset_cnt > 0; bailing\n", __func__);
ATH_PCU_UNLOCK(sc);
IF_LOCK(&ifp->if_snd);
+ sc->sc_stats.ast_tx_qstop++;
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
IF_UNLOCK(&ifp->if_snd);
return;
@@ -2375,6 +2390,17 @@ ath_start(struct ifnet *ifp)
ATH_PCU_UNLOCK(sc);
for (;;) {
+ ATH_TXBUF_LOCK(sc);
+ if (sc->sc_txbuf_cnt <= sc->sc_txq_data_minfree) {
+ /* XXX increment counter? */
+ ATH_TXBUF_UNLOCK(sc);
+ IF_LOCK(&ifp->if_snd);
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ IF_UNLOCK(&ifp->if_snd);
+ break;
+ }
+ ATH_TXBUF_UNLOCK(sc);
+
/*
* Grab a TX buffer and associated resources.
*/
@@ -2883,6 +2909,7 @@ ath_desc_alloc(struct ath_softc *sc)
ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
return error;
}
+ sc->sc_txbuf_cnt = ath_txbuf;
error = ath_descdma_setup(sc, &sc->sc_txdma_mgmt, &sc->sc_txbuf_mgmt,
"tx_mgmt", ath_txbuf_mgmt, ATH_TXDESC);
@@ -3686,8 +3713,17 @@ ath_returnbuf_tail(struct ath_softc *sc,
if (bf->bf_flags & ATH_BUF_MGMT)
TAILQ_INSERT_TAIL(&sc->sc_txbuf_mgmt, bf, bf_list);
- else
+ else {
TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
+ sc->sc_txbuf_cnt++;
+ if (sc->sc_txbuf_cnt > ath_txbuf) {
+ device_printf(sc->sc_dev,
+ "%s: sc_txbuf_cnt > %d?\n",
+ __func__,
+ ath_txbuf);
+ sc->sc_txbuf_cnt = ath_txbuf;
+ }
+ }
}
void
@@ -3698,8 +3734,17 @@ ath_returnbuf_head(struct ath_softc *sc,
if (bf->bf_flags & ATH_BUF_MGMT)
TAILQ_INSERT_HEAD(&sc->sc_txbuf_mgmt, bf, bf_list);
- else
+ else {
TAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
+ sc->sc_txbuf_cnt++;
+ if (sc->sc_txbuf_cnt > ATH_TXBUF) {
+ device_printf(sc->sc_dev,
+ "%s: sc_txbuf_cnt > %d?\n",
+ __func__,
+ ATH_TXBUF);
+ sc->sc_txbuf_cnt = ATH_TXBUF;
+ }
+ }
}
/*
Modified: head/sys/dev/ath/if_ath_sysctl.c
==============================================================================
--- head/sys/dev/ath/if_ath_sysctl.c Wed Jun 13 22:53:56 2012 (r237037)
+++ head/sys/dev/ath/if_ath_sysctl.c Thu Jun 14 00:51:53 2012 (r237038)
@@ -374,8 +374,8 @@ ath_sysctl_txagg(SYSCTL_HANDLER_ARGS)
t++;
}
ATH_TXBUF_UNLOCK(sc);
- printf("Total TX buffers: %d; Total TX buffers busy: %d\n",
- t, i);
+ printf("Total TX buffers: %d; Total TX buffers busy: %d (%d)\n",
+ t, i, sc->sc_txbuf_cnt);
i = t = 0;
ATH_TXBUF_LOCK(sc);
@@ -620,12 +620,11 @@ ath_sysctlattach(struct ath_softc *sc)
"tid_hwq_hi", CTLFLAG_RW, &sc->sc_tid_hwq_hi, 0,
"");
-#if 0
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"txq_data_minfree", CTLFLAG_RW, &sc->sc_txq_data_minfree,
0, "Minimum free buffers before adding a data frame"
" to the TX queue");
-#endif
+
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"txq_mcastq_maxdepth", CTLFLAG_RW,
&sc->sc_txq_mcastq_maxdepth, 0,
Modified: head/sys/dev/ath/if_athvar.h
==============================================================================
--- head/sys/dev/ath/if_athvar.h Wed Jun 13 22:53:56 2012 (r237037)
+++ head/sys/dev/ath/if_athvar.h Thu Jun 14 00:51:53 2012 (r237038)
@@ -501,6 +501,7 @@ struct ath_softc {
struct ath_descdma sc_txdma; /* TX descriptors */
ath_bufhead sc_txbuf; /* transmit buffer */
+ int sc_txbuf_cnt; /* how many buffers avail */
struct ath_descdma sc_txdma_mgmt; /* mgmt TX descriptors */
ath_bufhead sc_txbuf_mgmt; /* mgmt transmit buffer */
struct mtx sc_txbuflock; /* txbuf lock */
More information about the svn-src-all
mailing list