From owner-svn-src-user@FreeBSD.ORG Thu Apr 25 08:57:17 2013 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 0303BAAA; Thu, 25 Apr 2013 08:57:17 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id D9925169D; Thu, 25 Apr 2013 08:57:16 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3P8vGk4078881; Thu, 25 Apr 2013 08:57:16 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3P8vF27078876; Thu, 25 Apr 2013 08:57:15 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201304250857.r3P8vF27078876@svn.freebsd.org> From: Adrian Chadd Date: Thu, 25 Apr 2013 08:57:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r249890 - user/adrian/net80211_tx/sys/dev/ath X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.14 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: Thu, 25 Apr 2013 08:57:17 -0000 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