]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.1.5/mac80211-fix-race-between-the-agg-sm-and-the-tx-data-path.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.1.5 / mac80211-fix-race-between-the-agg-sm-and-the-tx-data-path.patch
1 From 2a1e0fd175dcfd72096ba9291d31e3b1b5342e60 Mon Sep 17 00:00:00 2001
2 From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
3 Date: Sun, 27 Nov 2011 15:29:44 +0200
4 Subject: mac80211: fix race between the AGG SM and the Tx data path
5
6 From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
7
8 commit 2a1e0fd175dcfd72096ba9291d31e3b1b5342e60 upstream.
9
10 When a packet is supposed to sent be as an a-MPDU, mac80211 sets
11 IEEE80211_TX_CTL_AMPDU to let the driver know. On the other
12 hand, mac80211 configures the driver for aggregration with the
13 ampdu_action callback.
14 There is race between these two mechanisms since the following
15 scenario can occur when the BA agreement is torn down:
16
17 Tx softIRQ drv configuration
18 ========== =================
19
20 check OPERATIONAL bit
21 Set the TX_CTL_AMPDU bit in the packet
22
23 clear OPERATIONAL bit
24 stop Tx AGG
25 Pass Tx packet to the driver.
26
27 In that case the driver would get a packet with TX_CTL_AMPDU set
28 although it has already been notified that the BA session has been
29 torn down.
30
31 To fix this, we need to synchronize all the Qdisc activity after we
32 cleared the OPERATIONAL bit. After that step, all the following
33 packets will be buffered until the driver reports it is ready to get
34 new packets for this RA / TID. This buffering allows not to run into
35 another race that would send packets with TX_CTL_AMPDU unset while
36 the driver hasn't been requested to tear down the BA session yet.
37
38 This race occurs in practice and iwlwifi complains with a WARN_ON
39 when it happens.
40
41 Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
42 Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
43 Signed-off-by: John W. Linville <linville@tuxdriver.com>
44 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
45
46 ---
47 net/mac80211/agg-tx.c | 14 ++++++++++++++
48 1 file changed, 14 insertions(+)
49
50 --- a/net/mac80211/agg-tx.c
51 +++ b/net/mac80211/agg-tx.c
52 @@ -194,6 +194,20 @@ int ___ieee80211_stop_tx_ba_session(stru
53 */
54 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
55
56 + /*
57 + * There might be a few packets being processed right now (on
58 + * another CPU) that have already gotten past the aggregation
59 + * check when it was still OPERATIONAL and consequently have
60 + * IEEE80211_TX_CTL_AMPDU set. In that case, this code might
61 + * call into the driver at the same time or even before the
62 + * TX paths calls into it, which could confuse the driver.
63 + *
64 + * Wait for all currently running TX paths to finish before
65 + * telling the driver. New packets will not go through since
66 + * the aggregation session is no longer OPERATIONAL.
67 + */
68 + synchronize_net();
69 +
70 tid_tx->stop_initiator = initiator;
71 tid_tx->tx_stop = tx;
72