diff options
author | Javier Cardona <javier@cozybit.com> | 2009-08-10 15:15:52 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-14 09:14:01 -0400 |
commit | 18889231e4527dfe23145efe318e74744794a95d (patch) | |
tree | bcb509dab37d80f6dbbfb6671a530aa882c9975e /net/mac80211/mesh.c | |
parent | 5b365834255d7c90fc724b032c814dfa297aacf9 (diff) |
mac80211: Move mpath and mpp growth to mesh workqueue.
This prevents calling rcu_synchronize from within the tx path by moving the
table growth code to the mesh workqueue.
Move mesh_table_free and mesh_table_grow from mesh.c to mesh_pathtbl.c and
declare them static.
Also, re-enable mesh in Kconfig and update the configuration description.
Signed-off-by: Javier Cardona <javier@cozybit.com>
Tested-by: Andrey Yurovsky <andrey@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r-- | net/mac80211/mesh.c | 77 |
1 files changed, 10 insertions, 67 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 25d0065778ef..3185e18c8214 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -47,7 +47,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data) | |||
47 | struct ieee80211_local *local = sdata->local; | 47 | struct ieee80211_local *local = sdata->local; |
48 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 48 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
49 | 49 | ||
50 | ifmsh->housekeeping = true; | 50 | ifmsh->wrkq_flags |= MESH_WORK_HOUSEKEEPING; |
51 | 51 | ||
52 | if (local->quiescing) { | 52 | if (local->quiescing) { |
53 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); | 53 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); |
@@ -320,30 +320,6 @@ struct mesh_table *mesh_table_alloc(int size_order) | |||
320 | return newtbl; | 320 | return newtbl; |
321 | } | 321 | } |
322 | 322 | ||
323 | static void __mesh_table_free(struct mesh_table *tbl) | ||
324 | { | ||
325 | kfree(tbl->hash_buckets); | ||
326 | kfree(tbl->hashwlock); | ||
327 | kfree(tbl); | ||
328 | } | ||
329 | |||
330 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | ||
331 | { | ||
332 | struct hlist_head *mesh_hash; | ||
333 | struct hlist_node *p, *q; | ||
334 | int i; | ||
335 | |||
336 | mesh_hash = tbl->hash_buckets; | ||
337 | for (i = 0; i <= tbl->hash_mask; i++) { | ||
338 | spin_lock(&tbl->hashwlock[i]); | ||
339 | hlist_for_each_safe(p, q, &mesh_hash[i]) { | ||
340 | tbl->free_node(p, free_leafs); | ||
341 | atomic_dec(&tbl->entries); | ||
342 | } | ||
343 | spin_unlock(&tbl->hashwlock[i]); | ||
344 | } | ||
345 | __mesh_table_free(tbl); | ||
346 | } | ||
347 | 323 | ||
348 | static void ieee80211_mesh_path_timer(unsigned long data) | 324 | static void ieee80211_mesh_path_timer(unsigned long data) |
349 | { | 325 | { |
@@ -360,44 +336,6 @@ static void ieee80211_mesh_path_timer(unsigned long data) | |||
360 | ieee80211_queue_work(&local->hw, &ifmsh->work); | 336 | ieee80211_queue_work(&local->hw, &ifmsh->work); |
361 | } | 337 | } |
362 | 338 | ||
363 | struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | ||
364 | { | ||
365 | struct mesh_table *newtbl; | ||
366 | struct hlist_head *oldhash; | ||
367 | struct hlist_node *p, *q; | ||
368 | int i; | ||
369 | |||
370 | if (atomic_read(&tbl->entries) | ||
371 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) | ||
372 | goto endgrow; | ||
373 | |||
374 | newtbl = mesh_table_alloc(tbl->size_order + 1); | ||
375 | if (!newtbl) | ||
376 | goto endgrow; | ||
377 | |||
378 | newtbl->free_node = tbl->free_node; | ||
379 | newtbl->mean_chain_len = tbl->mean_chain_len; | ||
380 | newtbl->copy_node = tbl->copy_node; | ||
381 | atomic_set(&newtbl->entries, atomic_read(&tbl->entries)); | ||
382 | |||
383 | oldhash = tbl->hash_buckets; | ||
384 | for (i = 0; i <= tbl->hash_mask; i++) | ||
385 | hlist_for_each(p, &oldhash[i]) | ||
386 | if (tbl->copy_node(p, newtbl) < 0) | ||
387 | goto errcopy; | ||
388 | |||
389 | return newtbl; | ||
390 | |||
391 | errcopy: | ||
392 | for (i = 0; i <= newtbl->hash_mask; i++) { | ||
393 | hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) | ||
394 | tbl->free_node(p, 0); | ||
395 | } | ||
396 | __mesh_table_free(newtbl); | ||
397 | endgrow: | ||
398 | return NULL; | ||
399 | } | ||
400 | |||
401 | /** | 339 | /** |
402 | * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame | 340 | * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame |
403 | * @hdr: 802.11 frame header | 341 | * @hdr: 802.11 frame header |
@@ -487,7 +425,6 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | |||
487 | if (free_plinks != sdata->u.mesh.accepting_plinks) | 425 | if (free_plinks != sdata->u.mesh.accepting_plinks) |
488 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); | 426 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
489 | 427 | ||
490 | ifmsh->housekeeping = false; | ||
491 | mod_timer(&ifmsh->housekeeping_timer, | 428 | mod_timer(&ifmsh->housekeeping_timer, |
492 | round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); | 429 | round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); |
493 | } | 430 | } |
@@ -524,8 +461,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
524 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 461 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
525 | struct ieee80211_local *local = sdata->local; | 462 | struct ieee80211_local *local = sdata->local; |
526 | 463 | ||
527 | ifmsh->housekeeping = true; | 464 | ifmsh->wrkq_flags |= MESH_WORK_HOUSEKEEPING; |
528 | queue_work(local->hw, &ifmsh->work); | 465 | ieee80211_queue_work(&local->hw, &ifmsh->work); |
529 | sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; | 466 | sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; |
530 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | | 467 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | |
531 | BSS_CHANGED_BEACON_ENABLED | | 468 | BSS_CHANGED_BEACON_ENABLED | |
@@ -664,7 +601,13 @@ static void ieee80211_mesh_work(struct work_struct *work) | |||
664 | ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) | 601 | ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) |
665 | mesh_path_start_discovery(sdata); | 602 | mesh_path_start_discovery(sdata); |
666 | 603 | ||
667 | if (ifmsh->housekeeping) | 604 | if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags)) |
605 | mesh_mpath_table_grow(); | ||
606 | |||
607 | if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags)) | ||
608 | mesh_mpp_table_grow(); | ||
609 | |||
610 | if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) | ||
668 | ieee80211_mesh_housekeeping(sdata, ifmsh); | 611 | ieee80211_mesh_housekeeping(sdata, ifmsh); |
669 | } | 612 | } |
670 | 613 | ||