aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/agg-tx.c2
-rw-r--r--net/mac80211/sta_info.c25
2 files changed, 27 insertions, 0 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index c45fa5df0d41..5c7f0c3c74cb 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -55,6 +55,8 @@
55 * @ampdu_action function will be called with the action 55 * @ampdu_action function will be called with the action
56 * %IEEE80211_AMPDU_TX_STOP. In this case, the call must not fail, 56 * %IEEE80211_AMPDU_TX_STOP. In this case, the call must not fail,
57 * and the driver must later call ieee80211_stop_tx_ba_cb_irqsafe(). 57 * and the driver must later call ieee80211_stop_tx_ba_cb_irqsafe().
58 * Note that the sta can get destroyed before the BA tear down is
59 * complete.
58 */ 60 */
59 61
60static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, 62static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index f98235262006..c6ca9bd81add 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -851,6 +851,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
851 struct ieee80211_sub_if_data *sdata; 851 struct ieee80211_sub_if_data *sdata;
852 unsigned long flags; 852 unsigned long flags;
853 int ret, i, ac; 853 int ret, i, ac;
854 struct tid_ampdu_tx *tid_tx;
854 855
855 might_sleep(); 856 might_sleep();
856 857
@@ -949,6 +950,30 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
949 } 950 }
950#endif 951#endif
951 952
953 /* There could be some memory leaks because of ampdu tx pending queue
954 * not being freed before destroying the station info.
955 *
956 * Make sure that such queues are purged before freeing the station
957 * info.
958 * TODO: We have to somehow postpone the full destruction
959 * until the aggregation stop completes. Refer
960 * http://thread.gmane.org/gmane.linux.kernel.wireless.general/81936
961 */
962 for (i = 0; i < STA_TID_NUM; i++) {
963 if (!sta->ampdu_mlme.tid_tx[i])
964 continue;
965 tid_tx = sta->ampdu_mlme.tid_tx[i];
966 if (skb_queue_len(&tid_tx->pending)) {
967#ifdef CONFIG_MAC80211_HT_DEBUG
968 wiphy_debug(local->hw.wiphy, "TX A-MPDU purging %d "
969 "packets for tid=%d\n",
970 skb_queue_len(&tid_tx->pending), i);
971#endif /* CONFIG_MAC80211_HT_DEBUG */
972 __skb_queue_purge(&tid_tx->pending);
973 }
974 kfree_rcu(tid_tx, rcu_head);
975 }
976
952 __sta_info_free(local, sta); 977 __sta_info_free(local, sta);
953 978
954 return 0; 979 return 0;