aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-03-23 12:28:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-27 20:13:21 -0400
commit2a577d98712a284a612dd51d69db5cb989810dc2 (patch)
treec2e667d92d280d404dd964548aefedd43996645c /net/mac80211/util.c
parentf0e72851f7ad108fed20426b46a18ab5fcd5729f (diff)
mac80211: rework the pending packets code
The pending packets code is quite incomprehensible, uses memory barriers nobody really understands, etc. This patch reworks it entirely, using the queue spinlock, proper stop bits and the skb queues themselves to indicate whether packets are pending or not (rather than a separate variable like before). Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Reviewed-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 021166c8cce2..0247d8022f5f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -365,16 +365,16 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
365 365
366 __clear_bit(reason, &local->queue_stop_reasons[queue]); 366 __clear_bit(reason, &local->queue_stop_reasons[queue]);
367 367
368 if (!skb_queue_empty(&local->pending[queue]) &&
369 local->queue_stop_reasons[queue] ==
370 BIT(IEEE80211_QUEUE_STOP_REASON_PENDING))
371 tasklet_schedule(&local->tx_pending_tasklet);
372
368 if (local->queue_stop_reasons[queue] != 0) 373 if (local->queue_stop_reasons[queue] != 0)
369 /* someone still has this queue stopped */ 374 /* someone still has this queue stopped */
370 return; 375 return;
371 376
372 if (test_bit(queue, local->queues_pending)) { 377 netif_wake_subqueue(local->mdev, queue);
373 set_bit(queue, local->queues_pending_run);
374 tasklet_schedule(&local->tx_pending_tasklet);
375 } else {
376 netif_wake_subqueue(local->mdev, queue);
377 }
378} 378}
379 379
380void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 380void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -420,9 +420,15 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
420 reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION; 420 reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION;
421 } 421 }
422 422
423 __set_bit(reason, &local->queue_stop_reasons[queue]); 423 /*
424 * Only stop if it was previously running, this is necessary
425 * for correct pending packets handling because there we may
426 * start (but not wake) the queue and rely on that.
427 */
428 if (!local->queue_stop_reasons[queue])
429 netif_stop_subqueue(local->mdev, queue);
424 430
425 netif_stop_subqueue(local->mdev, queue); 431 __set_bit(reason, &local->queue_stop_reasons[queue]);
426} 432}
427 433
428void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 434void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,