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>