diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2010-04-19 03:12:52 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-19 16:41:42 -0400 |
commit | 3393a608c4979a94d1887efc05b792849d361a65 (patch) | |
tree | 0aceeb1e67fd23f82844086fcc5fb6c16b24dafc /net/mac80211 | |
parent | 2aab4c273ad837fbcf2955aee32b9ec4706c2521 (diff) |
mac80211: Prevent running sta_cleanup timer unnecessarily
The sta_cleanup timer is used to periodically expire buffered frames from the
tx buf. The timer is executing periodically, regardless of the need for it.
This is wasting resources.
Fix this simply by not restarting the sta_cleanup timer if the tx buffer was
empty. Restart the timer when there is some more tx-traffic.
Cc: Janne Ylälehto <janne.ylalehto@nokia.com>
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/sta_info.c | 13 | ||||
-rw-r--r-- | net/mac80211/tx.c | 7 |
2 files changed, 17 insertions, 3 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ff0eb948917b..3de7a2260d65 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -575,7 +575,7 @@ static int sta_info_buffer_expired(struct sta_info *sta, | |||
575 | } | 575 | } |
576 | 576 | ||
577 | 577 | ||
578 | static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | 578 | static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, |
579 | struct sta_info *sta) | 579 | struct sta_info *sta) |
580 | { | 580 | { |
581 | unsigned long flags; | 581 | unsigned long flags; |
@@ -583,7 +583,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
583 | struct ieee80211_sub_if_data *sdata; | 583 | struct ieee80211_sub_if_data *sdata; |
584 | 584 | ||
585 | if (skb_queue_empty(&sta->ps_tx_buf)) | 585 | if (skb_queue_empty(&sta->ps_tx_buf)) |
586 | return; | 586 | return false; |
587 | 587 | ||
588 | for (;;) { | 588 | for (;;) { |
589 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); | 589 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); |
@@ -608,6 +608,8 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
608 | if (skb_queue_empty(&sta->ps_tx_buf)) | 608 | if (skb_queue_empty(&sta->ps_tx_buf)) |
609 | sta_info_clear_tim_bit(sta); | 609 | sta_info_clear_tim_bit(sta); |
610 | } | 610 | } |
611 | |||
612 | return true; | ||
611 | } | 613 | } |
612 | 614 | ||
613 | static int __must_check __sta_info_destroy(struct sta_info *sta) | 615 | static int __must_check __sta_info_destroy(struct sta_info *sta) |
@@ -755,15 +757,20 @@ static void sta_info_cleanup(unsigned long data) | |||
755 | { | 757 | { |
756 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 758 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
757 | struct sta_info *sta; | 759 | struct sta_info *sta; |
760 | bool timer_needed = false; | ||
758 | 761 | ||
759 | rcu_read_lock(); | 762 | rcu_read_lock(); |
760 | list_for_each_entry_rcu(sta, &local->sta_list, list) | 763 | list_for_each_entry_rcu(sta, &local->sta_list, list) |
761 | sta_info_cleanup_expire_buffered(local, sta); | 764 | if (sta_info_cleanup_expire_buffered(local, sta)) |
765 | timer_needed = true; | ||
762 | rcu_read_unlock(); | 766 | rcu_read_unlock(); |
763 | 767 | ||
764 | if (local->quiescing) | 768 | if (local->quiescing) |
765 | return; | 769 | return; |
766 | 770 | ||
771 | if (!timer_needed) | ||
772 | return; | ||
773 | |||
767 | local->sta_cleanup.expires = | 774 | local->sta_cleanup.expires = |
768 | round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); | 775 | round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); |
769 | add_timer(&local->sta_cleanup); | 776 | add_timer(&local->sta_cleanup); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2cb77267f733..e2aa972d584f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -429,6 +429,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
429 | struct sta_info *sta = tx->sta; | 429 | struct sta_info *sta = tx->sta; |
430 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 430 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
431 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 431 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
432 | struct ieee80211_local *local = tx->local; | ||
432 | u32 staflags; | 433 | u32 staflags; |
433 | 434 | ||
434 | if (unlikely(!sta || | 435 | if (unlikely(!sta || |
@@ -476,6 +477,12 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
476 | info->control.vif = &tx->sdata->vif; | 477 | info->control.vif = &tx->sdata->vif; |
477 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 478 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
478 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 479 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); |
480 | |||
481 | if (!timer_pending(&local->sta_cleanup)) | ||
482 | mod_timer(&local->sta_cleanup, | ||
483 | round_jiffies(jiffies + | ||
484 | STA_INFO_CLEANUP_INTERVAL)); | ||
485 | |||
479 | return TX_QUEUED; | 486 | return TX_QUEUED; |
480 | } | 487 | } |
481 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 488 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |