diff options
author | Veaceslav Falico <vfalico@redhat.com> | 2013-09-25 03:20:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-26 16:02:06 -0400 |
commit | 4087df87b868cef0dd19a9409b40fb9415503552 (patch) | |
tree | 48c9f33c44dd607dcabba0f934cc67a454181d22 /drivers/net/bonding/bond_main.c | |
parent | 77140d2951432487d012dbcdcf124168eafc49ca (diff) |
bonding: rework bond_ab_arp_probe() to use bond_for_each_slave()
Currently it uses the hard-to-rcuify bond_for_each_slave_from(), and also
it doesn't check every slave for disrepencies between the actual
IS_UP(slave) and the slave->link == BOND_LINK_UP, but only till we find the
next suitable slave.
Fix this by using bond_for_each_slave() and storing the first good slave in
*before till we find the current_arp_slave, after that we store the first good
slave in new_slave. If new_slave is empty - use the slave stored in before,
and if it's also empty - then we didn't find any suitable slave.
Also, in the meanwhile, check for each slave status.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6abbfaca0b93..3c96b1b10ba4 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2761,8 +2761,9 @@ do_failover: | |||
2761 | */ | 2761 | */ |
2762 | static void bond_ab_arp_probe(struct bonding *bond) | 2762 | static void bond_ab_arp_probe(struct bonding *bond) |
2763 | { | 2763 | { |
2764 | struct slave *slave, *next_slave; | 2764 | struct slave *slave, *before = NULL, *new_slave = NULL; |
2765 | int i; | 2765 | struct list_head *iter; |
2766 | bool found = false; | ||
2766 | 2767 | ||
2767 | read_lock(&bond->curr_slave_lock); | 2768 | read_lock(&bond->curr_slave_lock); |
2768 | 2769 | ||
@@ -2792,18 +2793,12 @@ static void bond_ab_arp_probe(struct bonding *bond) | |||
2792 | 2793 | ||
2793 | bond_set_slave_inactive_flags(bond->current_arp_slave); | 2794 | bond_set_slave_inactive_flags(bond->current_arp_slave); |
2794 | 2795 | ||
2795 | /* search for next candidate */ | 2796 | bond_for_each_slave(bond, slave, iter) { |
2796 | next_slave = bond_next_slave(bond, bond->current_arp_slave); | 2797 | if (!found && !before && IS_UP(slave->dev)) |
2797 | bond_for_each_slave_from(bond, slave, i, next_slave) { | 2798 | before = slave; |
2798 | if (IS_UP(slave->dev)) { | ||
2799 | slave->link = BOND_LINK_BACK; | ||
2800 | bond_set_slave_active_flags(slave); | ||
2801 | bond_arp_send_all(bond, slave); | ||
2802 | slave->jiffies = jiffies; | ||
2803 | bond->current_arp_slave = slave; | ||
2804 | break; | ||
2805 | } | ||
2806 | 2799 | ||
2800 | if (found && !new_slave && IS_UP(slave->dev)) | ||
2801 | new_slave = slave; | ||
2807 | /* if the link state is up at this point, we | 2802 | /* if the link state is up at this point, we |
2808 | * mark it down - this can happen if we have | 2803 | * mark it down - this can happen if we have |
2809 | * simultaneous link failures and | 2804 | * simultaneous link failures and |
@@ -2811,7 +2806,7 @@ static void bond_ab_arp_probe(struct bonding *bond) | |||
2811 | * one the current slave so it is still marked | 2806 | * one the current slave so it is still marked |
2812 | * up when it is actually down | 2807 | * up when it is actually down |
2813 | */ | 2808 | */ |
2814 | if (slave->link == BOND_LINK_UP) { | 2809 | if (!IS_UP(slave->dev) && slave->link == BOND_LINK_UP) { |
2815 | slave->link = BOND_LINK_DOWN; | 2810 | slave->link = BOND_LINK_DOWN; |
2816 | if (slave->link_failure_count < UINT_MAX) | 2811 | if (slave->link_failure_count < UINT_MAX) |
2817 | slave->link_failure_count++; | 2812 | slave->link_failure_count++; |
@@ -2821,7 +2816,22 @@ static void bond_ab_arp_probe(struct bonding *bond) | |||
2821 | pr_info("%s: backup interface %s is now down.\n", | 2816 | pr_info("%s: backup interface %s is now down.\n", |
2822 | bond->dev->name, slave->dev->name); | 2817 | bond->dev->name, slave->dev->name); |
2823 | } | 2818 | } |
2819 | if (slave == bond->current_arp_slave) | ||
2820 | found = true; | ||
2824 | } | 2821 | } |
2822 | |||
2823 | if (!new_slave && before) | ||
2824 | new_slave = before; | ||
2825 | |||
2826 | if (!new_slave) | ||
2827 | return; | ||
2828 | |||
2829 | new_slave->link = BOND_LINK_BACK; | ||
2830 | bond_set_slave_active_flags(new_slave); | ||
2831 | bond_arp_send_all(bond, new_slave); | ||
2832 | new_slave->jiffies = jiffies; | ||
2833 | bond->current_arp_slave = new_slave; | ||
2834 | |||
2825 | } | 2835 | } |
2826 | 2836 | ||
2827 | void bond_activebackup_arp_mon(struct work_struct *work) | 2837 | void bond_activebackup_arp_mon(struct work_struct *work) |