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

Commit 9eaeb3e4 authored by Maor Gottlieb's avatar Maor Gottlieb Committed by Greg Kroah-Hartman
Browse files

bonding: Export skip slave logic to function



[ Upstream commit 119d48fd4298594beccf4f2ecd00627826ce2646 ]

As a preparation for following change that add array of
all slaves, extract code that skip slave to function.

Signed-off-by: default avatarMaor Gottlieb <maorg@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Reviewed-by: default avatarJay Vosburgh <jay.vosburgh@canonical.com>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Stable-dep-of: f8a65ab2f3ff ("bonding: fix link recovery in mode 2 when updelay is nonzero")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 26b94635
Loading
Loading
Loading
Loading
+26 −21
Original line number Diff line number Diff line
@@ -4040,6 +4040,29 @@ static void bond_slave_arr_handler(struct work_struct *work)
	bond_slave_arr_work_rearm(bond, 1);
}

static void bond_skip_slave(struct bond_up_slave *slaves,
			    struct slave *skipslave)
{
	int idx;

	/* Rare situation where caller has asked to skip a specific
	 * slave but allocation failed (most likely!). BTW this is
	 * only possible when the call is initiated from
	 * __bond_release_one(). In this situation; overwrite the
	 * skipslave entry in the array with the last entry from the
	 * array to avoid a situation where the xmit path may choose
	 * this to-be-skipped slave to send a packet out.
	 */
	for (idx = 0; slaves && idx < slaves->count; idx++) {
		if (skipslave == slaves->arr[idx]) {
			slaves->arr[idx] =
				slaves->arr[slaves->count - 1];
			slaves->count--;
			break;
		}
	}
}

/* Build the usable slaves array in control path for modes that use xmit-hash
 * to determine the slave interface -
 * (a) BOND_MODE_8023AD
@@ -4109,27 +4132,9 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave)
	if (old_arr)
		kfree_rcu(old_arr, rcu);
out:
	if (ret != 0 && skipslave) {
		int idx;
	if (ret != 0 && skipslave)
		bond_skip_slave(rtnl_dereference(bond->slave_arr), skipslave);

		/* Rare situation where caller has asked to skip a specific
		 * slave but allocation failed (most likely!). BTW this is
		 * only possible when the call is initiated from
		 * __bond_release_one(). In this situation; overwrite the
		 * skipslave entry in the array with the last entry from the
		 * array to avoid a situation where the xmit path may choose
		 * this to-be-skipped slave to send a packet out.
		 */
		old_arr = rtnl_dereference(bond->slave_arr);
		for (idx = 0; old_arr != NULL && idx < old_arr->count; idx++) {
			if (skipslave == old_arr->arr[idx]) {
				old_arr->arr[idx] =
				    old_arr->arr[old_arr->count-1];
				old_arr->count--;
				break;
			}
		}
	}
	return ret;
}