Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Mar 2013 20:00:08 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r248341 - head/sys/dev/ath
Message-ID:  <201303152000.r2FK08fc046856@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Fri Mar 15 20:00:08 2013
New Revision: 248341
URL: http://svnweb.freebsd.org/changeset/base/248341

Log:
  Fix two bugs:
  
  * when pulling frames off of the TID queue, the ATH_TID_REMOVE()
    macro decrements the axq_depth field.  So don't do it twice.
  
  * in ath_tx_comp_cleanup_aggr(), bf wasn't being reset to bf_first
    before walking the buffer list to complete buffers; so those buffers
    will leak.

Modified:
  head/sys/dev/ath/if_ath_tx.c

Modified: head/sys/dev/ath/if_ath_tx.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx.c	Fri Mar 15 19:58:44 2013	(r248340)
+++ head/sys/dev/ath/if_ath_tx.c	Fri Mar 15 20:00:08 2013	(r248341)
@@ -3757,7 +3757,8 @@ ath_tx_tid_cleanup(struct ath_softc *sc,
 		if (bf->bf_state.bfs_isretried) {
 			bf_next = TAILQ_NEXT(bf, bf_list);
 			ATH_TID_REMOVE(atid, bf, bf_list);
-			atid->axq_depth--;
+			// Don't need this anymore; ATH_TID_REMOVE() decrements it for us
+			//atid->axq_depth--;
 			if (bf->bf_state.bfs_dobaw) {
 				ath_tx_update_baw(sc, an, atid, bf);
 				if (! bf->bf_state.bfs_addedbaw)
@@ -4140,11 +4141,10 @@ ath_tx_comp_cleanup_aggr(struct ath_soft
 	int tid = bf_first->bf_state.bfs_tid;
 	struct ath_tid *atid = &an->an_tid[tid];
 
-	bf = bf_first;
-
 	ATH_TX_LOCK(sc);
 
 	/* update incomp */
+	bf = bf_first;
 	while (bf) {
 		atid->incomp--;
 		bf = bf->bf_next;
@@ -4160,12 +4160,17 @@ ath_tx_comp_cleanup_aggr(struct ath_soft
 
 	/* Send BAR if required */
 	/* XXX why would we send a BAR when transitioning to non-aggregation? */
+	/*
+	 * XXX TODO: we should likely just tear down the BAR state here,
+	 * rather than sending a BAR.
+	 */
 	if (ath_tx_tid_bar_tx_ready(sc, atid))
 		ath_tx_tid_bar_tx(sc, atid);
 
 	ATH_TX_UNLOCK(sc);
 
 	/* Handle frame completion */
+	bf = bf_first;
 	while (bf) {
 		bf_next = bf->bf_next;
 		ath_tx_default_comp(sc, bf, 1);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303152000.r2FK08fc046856>