aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_sta.c
diff options
context:
space:
mode:
authorMichael Wu <flamingice@sourmilk.net>2007-07-27 09:43:23 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:47:37 -0400
commitbe8755e1804d6f60e6a96a46ac6bc46ce6dfca53 (patch)
treea3038a924114f49aa2372ab7c9417d4e072c4b20 /net/mac80211/ieee80211_sta.c
parentc2d1560ad8c2f6e0dd0d34102d022f3709325c26 (diff)
[MAC80211]: improve locking of sta_info related structures
The sta_info code has some awkward locking which prevents some driver callbacks from being allowed to sleep. This patch makes the locking more focused so code that calls driver callbacks are allowed to sleep. It also converts sta_lock to a rwlock. Signed-off-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: Jiri Benc <jbenc@suse.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ieee80211_sta.c')
-rw-r--r--net/mac80211/ieee80211_sta.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 0d99b685df5f..9aee1abae127 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -773,7 +773,7 @@ static void ieee80211_associated(struct net_device *dev,
773 "range\n", 773 "range\n",
774 dev->name, MAC_ARG(ifsta->bssid)); 774 dev->name, MAC_ARG(ifsta->bssid));
775 disassoc = 1; 775 disassoc = 1;
776 sta_info_free(sta, 0); 776 sta_info_free(sta);
777 ifsta->probereq_poll = 0; 777 ifsta->probereq_poll = 0;
778 } else { 778 } else {
779 ieee80211_send_probe_req(dev, ifsta->bssid, 779 ieee80211_send_probe_req(dev, ifsta->bssid,
@@ -1890,7 +1890,7 @@ static int ieee80211_sta_active_ibss(struct net_device *dev)
1890 int active = 0; 1890 int active = 0;
1891 struct sta_info *sta; 1891 struct sta_info *sta;
1892 1892
1893 spin_lock_bh(&local->sta_lock); 1893 read_lock_bh(&local->sta_lock);
1894 list_for_each_entry(sta, &local->sta_list, list) { 1894 list_for_each_entry(sta, &local->sta_list, list) {
1895 if (sta->dev == dev && 1895 if (sta->dev == dev &&
1896 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL, 1896 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
@@ -1899,7 +1899,7 @@ static int ieee80211_sta_active_ibss(struct net_device *dev)
1899 break; 1899 break;
1900 } 1900 }
1901 } 1901 }
1902 spin_unlock_bh(&local->sta_lock); 1902 read_unlock_bh(&local->sta_lock);
1903 1903
1904 return active; 1904 return active;
1905} 1905}
@@ -1909,16 +1909,24 @@ static void ieee80211_sta_expire(struct net_device *dev)
1909{ 1909{
1910 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1910 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1911 struct sta_info *sta, *tmp; 1911 struct sta_info *sta, *tmp;
1912 LIST_HEAD(tmp_list);
1912 1913
1913 spin_lock_bh(&local->sta_lock); 1914 write_lock_bh(&local->sta_lock);
1914 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) 1915 list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
1915 if (time_after(jiffies, sta->last_rx + 1916 if (time_after(jiffies, sta->last_rx +
1916 IEEE80211_IBSS_INACTIVITY_LIMIT)) { 1917 IEEE80211_IBSS_INACTIVITY_LIMIT)) {
1917 printk(KERN_DEBUG "%s: expiring inactive STA " MAC_FMT 1918 printk(KERN_DEBUG "%s: expiring inactive STA " MAC_FMT
1918 "\n", dev->name, MAC_ARG(sta->addr)); 1919 "\n", dev->name, MAC_ARG(sta->addr));
1919 sta_info_free(sta, 1); 1920 __sta_info_get(sta);
1921 sta_info_remove(sta);
1922 list_add(&sta->list, &tmp_list);
1920 } 1923 }
1921 spin_unlock_bh(&local->sta_lock); 1924 write_unlock_bh(&local->sta_lock);
1925
1926 list_for_each_entry_safe(sta, tmp, &tmp_list, list) {
1927 sta_info_free(sta);
1928 sta_info_put(sta);
1929 }
1922} 1930}
1923 1931
1924 1932