diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 85 |
1 files changed, 32 insertions, 53 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index cc13bfeac449..d58237b3dd98 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2635,6 +2635,20 @@ out_unlock: | |||
2635 | return RX_HANDLER_ANOTHER; | 2635 | return RX_HANDLER_ANOTHER; |
2636 | } | 2636 | } |
2637 | 2637 | ||
2638 | /* function to verify if we're in the arp_interval timeslice, returns true if | ||
2639 | * (last_act - arp_interval) <= jiffies <= (last_act + mod * arp_interval + | ||
2640 | * arp_interval/2) . the arp_interval/2 is needed for really fast networks. | ||
2641 | */ | ||
2642 | static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act, | ||
2643 | int mod) | ||
2644 | { | ||
2645 | int delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); | ||
2646 | |||
2647 | return time_in_range(jiffies, | ||
2648 | last_act - delta_in_ticks, | ||
2649 | last_act + mod * delta_in_ticks + delta_in_ticks/2); | ||
2650 | } | ||
2651 | |||
2638 | /* | 2652 | /* |
2639 | * this function is called regularly to monitor each slave's link | 2653 | * this function is called regularly to monitor each slave's link |
2640 | * ensuring that traffic is being sent and received when arp monitoring | 2654 | * ensuring that traffic is being sent and received when arp monitoring |
@@ -2648,13 +2662,9 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2648 | arp_work.work); | 2662 | arp_work.work); |
2649 | struct slave *slave, *oldcurrent; | 2663 | struct slave *slave, *oldcurrent; |
2650 | int do_failover = 0; | 2664 | int do_failover = 0; |
2651 | int delta_in_ticks, extra_ticks; | ||
2652 | 2665 | ||
2653 | read_lock(&bond->lock); | 2666 | read_lock(&bond->lock); |
2654 | 2667 | ||
2655 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); | ||
2656 | extra_ticks = delta_in_ticks / 2; | ||
2657 | |||
2658 | if (list_empty(&bond->slave_list)) | 2668 | if (list_empty(&bond->slave_list)) |
2659 | goto re_arm; | 2669 | goto re_arm; |
2660 | 2670 | ||
@@ -2671,12 +2681,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2671 | unsigned long trans_start = dev_trans_start(slave->dev); | 2681 | unsigned long trans_start = dev_trans_start(slave->dev); |
2672 | 2682 | ||
2673 | if (slave->link != BOND_LINK_UP) { | 2683 | if (slave->link != BOND_LINK_UP) { |
2674 | if (time_in_range(jiffies, | 2684 | if (bond_time_in_interval(bond, trans_start, 1) && |
2675 | trans_start - delta_in_ticks, | 2685 | bond_time_in_interval(bond, slave->dev->last_rx, 1)) { |
2676 | trans_start + delta_in_ticks + extra_ticks) && | ||
2677 | time_in_range(jiffies, | ||
2678 | slave->dev->last_rx - delta_in_ticks, | ||
2679 | slave->dev->last_rx + delta_in_ticks + extra_ticks)) { | ||
2680 | 2686 | ||
2681 | slave->link = BOND_LINK_UP; | 2687 | slave->link = BOND_LINK_UP; |
2682 | bond_set_active_slave(slave); | 2688 | bond_set_active_slave(slave); |
@@ -2704,12 +2710,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2704 | * when the source ip is 0, so don't take the link down | 2710 | * when the source ip is 0, so don't take the link down |
2705 | * if we don't know our ip yet | 2711 | * if we don't know our ip yet |
2706 | */ | 2712 | */ |
2707 | if (!time_in_range(jiffies, | 2713 | if (!bond_time_in_interval(bond, trans_start, 2) || |
2708 | trans_start - delta_in_ticks, | 2714 | !bond_time_in_interval(bond, slave->dev->last_rx, 2)) { |
2709 | trans_start + 2 * delta_in_ticks + extra_ticks) || | ||
2710 | !time_in_range(jiffies, | ||
2711 | slave->dev->last_rx - delta_in_ticks, | ||
2712 | slave->dev->last_rx + 2 * delta_in_ticks + extra_ticks)) { | ||
2713 | 2715 | ||
2714 | slave->link = BOND_LINK_DOWN; | 2716 | slave->link = BOND_LINK_DOWN; |
2715 | bond_set_backup_slave(slave); | 2717 | bond_set_backup_slave(slave); |
@@ -2749,7 +2751,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2749 | 2751 | ||
2750 | re_arm: | 2752 | re_arm: |
2751 | if (bond->params.arp_interval) | 2753 | if (bond->params.arp_interval) |
2752 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); | 2754 | queue_delayed_work(bond->wq, &bond->arp_work, |
2755 | msecs_to_jiffies(bond->params.arp_interval)); | ||
2753 | 2756 | ||
2754 | read_unlock(&bond->lock); | 2757 | read_unlock(&bond->lock); |
2755 | } | 2758 | } |
@@ -2762,33 +2765,21 @@ re_arm: | |||
2762 | * | 2765 | * |
2763 | * Called with bond->lock held for read. | 2766 | * Called with bond->lock held for read. |
2764 | */ | 2767 | */ |
2765 | static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | 2768 | static int bond_ab_arp_inspect(struct bonding *bond) |
2766 | { | 2769 | { |
2767 | unsigned long trans_start, last_rx; | 2770 | unsigned long trans_start, last_rx; |
2768 | struct slave *slave; | 2771 | struct slave *slave; |
2769 | int extra_ticks; | ||
2770 | int commit = 0; | 2772 | int commit = 0; |
2771 | 2773 | ||
2772 | /* All the time comparisons below need some extra time. Otherwise, on | ||
2773 | * fast networks the ARP probe/reply may arrive within the same jiffy | ||
2774 | * as it was sent. Then, the next time the ARP monitor is run, one | ||
2775 | * arp_interval will already have passed in the comparisons. | ||
2776 | */ | ||
2777 | extra_ticks = delta_in_ticks / 2; | ||
2778 | |||
2779 | bond_for_each_slave(bond, slave) { | 2774 | bond_for_each_slave(bond, slave) { |
2780 | slave->new_link = BOND_LINK_NOCHANGE; | 2775 | slave->new_link = BOND_LINK_NOCHANGE; |
2781 | last_rx = slave_last_rx(bond, slave); | 2776 | last_rx = slave_last_rx(bond, slave); |
2782 | 2777 | ||
2783 | if (slave->link != BOND_LINK_UP) { | 2778 | if (slave->link != BOND_LINK_UP) { |
2784 | if (time_in_range(jiffies, | 2779 | if (bond_time_in_interval(bond, last_rx, 1)) { |
2785 | last_rx - delta_in_ticks, | ||
2786 | last_rx + delta_in_ticks + extra_ticks)) { | ||
2787 | |||
2788 | slave->new_link = BOND_LINK_UP; | 2780 | slave->new_link = BOND_LINK_UP; |
2789 | commit++; | 2781 | commit++; |
2790 | } | 2782 | } |
2791 | |||
2792 | continue; | 2783 | continue; |
2793 | } | 2784 | } |
2794 | 2785 | ||
@@ -2797,9 +2788,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2797 | * active. This avoids bouncing, as the last receive | 2788 | * active. This avoids bouncing, as the last receive |
2798 | * times need a full ARP monitor cycle to be updated. | 2789 | * times need a full ARP monitor cycle to be updated. |
2799 | */ | 2790 | */ |
2800 | if (time_in_range(jiffies, | 2791 | if (bond_time_in_interval(bond, slave->jiffies, 2)) |
2801 | slave->jiffies - delta_in_ticks, | ||
2802 | slave->jiffies + 2 * delta_in_ticks + extra_ticks)) | ||
2803 | continue; | 2792 | continue; |
2804 | 2793 | ||
2805 | /* | 2794 | /* |
@@ -2817,10 +2806,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2817 | */ | 2806 | */ |
2818 | if (!bond_is_active_slave(slave) && | 2807 | if (!bond_is_active_slave(slave) && |
2819 | !bond->current_arp_slave && | 2808 | !bond->current_arp_slave && |
2820 | !time_in_range(jiffies, | 2809 | !bond_time_in_interval(bond, last_rx, 3)) { |
2821 | last_rx - delta_in_ticks, | ||
2822 | last_rx + 3 * delta_in_ticks + extra_ticks)) { | ||
2823 | |||
2824 | slave->new_link = BOND_LINK_DOWN; | 2810 | slave->new_link = BOND_LINK_DOWN; |
2825 | commit++; | 2811 | commit++; |
2826 | } | 2812 | } |
@@ -2833,13 +2819,8 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2833 | */ | 2819 | */ |
2834 | trans_start = dev_trans_start(slave->dev); | 2820 | trans_start = dev_trans_start(slave->dev); |
2835 | if (bond_is_active_slave(slave) && | 2821 | if (bond_is_active_slave(slave) && |
2836 | (!time_in_range(jiffies, | 2822 | (!bond_time_in_interval(bond, trans_start, 2) || |
2837 | trans_start - delta_in_ticks, | 2823 | !bond_time_in_interval(bond, last_rx, 2))) { |
2838 | trans_start + 2 * delta_in_ticks + extra_ticks) || | ||
2839 | !time_in_range(jiffies, | ||
2840 | last_rx - delta_in_ticks, | ||
2841 | last_rx + 2 * delta_in_ticks + extra_ticks))) { | ||
2842 | |||
2843 | slave->new_link = BOND_LINK_DOWN; | 2824 | slave->new_link = BOND_LINK_DOWN; |
2844 | commit++; | 2825 | commit++; |
2845 | } | 2826 | } |
@@ -2854,7 +2835,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2854 | * | 2835 | * |
2855 | * Called with RTNL and bond->lock for read. | 2836 | * Called with RTNL and bond->lock for read. |
2856 | */ | 2837 | */ |
2857 | static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) | 2838 | static void bond_ab_arp_commit(struct bonding *bond) |
2858 | { | 2839 | { |
2859 | unsigned long trans_start; | 2840 | unsigned long trans_start; |
2860 | struct slave *slave; | 2841 | struct slave *slave; |
@@ -2866,11 +2847,9 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) | |||
2866 | 2847 | ||
2867 | case BOND_LINK_UP: | 2848 | case BOND_LINK_UP: |
2868 | trans_start = dev_trans_start(slave->dev); | 2849 | trans_start = dev_trans_start(slave->dev); |
2869 | if ((!bond->curr_active_slave && | 2850 | if (bond->curr_active_slave != slave || |
2870 | time_in_range(jiffies, | 2851 | (!bond->curr_active_slave && |
2871 | trans_start - delta_in_ticks, | 2852 | bond_time_in_interval(bond, trans_start, 1))) { |
2872 | trans_start + delta_in_ticks + delta_in_ticks / 2)) || | ||
2873 | bond->curr_active_slave != slave) { | ||
2874 | slave->link = BOND_LINK_UP; | 2853 | slave->link = BOND_LINK_UP; |
2875 | if (bond->current_arp_slave) { | 2854 | if (bond->current_arp_slave) { |
2876 | bond_set_slave_inactive_flags( | 2855 | bond_set_slave_inactive_flags( |
@@ -3011,7 +2990,7 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
3011 | 2990 | ||
3012 | should_notify_peers = bond_should_notify_peers(bond); | 2991 | should_notify_peers = bond_should_notify_peers(bond); |
3013 | 2992 | ||
3014 | if (bond_ab_arp_inspect(bond, delta_in_ticks)) { | 2993 | if (bond_ab_arp_inspect(bond)) { |
3015 | read_unlock(&bond->lock); | 2994 | read_unlock(&bond->lock); |
3016 | 2995 | ||
3017 | /* Race avoidance with bond_close flush of workqueue */ | 2996 | /* Race avoidance with bond_close flush of workqueue */ |
@@ -3024,7 +3003,7 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
3024 | 3003 | ||
3025 | read_lock(&bond->lock); | 3004 | read_lock(&bond->lock); |
3026 | 3005 | ||
3027 | bond_ab_arp_commit(bond, delta_in_ticks); | 3006 | bond_ab_arp_commit(bond); |
3028 | 3007 | ||
3029 | read_unlock(&bond->lock); | 3008 | read_unlock(&bond->lock); |
3030 | rtnl_unlock(); | 3009 | rtnl_unlock(); |