aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelmut Schaa <helmut.schaa@googlemail.com>2012-03-07 11:20:30 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-12 14:19:35 -0400
commitaa4545806025c63ec12cfe17528de16dca36b785 (patch)
treea979799e3eb20b97f92483d327ea2f4115fe11af
parent4486ea987efdaa546bdda569e3dfacdc14a9fb13 (diff)
mac80211: Limit TID buffering during BA session setup/teardown
While setting up or tearing down a BA session mac80211 is buffering pending frames for the according TID. However, there's currently no limit on how many frames are buffered possibly leading to an out-of- memory situation. This can happen on systems with little memory when the CPU is fully loaded since the BA session work is executed in process context while frames can still come via softirq. Apply a limitation to the TIDs pending queue to avoid consuming too much memory in this situation. Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/tx.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 570737df2d22..d9e791d2b543 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1065,6 +1065,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1065{ 1065{
1066 bool queued = false; 1066 bool queued = false;
1067 bool reset_agg_timer = false; 1067 bool reset_agg_timer = false;
1068 struct sk_buff *purge_skb = NULL;
1068 1069
1069 if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { 1070 if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
1070 info->flags |= IEEE80211_TX_CTL_AMPDU; 1071 info->flags |= IEEE80211_TX_CTL_AMPDU;
@@ -1106,8 +1107,13 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1106 info->control.vif = &tx->sdata->vif; 1107 info->control.vif = &tx->sdata->vif;
1107 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1108 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1108 __skb_queue_tail(&tid_tx->pending, skb); 1109 __skb_queue_tail(&tid_tx->pending, skb);
1110 if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER)
1111 purge_skb = __skb_dequeue(&tid_tx->pending);
1109 } 1112 }
1110 spin_unlock(&tx->sta->lock); 1113 spin_unlock(&tx->sta->lock);
1114
1115 if (purge_skb)
1116 dev_kfree_skb(purge_skb);
1111 } 1117 }
1112 1118
1113 /* reset session timer */ 1119 /* reset session timer */