bonding: rework bond_find_best_slave() to use bond_for_each_slave()

bond_find_best_slave() does not have to be balanced - i.e. return the slave
that is *after* some other slave, but rather return the best slave that
suits, except of bond->primary_slave - in which case we just return it if
it's suitable.

After that we just look through all the slaves and return either first up
slave or the slave whose link came back earliest.

We also don't care about curr_active_slave lock cause we use it in
bond_should_change_active() only and there we take it right away - i.e. it
won't go away.

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>
This commit is contained in:
Veaceslav Falico 2013-09-25 09:20:18 +02:00 committed by David S. Miller
parent 6475ae4cee
commit 77140d2951

View File

@ -785,43 +785,24 @@ static bool bond_should_change_active(struct bonding *bond)
/**
* find_best_interface - select the best available slave to be the active one
* @bond: our bonding struct
*
* Warning: Caller must hold curr_slave_lock for writing.
*/
static struct slave *bond_find_best_slave(struct bonding *bond)
{
struct slave *new_active, *old_active;
struct slave *bestslave = NULL;
struct slave *slave, *bestslave = NULL;
struct list_head *iter;
int mintime = bond->params.updelay;
int i;
new_active = bond->curr_active_slave;
if (bond->primary_slave && bond->primary_slave->link == BOND_LINK_UP &&
bond_should_change_active(bond))
return bond->primary_slave;
if (!new_active) { /* there were no active slaves left */
new_active = bond_first_slave(bond);
if (!new_active)
return NULL; /* still no slave, return NULL */
}
if ((bond->primary_slave) &&
bond->primary_slave->link == BOND_LINK_UP &&
bond_should_change_active(bond)) {
new_active = bond->primary_slave;
}
/* remember where to stop iterating over the slaves */
old_active = new_active;
bond_for_each_slave_from(bond, new_active, i, old_active) {
if (new_active->link == BOND_LINK_UP) {
return new_active;
} else if (new_active->link == BOND_LINK_BACK &&
IS_UP(new_active->dev)) {
/* link up, but waiting for stabilization */
if (new_active->delay < mintime) {
mintime = new_active->delay;
bestslave = new_active;
}
bond_for_each_slave(bond, slave, iter) {
if (slave->link == BOND_LINK_UP)
return slave;
if (slave->link == BOND_LINK_BACK && IS_UP(slave->dev) &&
slave->delay < mintime) {
mintime = slave->delay;
bestslave = slave;
}
}