aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-02 19:02:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-14 16:29:34 -0400
commit07346f81e87d6e4cca7ae9adfa711d0c61c87b56 (patch)
tree237450c49843e0e19afc79356240a891da64d9fa /net/mac80211/rx.c
parent3434fbd39862d471c92b66c28cd449deea8e9f90 (diff)
mac80211: proper STA info locking
As discussed earlier, we can unify locking in struct sta_info and use just a single spinlock protecting all members of the structure that need protection. Many don't, but one of the especially bad ones is the 'flags' member that can currently be clobbered when RX and TX is being processed on different CPUs at the same time. Because having four spinlocks for different, mostly exclusive parts of a single structure is overkill, this patch also kills the ampdu and mesh plink spinlocks and uses just a single one for everything. Because none of the spinlocks are nested, this is safe. It remains to be seen whether or not we should make the sta flags use atomic bit operations instead, for now though this is a safe thing and using atomic operations instead will be very simple using the new static inline functions this patch introduces for accessing sta->flags. Since spin_lock_bh() is used with this lock, there shouldn't be any contention even if aggregation is enabled at around the same time as both requires frame transmission/reception which is in a bh context. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Cc: Tomas Winkler <tomasw@gmail.com> Cc: Ron Rindjunsky <ron.rindjunsky@intel.com> Cc: Luis Carlos Cobo <luisca@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e8b89c89e875..b399e09ec7aa 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -479,7 +479,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
479 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && 479 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL &&
480 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && 480 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
481 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 481 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
482 (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { 482 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
483 if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && 483 if ((!(rx->fc & IEEE80211_FCTL_FROMDS) &&
484 !(rx->fc & IEEE80211_FCTL_TODS) && 484 !(rx->fc & IEEE80211_FCTL_TODS) &&
485 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) 485 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
@@ -630,8 +630,7 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta)
630 630
631 if (sdata->bss) 631 if (sdata->bss)
632 atomic_inc(&sdata->bss->num_sta_ps); 632 atomic_inc(&sdata->bss->num_sta_ps);
633 sta->flags |= WLAN_STA_PS; 633 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
634 sta->flags &= ~WLAN_STA_PSPOLL;
635#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 634#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
636 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", 635 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n",
637 dev->name, print_mac(mac, sta->addr), sta->aid); 636 dev->name, print_mac(mac, sta->addr), sta->aid);
@@ -652,7 +651,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
652 if (sdata->bss) 651 if (sdata->bss)
653 atomic_dec(&sdata->bss->num_sta_ps); 652 atomic_dec(&sdata->bss->num_sta_ps);
654 653
655 sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL); 654 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
656 655
657 if (!skb_queue_empty(&sta->ps_tx_buf)) 656 if (!skb_queue_empty(&sta->ps_tx_buf))
658 sta_info_clear_tim_bit(sta); 657 sta_info_clear_tim_bit(sta);
@@ -727,9 +726,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
727 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { 726 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) {
728 /* Change STA power saving mode only in the end of a frame 727 /* Change STA power saving mode only in the end of a frame
729 * exchange sequence */ 728 * exchange sequence */
730 if ((sta->flags & WLAN_STA_PS) && !(rx->fc & IEEE80211_FCTL_PM)) 729 if (test_sta_flags(sta, WLAN_STA_PS) &&
730 !(rx->fc & IEEE80211_FCTL_PM))
731 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); 731 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta);
732 else if (!(sta->flags & WLAN_STA_PS) && 732 else if (!test_sta_flags(sta, WLAN_STA_PS) &&
733 (rx->fc & IEEE80211_FCTL_PM)) 733 (rx->fc & IEEE80211_FCTL_PM))
734 ap_sta_ps_start(dev, sta); 734 ap_sta_ps_start(dev, sta);
735 } 735 }
@@ -983,7 +983,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
983 * Tell TX path to send one frame even though the STA may 983 * Tell TX path to send one frame even though the STA may
984 * still remain is PS mode after this frame exchange. 984 * still remain is PS mode after this frame exchange.
985 */ 985 */
986 rx->sta->flags |= WLAN_STA_PSPOLL; 986 set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
987 987
988#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 988#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
989 printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", 989 printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n",
@@ -1046,7 +1046,8 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
1046static int 1046static int
1047ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) 1047ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
1048{ 1048{
1049 if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) { 1049 if (unlikely(!rx->sta ||
1050 !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) {
1050#ifdef CONFIG_MAC80211_DEBUG 1051#ifdef CONFIG_MAC80211_DEBUG
1051 if (net_ratelimit()) 1052 if (net_ratelimit())
1052 printk(KERN_DEBUG "%s: dropped frame " 1053 printk(KERN_DEBUG "%s: dropped frame "