Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+20 −11
Original line number Original line Diff line number Diff line
@@ -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)
		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)
			 */
			 */
			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)
	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)
		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)
		 */
		 */
		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)
		    !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)
		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)
			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) {