svn commit: r249890 - user/adrian/net80211_tx/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Thu Apr 25 08:57:17 UTC 2013
Author: adrian
Date: Thu Apr 25 08:57:15 2013
New Revision: 249890
URL: http://svnweb.freebsd.org/changeset/base/249890
Log:
Implement a hack to limit the queue depth of a node if it's asleep.
It's a hack; it only works for the normal data path and only for data
frames. But it's a start and it should limit ath_buf exhaustion when
there's a whole bunch of data pending for a node (eg if it's running
at a low MCS rate) and it goes to sleep.
Modified:
user/adrian/net80211_tx/sys/dev/ath/if_ath.c
user/adrian/net80211_tx/sys/dev/ath/if_ath_sysctl.c
user/adrian/net80211_tx/sys/dev/ath/if_ath_tx.c
user/adrian/net80211_tx/sys/dev/ath/if_athioctl.h
user/adrian/net80211_tx/sys/dev/ath/if_athvar.h
Modified: user/adrian/net80211_tx/sys/dev/ath/if_ath.c
==============================================================================
--- user/adrian/net80211_tx/sys/dev/ath/if_ath.c Thu Apr 25 08:37:18 2013 (r249889)
+++ user/adrian/net80211_tx/sys/dev/ath/if_ath.c Thu Apr 25 08:57:15 2013 (r249890)
@@ -688,6 +688,7 @@ ath_attach(u_int16_t devid, struct ath_s
* otherwise) to be transmitted.
*/
sc->sc_txq_data_minfree = 10;
+
/*
* Leave this as default to maintain legacy behaviour.
* Shortening the cabq/mcastq may end up causing some
@@ -695,6 +696,11 @@ ath_attach(u_int16_t devid, struct ath_s
*/
sc->sc_txq_mcastq_maxdepth = ath_txbuf;
+ /*
+ * How deep can the node software TX queue get whilst it's asleep.
+ */
+ sc->sc_txq_node_psq_maxdepth = 16;
+
/* Enable CABQ by default */
sc->sc_cabq_enable = 1;
Modified: user/adrian/net80211_tx/sys/dev/ath/if_ath_sysctl.c
==============================================================================
--- user/adrian/net80211_tx/sys/dev/ath/if_ath_sysctl.c Thu Apr 25 08:37:18 2013 (r249889)
+++ user/adrian/net80211_tx/sys/dev/ath/if_ath_sysctl.c Thu Apr 25 08:57:15 2013 (r249890)
@@ -754,6 +754,11 @@ ath_sysctlattach(struct ath_softc *sc)
&sc->sc_txq_mcastq_maxdepth, 0,
"Maximum buffer depth for multicast/broadcast frames");
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "sc_txq_node_psq_maxdepth", CTLFLAG_RW,
+ &sc->sc_txq_node_psq_maxdepth, 0,
+ "Maximum queue depth for a node in powersave");
+
#if 0
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"cabq_enable", CTLFLAG_RW,
@@ -1073,6 +1078,9 @@ ath_sysctl_stats_attach(struct ath_softc
&sc->sc_stats.ast_rx_keymiss, 0, "");
SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swfiltered", CTLFLAG_RD,
&sc->sc_stats.ast_tx_swfiltered, 0, "");
+ SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_node_psq_overflow",
+ CTLFLAG_RD, &sc->sc_stats.ast_tx_node_psq_overflow, 0,
+ "Number of frames dropped because the node was in powersave");
/* Attach the RX phy error array */
ath_sysctl_stats_attach_rxphyerr(sc, child);
Modified: user/adrian/net80211_tx/sys/dev/ath/if_ath_tx.c
==============================================================================
--- user/adrian/net80211_tx/sys/dev/ath/if_ath_tx.c Thu Apr 25 08:37:18 2013 (r249889)
+++ user/adrian/net80211_tx/sys/dev/ath/if_ath_tx.c Thu Apr 25 08:57:15 2013 (r249890)
@@ -1917,6 +1917,32 @@ ath_tx_start(struct ath_softc *sc, struc
}
}
+ /*
+ * Enforce how deep the unicast queue can grow.
+ *
+ * If the node is in power save then we don't want
+ * the software queue to grow too deep, or a node may
+ * end up consuming all of the ath_buf entries.
+ *
+ * For now, only do this for DATA frames.
+ *
+ * We will want to cap how many management/control
+ * frames get punted to the software queue so it doesn't
+ * fill up. But the correct solution isn't yet obvious.
+ * In any case, this check should at least let frames pass
+ * that we are direct-dispatching.
+ *
+ * XXX TODO: duplicate this to the raw xmit path!
+ */
+ if (type == IEEE80211_FC0_TYPE_DATA &&
+ ATH_NODE(ni)->an_is_powersave &&
+ atomic_load_acq_int(&ATH_NODE(ni)->an_swq_depth) >
+ sc->sc_txq_node_psq_maxdepth) {
+ sc->sc_stats.ast_tx_node_psq_overflow++;
+ m_freem(m0);
+ return (ENOBUFS);
+ }
+
/* A-MPDU TX */
is_ampdu_tx = ath_tx_ampdu_running(sc, ATH_NODE(ni), tid);
is_ampdu_pending = ath_tx_ampdu_pending(sc, ATH_NODE(ni), tid);
Modified: user/adrian/net80211_tx/sys/dev/ath/if_athioctl.h
==============================================================================
--- user/adrian/net80211_tx/sys/dev/ath/if_athioctl.h Thu Apr 25 08:37:18 2013 (r249889)
+++ user/adrian/net80211_tx/sys/dev/ath/if_athioctl.h Thu Apr 25 08:57:15 2013 (r249890)
@@ -163,8 +163,8 @@ struct ath_stats {
u_int32_t ast_tx_mcastq_overflow; /* multicast queue overflow */
u_int32_t ast_rx_keymiss;
u_int32_t ast_tx_swfiltered;
-
- u_int32_t ast_pad[15];
+ u_int32_t ast_tx_node_psq_overflow;
+ u_int32_t ast_pad[14];
};
#define SIOCGATHSTATS _IOWR('i', 137, struct ifreq)
Modified: user/adrian/net80211_tx/sys/dev/ath/if_athvar.h
==============================================================================
--- user/adrian/net80211_tx/sys/dev/ath/if_athvar.h Thu Apr 25 08:37:18 2013 (r249889)
+++ user/adrian/net80211_tx/sys/dev/ath/if_athvar.h Thu Apr 25 08:57:15 2013 (r249890)
@@ -794,6 +794,8 @@ struct ath_softc {
* management/multicast frames;
* + multicast frames overwhelming everything (when the
* air is sufficiently busy that cabq can't drain.)
+ * + A node in powersave shouldn't be allowed to exhaust
+ * all available mbufs;
*
* These implement:
* + data_minfree is the maximum number of free buffers
@@ -803,6 +805,7 @@ struct ath_softc {
*/
int sc_txq_data_minfree;
int sc_txq_mcastq_maxdepth;
+ int sc_txq_node_psq_maxdepth;
/*
* Aggregation twiddles
More information about the svn-src-user
mailing list