Commit 31e79a5954b78fbed15de2c8974d5a2b6019199a

Authored by Felix Fietkau
Committed by John W. Linville
1 parent 57674308d0

ath9k: another fix for the A-MPDU buffer leak

The patch 'ath9k: fix a buffer leak in A-MPDU completion' addressed the
issue of running out of buffers/descriptors in the tx path if a STA is
deleted while tx status feedback is still pending.
The remaining issue is that the skbs of the buffers are not reclaimed,
leaving a memory leak.
This patch fixes this issue by running the buffers through
ath_tx_complete_buf(), ensuring that the pending frames counter is also
updated.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@kernel.org
Signed-off-by: John W. Linville <linville@tuxdriver.com>

Showing 1 changed file with 15 additions and 4 deletions Side-by-side Diff

drivers/net/wireless/ath/ath9k/xmit.c
... ... @@ -329,7 +329,6 @@
329 329 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
330 330 bool rc_update = true;
331 331 struct ieee80211_tx_rate rates[4];
332   - unsigned long flags;
333 332  
334 333 skb = bf->bf_mpdu;
335 334 hdr = (struct ieee80211_hdr *)skb->data;
... ... @@ -346,9 +345,21 @@
346 345 if (!sta) {
347 346 rcu_read_unlock();
348 347  
349   - spin_lock_irqsave(&sc->tx.txbuflock, flags);
350   - list_splice_tail_init(bf_q, &sc->tx.txbuf);
351   - spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
  348 + INIT_LIST_HEAD(&bf_head);
  349 + while (bf) {
  350 + bf_next = bf->bf_next;
  351 +
  352 + bf->bf_state.bf_type |= BUF_XRETRY;
  353 + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ||
  354 + !bf->bf_stale || bf_next != NULL)
  355 + list_move_tail(&bf->list, &bf_head);
  356 +
  357 + ath_tx_rc_status(bf, ts, 0, 0, false);
  358 + ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
  359 + 0, 0);
  360 +
  361 + bf = bf_next;
  362 + }
352 363 return;
353 364 }
354 365