diff options
author | Johannes Berg <johannes.berg@intel.com> | 2015-05-19 09:40:21 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2015-05-19 09:46:21 -0400 |
commit | 22d3a3c829fa9ecdb493d1f1f2838d543f8d86a3 (patch) | |
tree | d8961aabf48478add145e56acc0683fec328f9b1 /net | |
parent | 47b4e1fc4972cc43a19121bc2608a60aef3bf216 (diff) |
mac80211: don't use napi_gro_receive() outside NAPI context
No matter how the driver manages its NAPI context, there's no way
sending frames to it from a timer can be correct, since it would
corrupt the internal GRO lists.
To avoid that, always use the non-NAPI path when releasing frames
from the timer.
Cc: stable@vger.kernel.org
Reported-by: Jean Trivelly <jean.trivelly@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/rx.c | 5 |
2 files changed, 6 insertions, 2 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ab46ab4a7249..cdc374296245 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -205,6 +205,8 @@ enum ieee80211_packet_rx_flags { | |||
205 | * @IEEE80211_RX_CMNTR: received on cooked monitor already | 205 | * @IEEE80211_RX_CMNTR: received on cooked monitor already |
206 | * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported | 206 | * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported |
207 | * to cfg80211_report_obss_beacon(). | 207 | * to cfg80211_report_obss_beacon(). |
208 | * @IEEE80211_RX_REORDER_TIMER: this frame is released by the | ||
209 | * reorder buffer timeout timer, not the normal RX path | ||
208 | * | 210 | * |
209 | * These flags are used across handling multiple interfaces | 211 | * These flags are used across handling multiple interfaces |
210 | * for a single frame. | 212 | * for a single frame. |
@@ -212,6 +214,7 @@ enum ieee80211_packet_rx_flags { | |||
212 | enum ieee80211_rx_flags { | 214 | enum ieee80211_rx_flags { |
213 | IEEE80211_RX_CMNTR = BIT(0), | 215 | IEEE80211_RX_CMNTR = BIT(0), |
214 | IEEE80211_RX_BEACON_REPORTED = BIT(1), | 216 | IEEE80211_RX_BEACON_REPORTED = BIT(1), |
217 | IEEE80211_RX_REORDER_TIMER = BIT(2), | ||
215 | }; | 218 | }; |
216 | 219 | ||
217 | struct ieee80211_rx_data { | 220 | struct ieee80211_rx_data { |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 260eed45b6d2..5793f75c5ffd 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2121,7 +2121,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
2121 | /* deliver to local stack */ | 2121 | /* deliver to local stack */ |
2122 | skb->protocol = eth_type_trans(skb, dev); | 2122 | skb->protocol = eth_type_trans(skb, dev); |
2123 | memset(skb->cb, 0, sizeof(skb->cb)); | 2123 | memset(skb->cb, 0, sizeof(skb->cb)); |
2124 | if (rx->local->napi) | 2124 | if (!(rx->flags & IEEE80211_RX_REORDER_TIMER) && |
2125 | rx->local->napi) | ||
2125 | napi_gro_receive(rx->local->napi, skb); | 2126 | napi_gro_receive(rx->local->napi, skb); |
2126 | else | 2127 | else |
2127 | netif_receive_skb(skb); | 2128 | netif_receive_skb(skb); |
@@ -3231,7 +3232,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
3231 | /* This is OK -- must be QoS data frame */ | 3232 | /* This is OK -- must be QoS data frame */ |
3232 | .security_idx = tid, | 3233 | .security_idx = tid, |
3233 | .seqno_idx = tid, | 3234 | .seqno_idx = tid, |
3234 | .flags = 0, | 3235 | .flags = IEEE80211_RX_REORDER_TIMER, |
3235 | }; | 3236 | }; |
3236 | struct tid_ampdu_rx *tid_agg_rx; | 3237 | struct tid_ampdu_rx *tid_agg_rx; |
3237 | 3238 | ||