@@ -829,21 +829,25 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
829
829
if (bond_is_lb (bond )) {
830
830
bond_alb_handle_active_change (bond , new_active );
831
831
if (old_active )
832
- bond_set_slave_inactive_flags (old_active );
832
+ bond_set_slave_inactive_flags (old_active ,
833
+ BOND_SLAVE_NOTIFY_NOW );
833
834
if (new_active )
834
- bond_set_slave_active_flags (new_active );
835
+ bond_set_slave_active_flags (new_active ,
836
+ BOND_SLAVE_NOTIFY_NOW );
835
837
} else {
836
838
rcu_assign_pointer (bond -> curr_active_slave , new_active );
837
839
}
838
840
839
841
if (bond -> params .mode == BOND_MODE_ACTIVEBACKUP ) {
840
842
if (old_active )
841
- bond_set_slave_inactive_flags (old_active );
843
+ bond_set_slave_inactive_flags (old_active ,
844
+ BOND_SLAVE_NOTIFY_NOW );
842
845
843
846
if (new_active ) {
844
847
bool should_notify_peers = false;
845
848
846
- bond_set_slave_active_flags (new_active );
849
+ bond_set_slave_active_flags (new_active ,
850
+ BOND_SLAVE_NOTIFY_NOW );
847
851
848
852
if (bond -> params .fail_over_mac )
849
853
bond_do_fail_over_mac (bond , new_active ,
@@ -1463,14 +1467,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1463
1467
1464
1468
switch (bond -> params .mode ) {
1465
1469
case BOND_MODE_ACTIVEBACKUP :
1466
- bond_set_slave_inactive_flags (new_slave );
1470
+ bond_set_slave_inactive_flags (new_slave ,
1471
+ BOND_SLAVE_NOTIFY_NOW );
1467
1472
break ;
1468
1473
case BOND_MODE_8023AD :
1469
1474
/* in 802.3ad mode, the internal mechanism
1470
1475
* will activate the slaves in the selected
1471
1476
* aggregator
1472
1477
*/
1473
- bond_set_slave_inactive_flags (new_slave );
1478
+ bond_set_slave_inactive_flags (new_slave , BOND_SLAVE_NOTIFY_NOW );
1474
1479
/* if this is the first slave */
1475
1480
if (!prev_slave ) {
1476
1481
SLAVE_AD_INFO (new_slave ).id = 1 ;
@@ -1488,7 +1493,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1488
1493
case BOND_MODE_TLB :
1489
1494
case BOND_MODE_ALB :
1490
1495
bond_set_active_slave (new_slave );
1491
- bond_set_slave_inactive_flags (new_slave );
1496
+ bond_set_slave_inactive_flags (new_slave , BOND_SLAVE_NOTIFY_NOW );
1492
1497
break ;
1493
1498
default :
1494
1499
pr_debug ("This slave is always active in trunk mode\n" );
@@ -2015,7 +2020,8 @@ static void bond_miimon_commit(struct bonding *bond)
2015
2020
2016
2021
if (bond -> params .mode == BOND_MODE_ACTIVEBACKUP ||
2017
2022
bond -> params .mode == BOND_MODE_8023AD )
2018
- bond_set_slave_inactive_flags (slave );
2023
+ bond_set_slave_inactive_flags (slave ,
2024
+ BOND_SLAVE_NOTIFY_NOW );
2019
2025
2020
2026
pr_info ("%s: link status definitely down for interface %s, disabling it\n" ,
2021
2027
bond -> dev -> name , slave -> dev -> name );
@@ -2562,7 +2568,8 @@ static void bond_ab_arp_commit(struct bonding *bond)
2562
2568
slave -> link = BOND_LINK_UP ;
2563
2569
if (bond -> current_arp_slave ) {
2564
2570
bond_set_slave_inactive_flags (
2565
- bond -> current_arp_slave );
2571
+ bond -> current_arp_slave ,
2572
+ BOND_SLAVE_NOTIFY_NOW );
2566
2573
bond -> current_arp_slave = NULL ;
2567
2574
}
2568
2575
@@ -2582,7 +2589,8 @@ static void bond_ab_arp_commit(struct bonding *bond)
2582
2589
slave -> link_failure_count ++ ;
2583
2590
2584
2591
slave -> link = BOND_LINK_DOWN ;
2585
- bond_set_slave_inactive_flags (slave );
2592
+ bond_set_slave_inactive_flags (slave ,
2593
+ BOND_SLAVE_NOTIFY_NOW );
2586
2594
2587
2595
pr_info ("%s: link status definitely down for interface %s, disabling it\n" ,
2588
2596
bond -> dev -> name , slave -> dev -> name );
@@ -2615,17 +2623,17 @@ static void bond_ab_arp_commit(struct bonding *bond)
2615
2623
2616
2624
/*
2617
2625
* Send ARP probes for active-backup mode ARP monitor.
2626
+ *
2627
+ * Called with rcu_read_lock hold.
2618
2628
*/
2619
2629
static bool bond_ab_arp_probe (struct bonding * bond )
2620
2630
{
2621
2631
struct slave * slave , * before = NULL , * new_slave = NULL ,
2622
- * curr_arp_slave , * curr_active_slave ;
2632
+ * curr_arp_slave = rcu_dereference (bond -> current_arp_slave ),
2633
+ * curr_active_slave = rcu_dereference (bond -> curr_active_slave );
2623
2634
struct list_head * iter ;
2624
2635
bool found = false;
2625
-
2626
- rcu_read_lock ();
2627
- curr_arp_slave = rcu_dereference (bond -> current_arp_slave );
2628
- curr_active_slave = rcu_dereference (bond -> curr_active_slave );
2636
+ bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER ;
2629
2637
2630
2638
if (curr_arp_slave && curr_active_slave )
2631
2639
pr_info ("PROBE: c_arp %s && cas %s BAD\n" ,
@@ -2634,32 +2642,23 @@ static bool bond_ab_arp_probe(struct bonding *bond)
2634
2642
2635
2643
if (curr_active_slave ) {
2636
2644
bond_arp_send_all (bond , curr_active_slave );
2637
- rcu_read_unlock ();
2638
- return true;
2645
+ return should_notify_rtnl ;
2639
2646
}
2640
- rcu_read_unlock ();
2641
2647
2642
2648
/* if we don't have a curr_active_slave, search for the next available
2643
2649
* backup slave from the current_arp_slave and make it the candidate
2644
2650
* for becoming the curr_active_slave
2645
2651
*/
2646
2652
2647
- if (!rtnl_trylock ())
2648
- return false;
2649
- /* curr_arp_slave might have gone away */
2650
- curr_arp_slave = ACCESS_ONCE (bond -> current_arp_slave );
2651
-
2652
2653
if (!curr_arp_slave ) {
2653
- curr_arp_slave = bond_first_slave (bond );
2654
- if (!curr_arp_slave ) {
2655
- rtnl_unlock ();
2656
- return true;
2657
- }
2654
+ curr_arp_slave = bond_first_slave_rcu (bond );
2655
+ if (!curr_arp_slave )
2656
+ return should_notify_rtnl ;
2658
2657
}
2659
2658
2660
- bond_set_slave_inactive_flags (curr_arp_slave );
2659
+ bond_set_slave_inactive_flags (curr_arp_slave , BOND_SLAVE_NOTIFY_LATER );
2661
2660
2662
- bond_for_each_slave (bond , slave , iter ) {
2661
+ bond_for_each_slave_rcu (bond , slave , iter ) {
2663
2662
if (!found && !before && IS_UP (slave -> dev ))
2664
2663
before = slave ;
2665
2664
@@ -2677,7 +2676,8 @@ static bool bond_ab_arp_probe(struct bonding *bond)
2677
2676
if (slave -> link_failure_count < UINT_MAX )
2678
2677
slave -> link_failure_count ++ ;
2679
2678
2680
- bond_set_slave_inactive_flags (slave );
2679
+ bond_set_slave_inactive_flags (slave ,
2680
+ BOND_SLAVE_NOTIFY_LATER );
2681
2681
2682
2682
pr_info ("%s: backup interface %s is now down.\n" ,
2683
2683
bond -> dev -> name , slave -> dev -> name );
@@ -2689,26 +2689,31 @@ static bool bond_ab_arp_probe(struct bonding *bond)
2689
2689
if (!new_slave && before )
2690
2690
new_slave = before ;
2691
2691
2692
- if (!new_slave ) {
2693
- rtnl_unlock ();
2694
- return true;
2695
- }
2692
+ if (!new_slave )
2693
+ goto check_state ;
2696
2694
2697
2695
new_slave -> link = BOND_LINK_BACK ;
2698
- bond_set_slave_active_flags (new_slave );
2696
+ bond_set_slave_active_flags (new_slave , BOND_SLAVE_NOTIFY_LATER );
2699
2697
bond_arp_send_all (bond , new_slave );
2700
2698
new_slave -> jiffies = jiffies ;
2701
2699
rcu_assign_pointer (bond -> current_arp_slave , new_slave );
2702
- rtnl_unlock ();
2703
2700
2704
- return true;
2701
+ check_state :
2702
+ bond_for_each_slave_rcu (bond , slave , iter ) {
2703
+ if (slave -> should_notify ) {
2704
+ should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW ;
2705
+ break ;
2706
+ }
2707
+ }
2708
+ return should_notify_rtnl ;
2705
2709
}
2706
2710
2707
2711
static void bond_activebackup_arp_mon (struct work_struct * work )
2708
2712
{
2709
2713
struct bonding * bond = container_of (work , struct bonding ,
2710
2714
arp_work .work );
2711
- bool should_notify_peers = false, should_commit = false;
2715
+ bool should_notify_peers = false;
2716
+ bool should_notify_rtnl = false;
2712
2717
int delta_in_ticks ;
2713
2718
2714
2719
delta_in_ticks = msecs_to_jiffies (bond -> params .arp_interval );
@@ -2717,11 +2722,12 @@ static void bond_activebackup_arp_mon(struct work_struct *work)
2717
2722
goto re_arm ;
2718
2723
2719
2724
rcu_read_lock ();
2725
+
2720
2726
should_notify_peers = bond_should_notify_peers (bond );
2721
- should_commit = bond_ab_arp_inspect (bond );
2722
- rcu_read_unlock ();
2723
2727
2724
- if (should_commit ) {
2728
+ if (bond_ab_arp_inspect (bond )) {
2729
+ rcu_read_unlock ();
2730
+
2725
2731
/* Race avoidance with bond_close flush of workqueue */
2726
2732
if (!rtnl_trylock ()) {
2727
2733
delta_in_ticks = 1 ;
@@ -2730,23 +2736,28 @@ static void bond_activebackup_arp_mon(struct work_struct *work)
2730
2736
}
2731
2737
2732
2738
bond_ab_arp_commit (bond );
2739
+
2733
2740
rtnl_unlock ();
2741
+ rcu_read_lock ();
2734
2742
}
2735
2743
2736
- if (!bond_ab_arp_probe (bond )) {
2737
- /* rtnl locking failed, re-arm */
2738
- delta_in_ticks = 1 ;
2739
- should_notify_peers = false;
2740
- }
2744
+ should_notify_rtnl = bond_ab_arp_probe (bond );
2745
+ rcu_read_unlock ();
2741
2746
2742
2747
re_arm :
2743
2748
if (bond -> params .arp_interval )
2744
2749
queue_delayed_work (bond -> wq , & bond -> arp_work , delta_in_ticks );
2745
2750
2746
- if (should_notify_peers ) {
2751
+ if (should_notify_peers || should_notify_rtnl ) {
2747
2752
if (!rtnl_trylock ())
2748
2753
return ;
2749
- call_netdevice_notifiers (NETDEV_NOTIFY_PEERS , bond -> dev );
2754
+
2755
+ if (should_notify_peers )
2756
+ call_netdevice_notifiers (NETDEV_NOTIFY_PEERS ,
2757
+ bond -> dev );
2758
+ if (should_notify_rtnl )
2759
+ bond_slave_state_notify (bond );
2760
+
2750
2761
rtnl_unlock ();
2751
2762
}
2752
2763
}
@@ -3046,9 +3057,11 @@ static int bond_open(struct net_device *bond_dev)
3046
3057
bond_for_each_slave (bond , slave , iter ) {
3047
3058
if ((bond -> params .mode == BOND_MODE_ACTIVEBACKUP )
3048
3059
&& (slave != bond -> curr_active_slave )) {
3049
- bond_set_slave_inactive_flags (slave );
3060
+ bond_set_slave_inactive_flags (slave ,
3061
+ BOND_SLAVE_NOTIFY_NOW );
3050
3062
} else {
3051
- bond_set_slave_active_flags (slave );
3063
+ bond_set_slave_active_flags (slave ,
3064
+ BOND_SLAVE_NOTIFY_NOW );
3052
3065
}
3053
3066
}
3054
3067
read_unlock (& bond -> curr_slave_lock );
0 commit comments