From owner-svn-src-all@FreeBSD.ORG Mon Jan 21 04:06:05 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 3826C6F7; Mon, 21 Jan 2013 04:06:05 +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 13698844; Mon, 21 Jan 2013 04:06:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0L464Zd047245; Mon, 21 Jan 2013 04:06:04 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0L464os047243; Mon, 21 Jan 2013 04:06:04 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201301210406.r0L464os047243@svn.freebsd.org> From: Adrian Chadd Date: Mon, 21 Jan 2013 04:06:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r245708 - head/sys/dev/ath X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Jan 2013 04:06:05 -0000 Author: adrian Date: Mon Jan 21 04:06:04 2013 New Revision: 245708 URL: http://svnweb.freebsd.org/changeset/base/245708 Log: Migrate CLRDMASK to be a per-node flag, rather than a per-TID flag. This is easily possible now that the TX is protected by a single lock, rather than a per-TXQ (and thus per-TID) lock. Only set CLRDMASK if none of the destinations are filtered. This likely will need some tuning when it comes time to do UASPD/PS-POLL TX, however at that point it should be manually set anyway. Tested: * AR9280, STA mode TODO: * More thorough testing in AP mode * test other chipsets, just to be safe/sure. Modified: head/sys/dev/ath/if_ath_tx.c head/sys/dev/ath/if_athvar.h Modified: head/sys/dev/ath/if_ath_tx.c ============================================================================== --- head/sys/dev/ath/if_ath_tx.c Mon Jan 21 02:47:14 2013 (r245707) +++ head/sys/dev/ath/if_ath_tx.c Mon Jan 21 04:06:04 2013 (r245708) @@ -1397,12 +1397,13 @@ static void ath_tx_update_clrdmask(struct ath_softc *sc, struct ath_tid *tid, struct ath_buf *bf) { + struct ath_node *an = ATH_NODE(bf->bf_node); ATH_TX_LOCK_ASSERT(sc); - if (tid->clrdmask == 1) { + if (an->clrdmask == 1) { bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; - tid->clrdmask = 0; + an->clrdmask = 0; } } @@ -2888,6 +2889,29 @@ ath_tx_swq(struct ath_softc *sc, struct } /* + * Only set the clrdmask bit if none of the nodes are currently + * filtered. + * + * XXX TODO: go through all the callers and check to see + * which are being called in the context of looping over all + * TIDs (eg, if all tids are being paused, resumed, etc.) + * That'll avoid O(n^2) complexity here. + */ +static void +ath_tx_set_clrdmask(struct ath_softc *sc, struct ath_node *an) +{ + int i; + + ATH_TX_LOCK_ASSERT(sc); + + for (i = 0; i < IEEE80211_TID_SIZE; i++) { + if (an->an_tid[i].isfiltered == 1) + break; + } + an->clrdmask = 1; +} + +/* * Configure the per-TID node state. * * This likely belongs in if_ath_node.c but I can't think of anywhere @@ -2918,12 +2942,12 @@ ath_tx_tid_init(struct ath_softc *sc, st atid->sched = 0; atid->hwq_depth = 0; atid->cleanup_inprogress = 0; - atid->clrdmask = 1; /* Always start by setting this bit */ if (i == IEEE80211_NONQOS_TID) atid->ac = ATH_NONQOS_TID_AC; else atid->ac = TID_TO_WME_AC(i); } + an->clrdmask = 1; /* Always start by setting this bit */ } /* @@ -2949,7 +2973,6 @@ ath_tx_tid_pause(struct ath_softc *sc, s static void ath_tx_tid_resume(struct ath_softc *sc, struct ath_tid *tid) { - ATH_TX_LOCK_ASSERT(sc); tid->paused--; @@ -2964,7 +2987,7 @@ ath_tx_tid_resume(struct ath_softc *sc, * Override the clrdmask configuration for the next frame * from this TID, just to get the ball rolling. */ - tid->clrdmask = 1; + ath_tx_set_clrdmask(sc, tid->an); if (tid->axq_depth == 0) return; @@ -3047,7 +3070,8 @@ ath_tx_tid_filt_comp_complete(struct ath DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: hwq=0, transition back\n", __func__); tid->isfiltered = 0; - tid->clrdmask = 1; + /* XXX ath_tx_tid_resume() also calls ath_tx_set_clrdmask()! */ + ath_tx_set_clrdmask(sc, tid->an); /* XXX this is really quite inefficient */ while ((bf = ATH_TID_FILT_LAST(tid, ath_bufhead_s)) != NULL) { @@ -3303,7 +3327,7 @@ ath_tx_tid_bar_tx(struct ath_softc *sc, * Override the clrdmask configuration for the next frame, * just to get the ball rolling. */ - tid->clrdmask = 1; + ath_tx_set_clrdmask(sc, tid->an); /* * Calculate new BAW left edge, now that all frames have either @@ -3484,7 +3508,7 @@ ath_tx_tid_drain(struct ath_softc *sc, s * * This won't hurt things if the TID is about to be freed. */ - tid->clrdmask = 1; + ath_tx_set_clrdmask(sc, tid->an); /* * Now that it's completed, grab the TID lock and update Modified: head/sys/dev/ath/if_athvar.h ============================================================================== --- head/sys/dev/ath/if_athvar.h Mon Jan 21 02:47:14 2013 (r245707) +++ head/sys/dev/ath/if_athvar.h Mon Jan 21 04:06:04 2013 (r245708) @@ -132,7 +132,6 @@ struct ath_tid { int bar_wait; /* waiting for BAR */ int bar_tx; /* BAR TXed */ int isfiltered; /* is this node currently filtered */ - int clrdmask; /* has clrdmask been set */ /* * Is the TID being cleaned up after a transition @@ -182,6 +181,7 @@ struct ath_node { struct mtx an_mtx; /* protecting the ath_node state */ uint32_t an_swq_depth; /* how many SWQ packets for this node */ + int clrdmask; /* has clrdmask been set */ /* variable-length rate control state follows */ }; #define ATH_NODE(ni) ((struct ath_node *)(ni))