summaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_rate.c
diff options
context:
space:
mode:
authorJohannes Berg2008-02-25 16:27:46 +0100
committerJohn W. Linville2008-03-06 21:30:46 +0100
commitd0709a65181beb787ef3f58cfe45536a2bb254c8 (patch)
tree29e5f36583b0e0a3f11b291347e57672eab41dad /net/mac80211/ieee80211_rate.c
parentmac80211: split ieee80211_txrx_data (diff)
downloadkernel-qcow2-linux-d0709a65181beb787ef3f58cfe45536a2bb254c8.tar.gz
kernel-qcow2-linux-d0709a65181beb787ef3f58cfe45536a2bb254c8.tar.xz
kernel-qcow2-linux-d0709a65181beb787ef3f58cfe45536a2bb254c8.zip
mac80211: RCU-ify STA info structure access
This makes access to the STA hash table/list use RCU to protect against freeing of items. However, it's not a true RCU, the copy step is missing: whenever somebody changes a STA item it is simply updated. This is an existing race condition that is now somewhat understandable. This patch also fixes the race key freeing vs. STA destruction by making sure that sta_info_destroy() is always called under RTNL and frees the key. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ieee80211_rate.c')
-rw-r--r--net/mac80211/ieee80211_rate.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c
index ebe29b716b27..4de06f128d90 100644
--- a/net/mac80211/ieee80211_rate.c
+++ b/net/mac80211/ieee80211_rate.c
@@ -170,9 +170,12 @@ void rate_control_get_rate(struct net_device *dev,
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct rate_control_ref *ref = local->rate_ctrl;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct sta_info *sta = sta_info_get(local, hdr->addr1);
+ struct sta_info *sta;
int i;
+ rcu_read_lock();
+ sta = sta_info_get(local, hdr->addr1);
+
memset(sel, 0, sizeof(struct rate_selection));
ref->ops->get_rate(ref->priv, dev, sband, skb, sel);
@@ -190,8 +193,7 @@ void rate_control_get_rate(struct net_device *dev,
}
}
- if (sta)
- sta_info_put(sta);
+ rcu_read_unlock();
}
struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)