diff options
-rw-r--r-- | net/mac80211/agg-tx.c | 2 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 25 |
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 | ||
60 | static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | 62 | static 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; |