Commit da210f55 authored by Jiri Bohac's avatar Jiri Bohac Committed by David S. Miller

bonding: add some slack to arp monitoring time limits

Currently, all the time limits in the bonding ARP monitor are in
multiples of arp_interval -- the time interval at which the ARP
monitor is periodically scheduled.

With a fast network round-trip and a little scheduling latency
of the ARP monitor work, a limit of n*delta_in_ticks may
effectively mean (n-1)*delta_in_ticks.

This is fatal in case of n==1  (the link will stay down
forever) and makes the behaviour non-deterministic in all the
other cases.

Add a delta_in_ticks/2 time slack to all the time limits.
Signed-off-by: default avatarJiri Bohac <jbohac@suse.cz>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eb7e0575
...@@ -2811,12 +2811,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work) ...@@ -2811,12 +2811,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
arp_work.work); arp_work.work);
struct slave *slave, *oldcurrent; struct slave *slave, *oldcurrent;
int do_failover = 0; int do_failover = 0;
int delta_in_ticks; int delta_in_ticks, extra_ticks;
int i; int i;
read_lock(&bond->lock); read_lock(&bond->lock);
delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
extra_ticks = delta_in_ticks / 2;
if (bond->slave_cnt == 0) if (bond->slave_cnt == 0)
goto re_arm; goto re_arm;
...@@ -2839,10 +2840,10 @@ void bond_loadbalance_arp_mon(struct work_struct *work) ...@@ -2839,10 +2840,10 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
if (slave->link != BOND_LINK_UP) { if (slave->link != BOND_LINK_UP) {
if (time_in_range(jiffies, if (time_in_range(jiffies,
trans_start - delta_in_ticks, trans_start - delta_in_ticks,
trans_start + delta_in_ticks) && trans_start + delta_in_ticks + extra_ticks) &&
time_in_range(jiffies, time_in_range(jiffies,
slave->dev->last_rx - delta_in_ticks, slave->dev->last_rx - delta_in_ticks,
slave->dev->last_rx + delta_in_ticks)) { slave->dev->last_rx + delta_in_ticks + extra_ticks)) {
slave->link = BOND_LINK_UP; slave->link = BOND_LINK_UP;
bond_set_active_slave(slave); bond_set_active_slave(slave);
...@@ -2872,10 +2873,10 @@ void bond_loadbalance_arp_mon(struct work_struct *work) ...@@ -2872,10 +2873,10 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
*/ */
if (!time_in_range(jiffies, if (!time_in_range(jiffies,
trans_start - delta_in_ticks, trans_start - delta_in_ticks,
trans_start + 2 * delta_in_ticks) || trans_start + 2 * delta_in_ticks + extra_ticks) ||
!time_in_range(jiffies, !time_in_range(jiffies,
slave->dev->last_rx - delta_in_ticks, slave->dev->last_rx - delta_in_ticks,
slave->dev->last_rx + 2 * delta_in_ticks)) { slave->dev->last_rx + 2 * delta_in_ticks + extra_ticks)) {
slave->link = BOND_LINK_DOWN; slave->link = BOND_LINK_DOWN;
bond_set_backup_slave(slave); bond_set_backup_slave(slave);
...@@ -2933,6 +2934,14 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) ...@@ -2933,6 +2934,14 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
struct slave *slave; struct slave *slave;
int i, commit = 0; int i, commit = 0;
unsigned long trans_start; unsigned long trans_start;
int extra_ticks;
/* All the time comparisons below need some extra time. Otherwise, on
* fast networks the ARP probe/reply may arrive within the same jiffy
* as it was sent. Then, the next time the ARP monitor is run, one
* arp_interval will already have passed in the comparisons.
*/
extra_ticks = delta_in_ticks / 2;
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave, i) {
slave->new_link = BOND_LINK_NOCHANGE; slave->new_link = BOND_LINK_NOCHANGE;
...@@ -2940,7 +2949,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) ...@@ -2940,7 +2949,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
if (slave->link != BOND_LINK_UP) { if (slave->link != BOND_LINK_UP) {
if (time_in_range(jiffies, if (time_in_range(jiffies,
slave_last_rx(bond, slave) - delta_in_ticks, slave_last_rx(bond, slave) - delta_in_ticks,
slave_last_rx(bond, slave) + delta_in_ticks)) { slave_last_rx(bond, slave) + delta_in_ticks + extra_ticks)) {
slave->new_link = BOND_LINK_UP; slave->new_link = BOND_LINK_UP;
commit++; commit++;
...@@ -2956,7 +2965,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) ...@@ -2956,7 +2965,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
*/ */
if (time_in_range(jiffies, if (time_in_range(jiffies,
slave->jiffies - delta_in_ticks, slave->jiffies - delta_in_ticks,
slave->jiffies + 2 * delta_in_ticks)) slave->jiffies + 2 * delta_in_ticks + extra_ticks))
continue; continue;
/* /*
...@@ -2976,7 +2985,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) ...@@ -2976,7 +2985,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
!bond->current_arp_slave && !bond->current_arp_slave &&
!time_in_range(jiffies, !time_in_range(jiffies,
slave_last_rx(bond, slave) - delta_in_ticks, slave_last_rx(bond, slave) - delta_in_ticks,
slave_last_rx(bond, slave) + 3 * delta_in_ticks)) { slave_last_rx(bond, slave) + 3 * delta_in_ticks + extra_ticks)) {
slave->new_link = BOND_LINK_DOWN; slave->new_link = BOND_LINK_DOWN;
commit++; commit++;
...@@ -2992,10 +3001,10 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) ...@@ -2992,10 +3001,10 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
if (bond_is_active_slave(slave) && if (bond_is_active_slave(slave) &&
(!time_in_range(jiffies, (!time_in_range(jiffies,
trans_start - delta_in_ticks, trans_start - delta_in_ticks,
trans_start + 2 * delta_in_ticks) || trans_start + 2 * delta_in_ticks + extra_ticks) ||
!time_in_range(jiffies, !time_in_range(jiffies,
slave_last_rx(bond, slave) - delta_in_ticks, slave_last_rx(bond, slave) - delta_in_ticks,
slave_last_rx(bond, slave) + 2 * delta_in_ticks))) { slave_last_rx(bond, slave) + 2 * delta_in_ticks + extra_ticks))) {
slave->new_link = BOND_LINK_DOWN; slave->new_link = BOND_LINK_DOWN;
commit++; commit++;
...@@ -3027,7 +3036,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) ...@@ -3027,7 +3036,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
if ((!bond->curr_active_slave && if ((!bond->curr_active_slave &&
time_in_range(jiffies, time_in_range(jiffies,
trans_start - delta_in_ticks, trans_start - delta_in_ticks,
trans_start + delta_in_ticks)) || trans_start + delta_in_ticks + delta_in_ticks / 2)) ||
bond->curr_active_slave != slave) { bond->curr_active_slave != slave) {
slave->link = BOND_LINK_UP; slave->link = BOND_LINK_UP;
if (bond->current_arp_slave) { if (bond->current_arp_slave) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment