| From 4cee78614cfa046a26c4fbf313d5bbacb3ad8efc Mon Sep 17 00:00:00 2001 |
| From: Felix Fietkau <nbd@openwrt.org> |
| Date: Fri, 23 Jul 2010 03:53:16 +0200 |
| Subject: ath9k: fix yet another buffer leak in the tx aggregation code |
| |
| From: Felix Fietkau <nbd@openwrt.org> |
| |
| commit 4cee78614cfa046a26c4fbf313d5bbacb3ad8efc upstream. |
| |
| When an aggregation session is being cleaned up, while the tx status |
| for some frames is being processed, the TID is flushed and its buffers |
| are sent out. |
| |
| Unfortunately that left the pending un-acked frames unprocessed, thus |
| leaking buffers. Fix this by reordering the code so that those frames |
| are processed first, before the TID is flushed. |
| |
| Signed-off-by: Felix Fietkau <nbd@openwrt.org> |
| Signed-off-by: John W. Linville <linville@tuxdriver.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/net/wireless/ath/ath9k/xmit.c | 16 ++++++++-------- |
| 1 file changed, 8 insertions(+), 8 deletions(-) |
| |
| --- a/drivers/net/wireless/ath/ath9k/xmit.c |
| +++ b/drivers/net/wireless/ath/ath9k/xmit.c |
| @@ -423,6 +423,14 @@ static void ath_tx_complete_aggr(struct |
| bf = bf_next; |
| } |
| |
| + /* prepend un-acked frames to the beginning of the pending frame queue */ |
| + if (!list_empty(&bf_pending)) { |
| + spin_lock_bh(&txq->axq_lock); |
| + list_splice(&bf_pending, &tid->buf_q); |
| + ath_tx_queue_tid(txq, tid); |
| + spin_unlock_bh(&txq->axq_lock); |
| + } |
| + |
| if (tid->state & AGGR_CLEANUP) { |
| if (tid->baw_head == tid->baw_tail) { |
| tid->state &= ~AGGR_ADDBA_COMPLETE; |
| @@ -435,14 +443,6 @@ static void ath_tx_complete_aggr(struct |
| return; |
| } |
| |
| - /* prepend un-acked frames to the beginning of the pending frame queue */ |
| - if (!list_empty(&bf_pending)) { |
| - spin_lock_bh(&txq->axq_lock); |
| - list_splice(&bf_pending, &tid->buf_q); |
| - ath_tx_queue_tid(txq, tid); |
| - spin_unlock_bh(&txq->axq_lock); |
| - } |
| - |
| rcu_read_unlock(); |
| |
| if (needreset) |