From owner-svn-src-head@FreeBSD.ORG Thu Jun 14 00:51:54 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 13833106566B; Thu, 14 Jun 2012 00:51:54 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [69.147.83.44]) by mx1.freebsd.org (Postfix) with ESMTP id F34B28FC12; Thu, 14 Jun 2012 00:51:53 +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 q5E0prXS059275; Thu, 14 Jun 2012 00:51:53 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q5E0priH059271; Thu, 14 Jun 2012 00:51:53 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201206140051.q5E0priH059271@svn.freebsd.org> From: Adrian Chadd Date: Thu, 14 Jun 2012 00:51:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r237038 - head/sys/dev/ath X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jun 2012 00:51:54 -0000 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 */