bonding: rework bond_find_best_slave() to use bond_for_each_slave()
authorVeaceslav Falico <vfalico@redhat.com>
Wed, 25 Sep 2013 07:20:18 +0000 (09:20 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 26 Sep 2013 20:02:05 +0000 (16:02 -0400)
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>
drivers/net/bonding/bond_main.c

index 85e99ae..6abbfac 100644 (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 (!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))
+               return bond->primary_slave;
 
-       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;
                }
        }