@@ -59,8 +59,10 @@ static struct mesh_table *mesh_table_alloc(void)
59
59
return NULL ;
60
60
61
61
INIT_HLIST_HEAD (& newtbl -> known_gates );
62
+ INIT_HLIST_HEAD (& newtbl -> walk_head );
62
63
atomic_set (& newtbl -> entries , 0 );
63
64
spin_lock_init (& newtbl -> gates_lock );
65
+ spin_lock_init (& newtbl -> walk_lock );
64
66
65
67
return newtbl ;
66
68
}
@@ -249,28 +251,15 @@ mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
249
251
static struct mesh_path *
250
252
__mesh_path_lookup_by_idx (struct mesh_table * tbl , int idx )
251
253
{
252
- int i = 0 , ret ;
253
- struct mesh_path * mpath = NULL ;
254
- struct rhashtable_iter iter ;
255
-
256
- ret = rhashtable_walk_init (& tbl -> rhead , & iter , GFP_ATOMIC );
257
- if (ret )
258
- return NULL ;
259
-
260
- rhashtable_walk_start (& iter );
254
+ int i = 0 ;
255
+ struct mesh_path * mpath ;
261
256
262
- while ((mpath = rhashtable_walk_next (& iter ))) {
263
- if (IS_ERR (mpath ) && PTR_ERR (mpath ) == - EAGAIN )
264
- continue ;
265
- if (IS_ERR (mpath ))
266
- break ;
257
+ hlist_for_each_entry_rcu (mpath , & tbl -> walk_head , walk_list ) {
267
258
if (i ++ == idx )
268
259
break ;
269
260
}
270
- rhashtable_walk_stop (& iter );
271
- rhashtable_walk_exit (& iter );
272
261
273
- if (IS_ERR ( mpath ) || !mpath )
262
+ if (!mpath )
274
263
return NULL ;
275
264
276
265
if (mpath_expired (mpath )) {
@@ -432,6 +421,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata,
432
421
return ERR_PTR (- ENOMEM );
433
422
434
423
tbl = sdata -> u .mesh .mesh_paths ;
424
+ spin_lock_bh (& tbl -> walk_lock );
435
425
do {
436
426
ret = rhashtable_lookup_insert_fast (& tbl -> rhead ,
437
427
& new_mpath -> rhash ,
@@ -441,8 +431,10 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata,
441
431
mpath = rhashtable_lookup_fast (& tbl -> rhead ,
442
432
dst ,
443
433
mesh_rht_params );
444
-
434
+ else if (!ret )
435
+ hlist_add_head (& new_mpath -> walk_list , & tbl -> walk_head );
445
436
} while (unlikely (ret == - EEXIST && !mpath ));
437
+ spin_unlock_bh (& tbl -> walk_lock );
446
438
447
439
if (ret && ret != - EEXIST )
448
440
return ERR_PTR (ret );
@@ -480,9 +472,14 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
480
472
481
473
memcpy (new_mpath -> mpp , mpp , ETH_ALEN );
482
474
tbl = sdata -> u .mesh .mpp_paths ;
475
+
476
+ spin_lock_bh (& tbl -> walk_lock );
483
477
ret = rhashtable_lookup_insert_fast (& tbl -> rhead ,
484
478
& new_mpath -> rhash ,
485
479
mesh_rht_params );
480
+ if (!ret )
481
+ hlist_add_head_rcu (& new_mpath -> walk_list , & tbl -> walk_head );
482
+ spin_unlock_bh (& tbl -> walk_lock );
486
483
487
484
sdata -> u .mesh .mpp_paths_generation ++ ;
488
485
return ret ;
@@ -503,20 +500,9 @@ void mesh_plink_broken(struct sta_info *sta)
503
500
struct mesh_table * tbl = sdata -> u .mesh .mesh_paths ;
504
501
static const u8 bcast [ETH_ALEN ] = {0xff , 0xff , 0xff , 0xff , 0xff , 0xff };
505
502
struct mesh_path * mpath ;
506
- struct rhashtable_iter iter ;
507
- int ret ;
508
-
509
- ret = rhashtable_walk_init (& tbl -> rhead , & iter , GFP_ATOMIC );
510
- if (ret )
511
- return ;
512
-
513
- rhashtable_walk_start (& iter );
514
503
515
- while ((mpath = rhashtable_walk_next (& iter ))) {
516
- if (IS_ERR (mpath ) && PTR_ERR (mpath ) == - EAGAIN )
517
- continue ;
518
- if (IS_ERR (mpath ))
519
- break ;
504
+ rcu_read_lock ();
505
+ hlist_for_each_entry_rcu (mpath , & tbl -> walk_head , walk_list ) {
520
506
if (rcu_access_pointer (mpath -> next_hop ) == sta &&
521
507
mpath -> flags & MESH_PATH_ACTIVE &&
522
508
!(mpath -> flags & MESH_PATH_FIXED )) {
@@ -530,8 +516,7 @@ void mesh_plink_broken(struct sta_info *sta)
530
516
WLAN_REASON_MESH_PATH_DEST_UNREACHABLE , bcast );
531
517
}
532
518
}
533
- rhashtable_walk_stop (& iter );
534
- rhashtable_walk_exit (& iter );
519
+ rcu_read_unlock ();
535
520
}
536
521
537
522
static void mesh_path_free_rcu (struct mesh_table * tbl ,
@@ -551,6 +536,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl,
551
536
552
537
static void __mesh_path_del (struct mesh_table * tbl , struct mesh_path * mpath )
553
538
{
539
+ hlist_del_rcu (& mpath -> walk_list );
554
540
rhashtable_remove_fast (& tbl -> rhead , & mpath -> rhash , mesh_rht_params );
555
541
mesh_path_free_rcu (tbl , mpath );
556
542
}
@@ -571,79 +557,41 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
571
557
struct ieee80211_sub_if_data * sdata = sta -> sdata ;
572
558
struct mesh_table * tbl = sdata -> u .mesh .mesh_paths ;
573
559
struct mesh_path * mpath ;
574
- struct rhashtable_iter iter ;
575
- int ret ;
576
-
577
- ret = rhashtable_walk_init (& tbl -> rhead , & iter , GFP_ATOMIC );
578
- if (ret )
579
- return ;
580
-
581
- rhashtable_walk_start (& iter );
582
-
583
- while ((mpath = rhashtable_walk_next (& iter ))) {
584
- if (IS_ERR (mpath ) && PTR_ERR (mpath ) == - EAGAIN )
585
- continue ;
586
- if (IS_ERR (mpath ))
587
- break ;
560
+ struct hlist_node * n ;
588
561
562
+ spin_lock_bh (& tbl -> walk_lock );
563
+ hlist_for_each_entry_safe (mpath , n , & tbl -> walk_head , walk_list ) {
589
564
if (rcu_access_pointer (mpath -> next_hop ) == sta )
590
565
__mesh_path_del (tbl , mpath );
591
566
}
592
-
593
- rhashtable_walk_stop (& iter );
594
- rhashtable_walk_exit (& iter );
567
+ spin_unlock_bh (& tbl -> walk_lock );
595
568
}
596
569
597
570
static void mpp_flush_by_proxy (struct ieee80211_sub_if_data * sdata ,
598
571
const u8 * proxy )
599
572
{
600
573
struct mesh_table * tbl = sdata -> u .mesh .mpp_paths ;
601
574
struct mesh_path * mpath ;
602
- struct rhashtable_iter iter ;
603
- int ret ;
604
-
605
- ret = rhashtable_walk_init (& tbl -> rhead , & iter , GFP_ATOMIC );
606
- if (ret )
607
- return ;
608
-
609
- rhashtable_walk_start (& iter );
610
-
611
- while ((mpath = rhashtable_walk_next (& iter ))) {
612
- if (IS_ERR (mpath ) && PTR_ERR (mpath ) == - EAGAIN )
613
- continue ;
614
- if (IS_ERR (mpath ))
615
- break ;
575
+ struct hlist_node * n ;
616
576
577
+ spin_lock_bh (& tbl -> walk_lock );
578
+ hlist_for_each_entry_safe (mpath , n , & tbl -> walk_head , walk_list ) {
617
579
if (ether_addr_equal (mpath -> mpp , proxy ))
618
580
__mesh_path_del (tbl , mpath );
619
581
}
620
-
621
- rhashtable_walk_stop (& iter );
622
- rhashtable_walk_exit (& iter );
582
+ spin_unlock_bh (& tbl -> walk_lock );
623
583
}
624
584
625
585
static void table_flush_by_iface (struct mesh_table * tbl )
626
586
{
627
587
struct mesh_path * mpath ;
628
- struct rhashtable_iter iter ;
629
- int ret ;
630
-
631
- ret = rhashtable_walk_init (& tbl -> rhead , & iter , GFP_ATOMIC );
632
- if (ret )
633
- return ;
634
-
635
- rhashtable_walk_start (& iter );
588
+ struct hlist_node * n ;
636
589
637
- while ((mpath = rhashtable_walk_next (& iter ))) {
638
- if (IS_ERR (mpath ) && PTR_ERR (mpath ) == - EAGAIN )
639
- continue ;
640
- if (IS_ERR (mpath ))
641
- break ;
590
+ spin_lock_bh (& tbl -> walk_lock );
591
+ hlist_for_each_entry_safe (mpath , n , & tbl -> walk_head , walk_list ) {
642
592
__mesh_path_del (tbl , mpath );
643
593
}
644
-
645
- rhashtable_walk_stop (& iter );
646
- rhashtable_walk_exit (& iter );
594
+ spin_unlock_bh (& tbl -> walk_lock );
647
595
}
648
596
649
597
/**
@@ -675,15 +623,15 @@ static int table_path_del(struct mesh_table *tbl,
675
623
{
676
624
struct mesh_path * mpath ;
677
625
678
- rcu_read_lock ( );
626
+ spin_lock_bh ( & tbl -> walk_lock );
679
627
mpath = rhashtable_lookup_fast (& tbl -> rhead , addr , mesh_rht_params );
680
628
if (!mpath ) {
681
629
rcu_read_unlock ();
682
630
return - ENXIO ;
683
631
}
684
632
685
633
__mesh_path_del (tbl , mpath );
686
- rcu_read_unlock ( );
634
+ spin_unlock_bh ( & tbl -> walk_lock );
687
635
return 0 ;
688
636
}
689
637
@@ -854,28 +802,16 @@ void mesh_path_tbl_expire(struct ieee80211_sub_if_data *sdata,
854
802
struct mesh_table * tbl )
855
803
{
856
804
struct mesh_path * mpath ;
857
- struct rhashtable_iter iter ;
858
- int ret ;
805
+ struct hlist_node * n ;
859
806
860
- ret = rhashtable_walk_init (& tbl -> rhead , & iter , GFP_KERNEL );
861
- if (ret )
862
- return ;
863
-
864
- rhashtable_walk_start (& iter );
865
-
866
- while ((mpath = rhashtable_walk_next (& iter ))) {
867
- if (IS_ERR (mpath ) && PTR_ERR (mpath ) == - EAGAIN )
868
- continue ;
869
- if (IS_ERR (mpath ))
870
- break ;
807
+ spin_lock_bh (& tbl -> walk_lock );
808
+ hlist_for_each_entry_safe (mpath , n , & tbl -> walk_head , walk_list ) {
871
809
if ((!(mpath -> flags & MESH_PATH_RESOLVING )) &&
872
810
(!(mpath -> flags & MESH_PATH_FIXED )) &&
873
811
time_after (jiffies , mpath -> exp_time + MESH_PATH_EXPIRE ))
874
812
__mesh_path_del (tbl , mpath );
875
813
}
876
-
877
- rhashtable_walk_stop (& iter );
878
- rhashtable_walk_exit (& iter );
814
+ spin_unlock_bh (& tbl -> walk_lock );
879
815
}
880
816
881
817
void mesh_path_expire (struct ieee80211_sub_if_data * sdata )
0 commit comments