Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Oct 2004 23:37:24 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 64003 for review
Message-ID:  <200410302337.i9UNbOqm088758@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=64003

Change 64003 by sam@sam_ebb on 2004/10/30 23:36:50

	Reclaim node references when cleaning the tx queues when a
	node is cleansed.  Previously we could get away with just
	nulling out the held reference as we were only called just
	before the node was reclaimed.  But with recent changes to
	cleanup node state separately from freeing a node we must
	properly release references.  This fixes refcnt leaks when
	operating as an ap.

Affected files ...

.. //depot/projects/wifi/sys/dev/ath/if_ath.c#5 edit

Differences ...

==== //depot/projects/wifi/sys/dev/ath/if_ath.c#5 (text+ko) ====

@@ -2023,20 +2023,26 @@
 
 /*
  * Clear any references to a node in a transmit queue.
- * This happens when the node is removed so we don't
- * need to worry about reclaiming reference counts; we
- * just null the pointer and the right thing will happen
- * when the buffer is cleaned.
+ * This happens when the node is cleaned so we don't
+ * need to worry about the reference count going to zero;
+ * we just reclaim the reference w/o dropping the txq lock.
+ * Then we null the pointer and the right thing happens
+ * when the buffer is cleaned in ath_tx_processq.
  */
 static void
-ath_tx_cleanq(struct ath_txq *txq, struct ieee80211_node *ni)
+ath_tx_cleanq(struct ieee80211com *ic, struct ath_txq *txq,
+	struct ieee80211_node *ni)
 {
 	struct ath_buf *bf;
 
 	ATH_TXQ_LOCK(txq);
 	STAILQ_FOREACH(bf, &txq->axq_q, bf_list) {
-		if (bf->bf_node == ni)
+		if (bf->bf_node == ni) {
 			bf->bf_node = NULL;
+			if (ni != ic->ic_bss)
+				/* NB: cannot use ieee80211_unref_node */
+				ieee80211_node_decref(ni);
+		}
 	}
 	ATH_TXQ_UNLOCK(txq);
 }
@@ -2051,7 +2057,7 @@
 
 	for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
 		if (ATH_TXQ_SETUP(sc, i))
-			ath_tx_cleanq(&sc->sc_txq[i], ni);
+			ath_tx_cleanq(ic, &sc->sc_txq[i], ni);
 	ath_rate_node_cleanup(sc, ATH_NODE(ni));
 	sc->sc_node_cleanup(ic, ni);
 }


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