diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-02-25 10:27:46 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-06 15:30:46 -0500 |
commit | d0709a65181beb787ef3f58cfe45536a2bb254c8 (patch) | |
tree | 29e5f36583b0e0a3f11b291347e57672eab41dad /net/mac80211/mesh_hwmp.c | |
parent | 5cf121c3cdb955583bf0c5d28c992b7968a4aa1a (diff) |
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/mesh_hwmp.c')
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 6 |
1 files changed, 1 insertions, 5 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index c2f40ef418cf..d8530fe7a0b3 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -294,7 +294,6 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
294 | orig_metric = PREP_IE_METRIC(hwmp_ie); | 294 | orig_metric = PREP_IE_METRIC(hwmp_ie); |
295 | break; | 295 | break; |
296 | default: | 296 | default: |
297 | sta_info_put(sta); | ||
298 | rcu_read_unlock(); | 297 | rcu_read_unlock(); |
299 | return 0; | 298 | return 0; |
300 | } | 299 | } |
@@ -330,7 +329,6 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
330 | mpath = mesh_path_lookup(orig_addr, dev); | 329 | mpath = mesh_path_lookup(orig_addr, dev); |
331 | if (!mpath) { | 330 | if (!mpath) { |
332 | rcu_read_unlock(); | 331 | rcu_read_unlock(); |
333 | sta_info_put(sta); | ||
334 | return 0; | 332 | return 0; |
335 | } | 333 | } |
336 | spin_lock_bh(&mpath->state_lock); | 334 | spin_lock_bh(&mpath->state_lock); |
@@ -372,7 +370,6 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
372 | mpath = mesh_path_lookup(ta, dev); | 370 | mpath = mesh_path_lookup(ta, dev); |
373 | if (!mpath) { | 371 | if (!mpath) { |
374 | rcu_read_unlock(); | 372 | rcu_read_unlock(); |
375 | sta_info_put(sta); | ||
376 | return 0; | 373 | return 0; |
377 | } | 374 | } |
378 | spin_lock_bh(&mpath->state_lock); | 375 | spin_lock_bh(&mpath->state_lock); |
@@ -391,7 +388,6 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
391 | spin_unlock_bh(&mpath->state_lock); | 388 | spin_unlock_bh(&mpath->state_lock); |
392 | } | 389 | } |
393 | 390 | ||
394 | sta_info_put(sta); | ||
395 | rcu_read_unlock(); | 391 | rcu_read_unlock(); |
396 | 392 | ||
397 | return process ? new_metric : 0; | 393 | return process ? new_metric : 0; |
@@ -861,5 +857,5 @@ void mesh_path_timer(unsigned long data) | |||
861 | endmpathtimer: | 857 | endmpathtimer: |
862 | rcu_read_unlock(); | 858 | rcu_read_unlock(); |
863 | if (delete) | 859 | if (delete) |
864 | mesh_path_del(mpath->dst, mpath->dev); | 860 | mesh_path_del(mpath->dst, mpath->dev, false); |
865 | } | 861 | } |