aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.c
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2009-08-10 15:15:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:14:01 -0400
commit18889231e4527dfe23145efe318e74744794a95d (patch)
treebcb509dab37d80f6dbbfb6671a530aa882c9975e /net/mac80211/mesh.c
parent5b365834255d7c90fc724b032c814dfa297aacf9 (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.c77
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
323static void __mesh_table_free(struct mesh_table *tbl)
324{
325 kfree(tbl->hash_buckets);
326 kfree(tbl->hashwlock);
327 kfree(tbl);
328}
329
330void 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
348static void ieee80211_mesh_path_timer(unsigned long data) 324static 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
363struct 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
391errcopy:
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);
397endgrow:
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