diff options
author | Javier Cardona <javier@cozybit.com> | 2011-08-29 16:23:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-13 15:42:33 -0400 |
commit | 239289e446d4e86ae94b1ca57e358b106cc4bee6 (patch) | |
tree | d0fe60443519912a7af5730e7e09dd0e89271721 /net/mac80211 | |
parent | cd72e817480bd3a1d2cdf03b65a1f3920c1c88a0 (diff) |
mac80211: Consolidate mesh path duplicated functions
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 70 |
1 files changed, 28 insertions, 42 deletions
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 7797f55eec46..a66a2cab8d34 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -48,10 +48,10 @@ static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ | |||
48 | int mesh_paths_generation; | 48 | int mesh_paths_generation; |
49 | 49 | ||
50 | /* This lock will have the grow table function as writer and add / delete nodes | 50 | /* This lock will have the grow table function as writer and add / delete nodes |
51 | * as readers. When reading the table (i.e. doing lookups) we are well protected | 51 | * as readers. RCU provides sufficient protection only when reading the table |
52 | * by RCU. We need to take this lock when modying the number of buckets | 52 | * (i.e. doing lookups). Adding or adding or removing nodes requires we take |
53 | * on one of the path tables but we don't need to if adding or removing mpaths | 53 | * the read lock or we risk operating on an old table. The write lock is only |
54 | * from hash buckets. | 54 | * needed when modifying the number of buckets a table. |
55 | */ | 55 | */ |
56 | static DEFINE_RWLOCK(pathtbl_resize_lock); | 56 | static DEFINE_RWLOCK(pathtbl_resize_lock); |
57 | 57 | ||
@@ -335,25 +335,14 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath, | |||
335 | } | 335 | } |
336 | 336 | ||
337 | 337 | ||
338 | /** | 338 | static struct mesh_path *path_lookup(struct mesh_table *tbl, u8 *dst, |
339 | * mesh_path_lookup - look up a path in the mesh path table | 339 | struct ieee80211_sub_if_data *sdata) |
340 | * @dst: hardware address (ETH_ALEN length) of destination | ||
341 | * @sdata: local subif | ||
342 | * | ||
343 | * Returns: pointer to the mesh path structure, or NULL if not found | ||
344 | * | ||
345 | * Locking: must be called within a read rcu section. | ||
346 | */ | ||
347 | struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) | ||
348 | { | 340 | { |
349 | struct mesh_path *mpath; | 341 | struct mesh_path *mpath; |
350 | struct hlist_node *n; | 342 | struct hlist_node *n; |
351 | struct hlist_head *bucket; | 343 | struct hlist_head *bucket; |
352 | struct mesh_table *tbl; | ||
353 | struct mpath_node *node; | 344 | struct mpath_node *node; |
354 | 345 | ||
355 | tbl = rcu_dereference(mesh_paths); | ||
356 | |||
357 | bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)]; | 346 | bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)]; |
358 | hlist_for_each_entry_rcu(node, n, bucket, list) { | 347 | hlist_for_each_entry_rcu(node, n, bucket, list) { |
359 | mpath = node->mpath; | 348 | mpath = node->mpath; |
@@ -370,30 +359,23 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
370 | return NULL; | 359 | return NULL; |
371 | } | 360 | } |
372 | 361 | ||
373 | struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) | 362 | /** |
363 | * mesh_path_lookup - look up a path in the mesh path table | ||
364 | * @dst: hardware address (ETH_ALEN length) of destination | ||
365 | * @sdata: local subif | ||
366 | * | ||
367 | * Returns: pointer to the mesh path structure, or NULL if not found | ||
368 | * | ||
369 | * Locking: must be called within a read rcu section. | ||
370 | */ | ||
371 | struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) | ||
374 | { | 372 | { |
375 | struct mesh_path *mpath; | 373 | return path_lookup(rcu_dereference(mesh_paths), dst, sdata); |
376 | struct hlist_node *n; | 374 | } |
377 | struct hlist_head *bucket; | ||
378 | struct mesh_table *tbl; | ||
379 | struct mpath_node *node; | ||
380 | |||
381 | tbl = rcu_dereference(mpp_paths); | ||
382 | 375 | ||
383 | bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)]; | 376 | struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) |
384 | hlist_for_each_entry_rcu(node, n, bucket, list) { | 377 | { |
385 | mpath = node->mpath; | 378 | return path_lookup(rcu_dereference(mpp_paths), dst, sdata); |
386 | if (mpath->sdata == sdata && | ||
387 | memcmp(dst, mpath->dst, ETH_ALEN) == 0) { | ||
388 | if (MPATH_EXPIRED(mpath)) { | ||
389 | spin_lock_bh(&mpath->state_lock); | ||
390 | mpath->flags &= ~MESH_PATH_ACTIVE; | ||
391 | spin_unlock_bh(&mpath->state_lock); | ||
392 | } | ||
393 | return mpath; | ||
394 | } | ||
395 | } | ||
396 | return NULL; | ||
397 | } | 379 | } |
398 | 380 | ||
399 | 381 | ||
@@ -836,7 +818,8 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) | |||
836 | int i; | 818 | int i; |
837 | 819 | ||
838 | rcu_read_lock(); | 820 | rcu_read_lock(); |
839 | tbl = rcu_dereference(mesh_paths); | 821 | read_lock_bh(&pathtbl_resize_lock); |
822 | tbl = resize_dereference_mesh_paths(); | ||
840 | for_each_mesh_entry(tbl, p, node, i) { | 823 | for_each_mesh_entry(tbl, p, node, i) { |
841 | mpath = node->mpath; | 824 | mpath = node->mpath; |
842 | if (rcu_dereference(mpath->next_hop) == sta) { | 825 | if (rcu_dereference(mpath->next_hop) == sta) { |
@@ -845,6 +828,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) | |||
845 | spin_unlock_bh(&tbl->hashwlock[i]); | 828 | spin_unlock_bh(&tbl->hashwlock[i]); |
846 | } | 829 | } |
847 | } | 830 | } |
831 | read_unlock_bh(&pathtbl_resize_lock); | ||
848 | rcu_read_unlock(); | 832 | rcu_read_unlock(); |
849 | } | 833 | } |
850 | 834 | ||
@@ -880,10 +864,12 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) | |||
880 | struct mesh_table *tbl; | 864 | struct mesh_table *tbl; |
881 | 865 | ||
882 | rcu_read_lock(); | 866 | rcu_read_lock(); |
883 | tbl = rcu_dereference(mesh_paths); | 867 | read_lock_bh(&pathtbl_resize_lock); |
868 | tbl = resize_dereference_mesh_paths(); | ||
884 | table_flush_by_iface(tbl, sdata); | 869 | table_flush_by_iface(tbl, sdata); |
885 | tbl = rcu_dereference(mpp_paths); | 870 | tbl = resize_dereference_mpp_paths(); |
886 | table_flush_by_iface(tbl, sdata); | 871 | table_flush_by_iface(tbl, sdata); |
872 | read_unlock_bh(&pathtbl_resize_lock); | ||
887 | rcu_read_unlock(); | 873 | rcu_read_unlock(); |
888 | } | 874 | } |
889 | 875 | ||