aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bonding/bond_3ad.c16
-rw-r--r--drivers/net/bonding/bond_main.c115
-rw-r--r--drivers/net/bonding/bonding.h47
3 files changed, 120 insertions, 58 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 6d20fbde8d43..dcde56057fe1 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -181,7 +181,7 @@ static inline int __agg_has_partner(struct aggregator *agg)
181 */ 181 */
182static inline void __disable_port(struct port *port) 182static inline void __disable_port(struct port *port)
183{ 183{
184 bond_set_slave_inactive_flags(port->slave); 184 bond_set_slave_inactive_flags(port->slave, BOND_SLAVE_NOTIFY_LATER);
185} 185}
186 186
187/** 187/**
@@ -193,7 +193,7 @@ static inline void __enable_port(struct port *port)
193 struct slave *slave = port->slave; 193 struct slave *slave = port->slave;
194 194
195 if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) 195 if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev))
196 bond_set_slave_active_flags(slave); 196 bond_set_slave_active_flags(slave, BOND_SLAVE_NOTIFY_LATER);
197} 197}
198 198
199/** 199/**
@@ -2062,6 +2062,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
2062 struct list_head *iter; 2062 struct list_head *iter;
2063 struct slave *slave; 2063 struct slave *slave;
2064 struct port *port; 2064 struct port *port;
2065 bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER;
2065 2066
2066 read_lock(&bond->lock); 2067 read_lock(&bond->lock);
2067 rcu_read_lock(); 2068 rcu_read_lock();
@@ -2119,8 +2120,19 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
2119 } 2120 }
2120 2121
2121re_arm: 2122re_arm:
2123 bond_for_each_slave_rcu(bond, slave, iter) {
2124 if (slave->should_notify) {
2125 should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW;
2126 break;
2127 }
2128 }
2122 rcu_read_unlock(); 2129 rcu_read_unlock();
2123 read_unlock(&bond->lock); 2130 read_unlock(&bond->lock);
2131
2132 if (should_notify_rtnl && rtnl_trylock()) {
2133 bond_slave_state_notify(bond);
2134 rtnl_unlock();
2135 }
2124 queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); 2136 queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks);
2125} 2137}
2126 2138
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1c6104d3501d..82b70ff1fd28 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -829,21 +829,25 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
829 if (bond_is_lb(bond)) { 829 if (bond_is_lb(bond)) {
830 bond_alb_handle_active_change(bond, new_active); 830 bond_alb_handle_active_change(bond, new_active);
831 if (old_active) 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 if (new_active) 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 } else { 837 } else {
836 rcu_assign_pointer(bond->curr_active_slave, new_active); 838 rcu_assign_pointer(bond->curr_active_slave, new_active);
837 } 839 }
838 840
839 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { 841 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
840 if (old_active) 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 if (new_active) { 846 if (new_active) {
844 bool should_notify_peers = false; 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 if (bond->params.fail_over_mac) 852 if (bond->params.fail_over_mac)
849 bond_do_fail_over_mac(bond, new_active, 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 switch (bond->params.mode) { 1468 switch (bond->params.mode) {
1465 case BOND_MODE_ACTIVEBACKUP: 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 break; 1472 break;
1468 case BOND_MODE_8023AD: 1473 case BOND_MODE_8023AD:
1469 /* in 802.3ad mode, the internal mechanism 1474 /* in 802.3ad mode, the internal mechanism
1470 * will activate the slaves in the selected 1475 * will activate the slaves in the selected
1471 * aggregator 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 /* if this is the first slave */ 1479 /* if this is the first slave */
1475 if (!prev_slave) { 1480 if (!prev_slave) {
1476 SLAVE_AD_INFO(new_slave).id = 1; 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 case BOND_MODE_TLB: 1493 case BOND_MODE_TLB:
1489 case BOND_MODE_ALB: 1494 case BOND_MODE_ALB:
1490 bond_set_active_slave(new_slave); 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 break; 1497 break;
1493 default: 1498 default:
1494 pr_debug("This slave is always active in trunk mode\n"); 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 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || 2021 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP ||
2017 bond->params.mode == BOND_MODE_8023AD) 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 pr_info("%s: link status definitely down for interface %s, disabling it\n", 2026 pr_info("%s: link status definitely down for interface %s, disabling it\n",
2021 bond->dev->name, slave->dev->name); 2027 bond->dev->name, slave->dev->name);
@@ -2562,7 +2568,8 @@ static void bond_ab_arp_commit(struct bonding *bond)
2562 slave->link = BOND_LINK_UP; 2568 slave->link = BOND_LINK_UP;
2563 if (bond->current_arp_slave) { 2569 if (bond->current_arp_slave) {
2564 bond_set_slave_inactive_flags( 2570 bond_set_slave_inactive_flags(
2565 bond->current_arp_slave); 2571 bond->current_arp_slave,
2572 BOND_SLAVE_NOTIFY_NOW);
2566 bond->current_arp_slave = NULL; 2573 bond->current_arp_slave = NULL;
2567 } 2574 }
2568 2575
@@ -2582,7 +2589,8 @@ static void bond_ab_arp_commit(struct bonding *bond)
2582 slave->link_failure_count++; 2589 slave->link_failure_count++;
2583 2590
2584 slave->link = BOND_LINK_DOWN; 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 pr_info("%s: link status definitely down for interface %s, disabling it\n", 2595 pr_info("%s: link status definitely down for interface %s, disabling it\n",
2588 bond->dev->name, slave->dev->name); 2596 bond->dev->name, slave->dev->name);
@@ -2615,17 +2623,17 @@ do_failover:
2615 2623
2616/* 2624/*
2617 * Send ARP probes for active-backup mode ARP monitor. 2625 * Send ARP probes for active-backup mode ARP monitor.
2626 *
2627 * Called with rcu_read_lock hold.
2618 */ 2628 */
2619static bool bond_ab_arp_probe(struct bonding *bond) 2629static bool bond_ab_arp_probe(struct bonding *bond)
2620{ 2630{
2621 struct slave *slave, *before = NULL, *new_slave = NULL, 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 struct list_head *iter; 2634 struct list_head *iter;
2624 bool found = false; 2635 bool found = false;
2625 2636 bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER;
2626 rcu_read_lock();
2627 curr_arp_slave = rcu_dereference(bond->current_arp_slave);
2628 curr_active_slave = rcu_dereference(bond->curr_active_slave);
2629 2637
2630 if (curr_arp_slave && curr_active_slave) 2638 if (curr_arp_slave && curr_active_slave)
2631 pr_info("PROBE: c_arp %s && cas %s BAD\n", 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 if (curr_active_slave) { 2643 if (curr_active_slave) {
2636 bond_arp_send_all(bond, curr_active_slave); 2644 bond_arp_send_all(bond, curr_active_slave);
2637 rcu_read_unlock(); 2645 return should_notify_rtnl;
2638 return true;
2639 } 2646 }
2640 rcu_read_unlock();
2641 2647
2642 /* if we don't have a curr_active_slave, search for the next available 2648 /* if we don't have a curr_active_slave, search for the next available
2643 * backup slave from the current_arp_slave and make it the candidate 2649 * backup slave from the current_arp_slave and make it the candidate
2644 * for becoming the curr_active_slave 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 if (!curr_arp_slave) { 2653 if (!curr_arp_slave) {
2653 curr_arp_slave = bond_first_slave(bond); 2654 curr_arp_slave = bond_first_slave_rcu(bond);
2654 if (!curr_arp_slave) { 2655 if (!curr_arp_slave)
2655 rtnl_unlock(); 2656 return should_notify_rtnl;
2656 return true;
2657 }
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 if (!found && !before && IS_UP(slave->dev)) 2662 if (!found && !before && IS_UP(slave->dev))
2664 before = slave; 2663 before = slave;
2665 2664
@@ -2677,7 +2676,8 @@ static bool bond_ab_arp_probe(struct bonding *bond)
2677 if (slave->link_failure_count < UINT_MAX) 2676 if (slave->link_failure_count < UINT_MAX)
2678 slave->link_failure_count++; 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 pr_info("%s: backup interface %s is now down.\n", 2682 pr_info("%s: backup interface %s is now down.\n",
2683 bond->dev->name, slave->dev->name); 2683 bond->dev->name, slave->dev->name);
@@ -2689,26 +2689,31 @@ static bool bond_ab_arp_probe(struct bonding *bond)
2689 if (!new_slave && before) 2689 if (!new_slave && before)
2690 new_slave = before; 2690 new_slave = before;
2691 2691
2692 if (!new_slave) { 2692 if (!new_slave)
2693 rtnl_unlock(); 2693 goto check_state;
2694 return true;
2695 }
2696 2694
2697 new_slave->link = BOND_LINK_BACK; 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 bond_arp_send_all(bond, new_slave); 2697 bond_arp_send_all(bond, new_slave);
2700 new_slave->jiffies = jiffies; 2698 new_slave->jiffies = jiffies;
2701 rcu_assign_pointer(bond->current_arp_slave, new_slave); 2699 rcu_assign_pointer(bond->current_arp_slave, new_slave);
2702 rtnl_unlock();
2703 2700
2704 return true; 2701check_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
2707static void bond_activebackup_arp_mon(struct work_struct *work) 2711static void bond_activebackup_arp_mon(struct work_struct *work)
2708{ 2712{
2709 struct bonding *bond = container_of(work, struct bonding, 2713 struct bonding *bond = container_of(work, struct bonding,
2710 arp_work.work); 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 int delta_in_ticks; 2717 int delta_in_ticks;
2713 2718
2714 delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); 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 goto re_arm; 2722 goto re_arm;
2718 2723
2719 rcu_read_lock(); 2724 rcu_read_lock();
2725
2720 should_notify_peers = bond_should_notify_peers(bond); 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 /* Race avoidance with bond_close flush of workqueue */ 2731 /* Race avoidance with bond_close flush of workqueue */
2726 if (!rtnl_trylock()) { 2732 if (!rtnl_trylock()) {
2727 delta_in_ticks = 1; 2733 delta_in_ticks = 1;
@@ -2730,23 +2736,28 @@ static void bond_activebackup_arp_mon(struct work_struct *work)
2730 } 2736 }
2731 2737
2732 bond_ab_arp_commit(bond); 2738 bond_ab_arp_commit(bond);
2739
2733 rtnl_unlock(); 2740 rtnl_unlock();
2741 rcu_read_lock();
2734 } 2742 }
2735 2743
2736 if (!bond_ab_arp_probe(bond)) { 2744 should_notify_rtnl = bond_ab_arp_probe(bond);
2737 /* rtnl locking failed, re-arm */ 2745 rcu_read_unlock();
2738 delta_in_ticks = 1;
2739 should_notify_peers = false;
2740 }
2741 2746
2742re_arm: 2747re_arm:
2743 if (bond->params.arp_interval) 2748 if (bond->params.arp_interval)
2744 queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); 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 if (!rtnl_trylock()) 2752 if (!rtnl_trylock())
2748 return; 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 rtnl_unlock(); 2761 rtnl_unlock();
2751 } 2762 }
2752} 2763}
@@ -3046,9 +3057,11 @@ static int bond_open(struct net_device *bond_dev)
3046 bond_for_each_slave(bond, slave, iter) { 3057 bond_for_each_slave(bond, slave, iter) {
3047 if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) 3058 if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP)
3048 && (slave != bond->curr_active_slave)) { 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 } else { 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 read_unlock(&bond->curr_slave_lock); 3067 read_unlock(&bond->curr_slave_lock);
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 86ccfb9f71cc..2b0fdec695f7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -195,7 +195,8 @@ struct slave {
195 s8 new_link; 195 s8 new_link;
196 u8 backup:1, /* indicates backup slave. Value corresponds with 196 u8 backup:1, /* indicates backup slave. Value corresponds with
197 BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ 197 BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
198 inactive:1; /* indicates inactive slave */ 198 inactive:1, /* indicates inactive slave */
199 should_notify:1; /* indicateds whether the state changed */
199 u8 duplex; 200 u8 duplex;
200 u32 original_mtu; 201 u32 original_mtu;
201 u32 link_failure_count; 202 u32 link_failure_count;
@@ -303,6 +304,24 @@ static inline void bond_set_backup_slave(struct slave *slave)
303 } 304 }
304} 305}
305 306
307static inline void bond_set_slave_state(struct slave *slave,
308 int slave_state, bool notify)
309{
310 if (slave->backup == slave_state)
311 return;
312
313 slave->backup = slave_state;
314 if (notify) {
315 rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL);
316 slave->should_notify = 0;
317 } else {
318 if (slave->should_notify)
319 slave->should_notify = 0;
320 else
321 slave->should_notify = 1;
322 }
323}
324
306static inline void bond_slave_state_change(struct bonding *bond) 325static inline void bond_slave_state_change(struct bonding *bond)
307{ 326{
308 struct list_head *iter; 327 struct list_head *iter;
@@ -316,6 +335,19 @@ static inline void bond_slave_state_change(struct bonding *bond)
316 } 335 }
317} 336}
318 337
338static inline void bond_slave_state_notify(struct bonding *bond)
339{
340 struct list_head *iter;
341 struct slave *tmp;
342
343 bond_for_each_slave(bond, tmp, iter) {
344 if (tmp->should_notify) {
345 rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_KERNEL);
346 tmp->should_notify = 0;
347 }
348 }
349}
350
319static inline int bond_slave_state(struct slave *slave) 351static inline int bond_slave_state(struct slave *slave)
320{ 352{
321 return slave->backup; 353 return slave->backup;
@@ -343,6 +375,9 @@ static inline bool bond_is_active_slave(struct slave *slave)
343#define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ 375#define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \
344 BOND_ARP_VALIDATE_BACKUP) 376 BOND_ARP_VALIDATE_BACKUP)
345 377
378#define BOND_SLAVE_NOTIFY_NOW true
379#define BOND_SLAVE_NOTIFY_LATER false
380
346static inline int slave_do_arp_validate(struct bonding *bond, 381static inline int slave_do_arp_validate(struct bonding *bond,
347 struct slave *slave) 382 struct slave *slave)
348{ 383{
@@ -394,17 +429,19 @@ static inline void bond_netpoll_send_skb(const struct slave *slave,
394} 429}
395#endif 430#endif
396 431
397static inline void bond_set_slave_inactive_flags(struct slave *slave) 432static inline void bond_set_slave_inactive_flags(struct slave *slave,
433 bool notify)
398{ 434{
399 if (!bond_is_lb(slave->bond)) 435 if (!bond_is_lb(slave->bond))
400 bond_set_backup_slave(slave); 436 bond_set_slave_state(slave, BOND_STATE_BACKUP, notify);
401 if (!slave->bond->params.all_slaves_active) 437 if (!slave->bond->params.all_slaves_active)
402 slave->inactive = 1; 438 slave->inactive = 1;
403} 439}
404 440
405static inline void bond_set_slave_active_flags(struct slave *slave) 441static inline void bond_set_slave_active_flags(struct slave *slave,
442 bool notify)
406{ 443{
407 bond_set_active_slave(slave); 444 bond_set_slave_state(slave, BOND_STATE_ACTIVE, notify);
408 slave->inactive = 0; 445 slave->inactive = 0;
409} 446}
410 447