Changeset 29493


Ignore:
Timestamp:
2011-12-10T22:16:58+01:00 (4 years ago)
Author:
nbd
Message:

mac80211: merge an upstream fix for an aggregation related race condition

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/package/mac80211/patches/300-pending_work.patch

    r29460 r29493  
    533533        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 
    534534                                          IEEE80211_STYPE_ACTION); 
    535 @@ -437,7 +440,9 @@ int ieee80211_start_tx_ba_session(struct 
     535@@ -319,6 +322,38 @@ ieee80211_wake_queue_agg(struct ieee8021 
     536        __release(agg_queue); 
     537 } 
     538  
     539+/* 
     540+ * splice packets from the STA's pending to the local pending, 
     541+ * requires a call to ieee80211_agg_splice_finish later 
     542+ */ 
     543+static void __acquires(agg_queue) 
     544+ieee80211_agg_splice_packets(struct ieee80211_local *local, 
     545+                            struct tid_ampdu_tx *tid_tx, u16 tid) 
     546+{ 
     547+       int queue = ieee80211_ac_from_tid(tid); 
     548+       unsigned long flags; 
     549+ 
     550+       ieee80211_stop_queue_agg(local, tid); 
     551+ 
     552+       if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" 
     553+                         " from the pending queue\n", tid)) 
     554+               return; 
     555+ 
     556+       if (!skb_queue_empty(&tid_tx->pending)) { 
     557+               spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 
     558+               /* copy over remaining packets */ 
     559+               skb_queue_splice_tail_init(&tid_tx->pending, 
     560+                                          &local->pending[queue]); 
     561+               spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 
     562+       } 
     563+} 
     564+ 
     565+static void __releases(agg_queue) 
     566+ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid) 
     567+{ 
     568+       ieee80211_wake_queue_agg(local, tid); 
     569+} 
     570+ 
     571 void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) 
     572 { 
     573        struct tid_ampdu_tx *tid_tx; 
     574@@ -330,19 +365,17 @@ void ieee80211_tx_ba_session_handle_star 
     575        tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 
     576  
     577        /* 
     578-        * While we're asking the driver about the aggregation, 
     579-        * stop the AC queue so that we don't have to worry 
     580-        * about frames that came in while we were doing that, 
     581-        * which would require us to put them to the AC pending 
     582-        * afterwards which just makes the code more complex. 
     583+        * Start queuing up packets for this aggregation session. 
     584+        * We're going to release them once the driver is OK with 
     585+        * that. 
     586         */ 
     587-       ieee80211_stop_queue_agg(local, tid); 
     588- 
     589        clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); 
     590  
     591        /* 
     592-        * make sure no packets are being processed to get 
     593-        * valid starting sequence number 
     594+        * Make sure no packets are being processed. This ensures that 
     595+        * we have a valid starting sequence number and that in-flight 
     596+        * packets have been flushed out and no packets for this TID 
     597+        * will go into the driver during the ampdu_action call. 
     598         */ 
     599        synchronize_net(); 
     600  
     601@@ -356,10 +389,11 @@ void ieee80211_tx_ba_session_handle_star 
     602                                        " tid %d\n", tid); 
     603 #endif 
     604                spin_lock_bh(&sta->lock); 
     605+               ieee80211_agg_splice_packets(local, tid_tx, tid); 
     606                ieee80211_assign_tid_tx(sta, tid, NULL); 
     607+               ieee80211_agg_splice_finish(local, tid); 
     608                spin_unlock_bh(&sta->lock); 
     609  
     610-               ieee80211_wake_queue_agg(local, tid); 
     611 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) 
     612                kfree_rcu(tid_tx, rcu_head); 
     613 #else 
     614@@ -368,9 +402,6 @@ void ieee80211_tx_ba_session_handle_star 
     615                return; 
     616        } 
     617  
     618-       /* we can take packets again now */ 
     619-       ieee80211_wake_queue_agg(local, tid); 
     620- 
     621        /* activate the timer for the recipient's addBA response */ 
     622        mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); 
     623 #ifdef CONFIG_MAC80211_HT_DEBUG 
     624@@ -437,7 +468,9 @@ int ieee80211_start_tx_ba_session(struct 
    536625        if (sdata->vif.type != NL80211_IFTYPE_STATION && 
    537626            sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 
     
    544633  
    545634        if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { 
    546 @@ -448,6 +453,27 @@ int ieee80211_start_tx_ba_session(struct 
     635@@ -448,6 +481,27 @@ int ieee80211_start_tx_ba_session(struct 
    547636                return -EINVAL; 
    548637        } 
     
    572661  
    573662        /* we have tried too many times, receiver does not want A-MPDU */ 
     663@@ -508,38 +562,6 @@ int ieee80211_start_tx_ba_session(struct 
     664 } 
     665 EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 
     666  
     667-/* 
     668- * splice packets from the STA's pending to the local pending, 
     669- * requires a call to ieee80211_agg_splice_finish later 
     670- */ 
     671-static void __acquires(agg_queue) 
     672-ieee80211_agg_splice_packets(struct ieee80211_local *local, 
     673-                            struct tid_ampdu_tx *tid_tx, u16 tid) 
     674-{ 
     675-       int queue = ieee80211_ac_from_tid(tid); 
     676-       unsigned long flags; 
     677- 
     678-       ieee80211_stop_queue_agg(local, tid); 
     679- 
     680-       if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" 
     681-                         " from the pending queue\n", tid)) 
     682-               return; 
     683- 
     684-       if (!skb_queue_empty(&tid_tx->pending)) { 
     685-               spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 
     686-               /* copy over remaining packets */ 
     687-               skb_queue_splice_tail_init(&tid_tx->pending, 
     688-                                          &local->pending[queue]); 
     689-               spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 
     690-       } 
     691-} 
     692- 
     693-static void __releases(agg_queue) 
     694-ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid) 
     695-{ 
     696-       ieee80211_wake_queue_agg(local, tid); 
     697-} 
     698- 
     699 static void ieee80211_agg_tx_operational(struct ieee80211_local *local, 
     700                                         struct sta_info *sta, u16 tid) 
     701 { 
    574702--- a/net/mac80211/debugfs_sta.c 
    575703+++ b/net/mac80211/debugfs_sta.c 
Note: See TracChangeset for help on using the changeset viewer.