Commit 8448b11e authored by Amir Noam's avatar Amir Noam Committed by Linus Torvalds

[netdrvr bonding] fix monitoring functions

This fix got missed in the bonding patchset applied a while ago.
parent 5e927360
...@@ -2238,8 +2238,9 @@ static int bond_release_all(struct net_device *master) ...@@ -2238,8 +2238,9 @@ static int bond_release_all(struct net_device *master)
static void bond_mii_monitor(struct net_device *master) static void bond_mii_monitor(struct net_device *master)
{ {
bonding_t *bond = (struct bonding *) master->priv; bonding_t *bond = (struct bonding *) master->priv;
slave_t *slave, *bestslave, *oldcurrent; slave_t *slave, *oldcurrent;
int slave_died = 0; int slave_died = 0;
int do_failover = 0;
read_lock(&bond->lock); read_lock(&bond->lock);
...@@ -2249,7 +2250,6 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2249,7 +2250,6 @@ static void bond_mii_monitor(struct net_device *master)
* program could monitor the link itself if needed. * program could monitor the link itself if needed.
*/ */
bestslave = NULL;
slave = (slave_t *)bond; slave = (slave_t *)bond;
read_lock(&bond->ptrlock); read_lock(&bond->ptrlock);
...@@ -2257,8 +2257,6 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2257,8 +2257,6 @@ static void bond_mii_monitor(struct net_device *master)
read_unlock(&bond->ptrlock); read_unlock(&bond->ptrlock);
while ((slave = slave->prev) != (slave_t *)bond) { while ((slave = slave->prev) != (slave_t *)bond) {
/* use updelay+1 to match an UP slave even when updelay is 0 */
int mindelay = updelay + 1;
struct net_device *dev = slave->dev; struct net_device *dev = slave->dev;
int link_state; int link_state;
u16 old_speed = slave->speed; u16 old_speed = slave->speed;
...@@ -2269,14 +2267,7 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2269,14 +2267,7 @@ static void bond_mii_monitor(struct net_device *master)
switch (slave->link) { switch (slave->link) {
case BOND_LINK_UP: /* the link was up */ case BOND_LINK_UP: /* the link was up */
if (link_state == BMSR_LSTATUS) { if (link_state == BMSR_LSTATUS) {
/* link stays up, tell that this one /* link stays up, nothing more to do */
is immediately available */
if (IS_UP(dev) && (mindelay > -2)) {
/* -2 is the best case :
this slave was already up */
mindelay = -2;
bestslave = slave;
}
break; break;
} }
else { /* link going down */ else { /* link going down */
...@@ -2316,6 +2307,7 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2316,6 +2307,7 @@ static void bond_mii_monitor(struct net_device *master)
(bond_mode == BOND_MODE_8023AD)) { (bond_mode == BOND_MODE_8023AD)) {
bond_set_slave_inactive_flags(slave); bond_set_slave_inactive_flags(slave);
} }
printk(KERN_INFO printk(KERN_INFO
"%s: link status definitely down " "%s: link status definitely down "
"for interface %s, disabling it", "for interface %s, disabling it",
...@@ -2332,12 +2324,10 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2332,12 +2324,10 @@ static void bond_mii_monitor(struct net_device *master)
bond_alb_handle_link_change(bond, slave, BOND_LINK_DOWN); bond_alb_handle_link_change(bond, slave, BOND_LINK_DOWN);
} }
write_lock(&bond->ptrlock); if (slave == oldcurrent) {
if (slave == bond->current_slave) { do_failover = 1;
/* find a new interface and be verbose */
reselect_active_interface(bond);
} }
write_unlock(&bond->ptrlock);
slave_died = 1; slave_died = 1;
} else { } else {
slave->delay--; slave->delay--;
...@@ -2352,13 +2342,6 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2352,13 +2342,6 @@ static void bond_mii_monitor(struct net_device *master)
master->name, master->name,
(downdelay - slave->delay) * miimon, (downdelay - slave->delay) * miimon,
dev->name); dev->name);
if (IS_UP(dev) && (mindelay > -1)) {
/* -1 is a good case : this slave went
down only for a short time */
mindelay = -1;
bestslave = slave;
}
} }
break; break;
case BOND_LINK_DOWN: /* the link was down */ case BOND_LINK_DOWN: /* the link was down */
...@@ -2428,26 +2411,12 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2428,26 +2411,12 @@ static void bond_mii_monitor(struct net_device *master)
bond_alb_handle_link_change(bond, slave, BOND_LINK_UP); bond_alb_handle_link_change(bond, slave, BOND_LINK_UP);
} }
write_lock(&bond->ptrlock); if ((oldcurrent == NULL) ||
if ( (bond->primary_slave != NULL) (slave == bond->primary_slave)) {
&& (slave == bond->primary_slave) ) do_failover = 1;
reselect_active_interface(bond); }
write_unlock(&bond->ptrlock); } else {
}
else
slave->delay--; slave->delay--;
/* we'll also look for the mostly eligible slave */
if (bond->primary_slave == NULL) {
if (IS_UP(dev) && (slave->delay < mindelay)) {
mindelay = slave->delay;
bestslave = slave;
}
} else if ( (IS_UP(bond->primary_slave->dev)) ||
( (!IS_UP(bond->primary_slave->dev)) &&
(IS_UP(dev) && (slave->delay < mindelay)) ) ) {
mindelay = slave->delay;
bestslave = slave;
} }
} }
break; break;
...@@ -2466,26 +2435,17 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2466,26 +2435,17 @@ static void bond_mii_monitor(struct net_device *master)
} /* end of while */ } /* end of while */
/* if (do_failover) {
* if there's no active interface and we discovered that one write_lock(&bond->ptrlock);
* of the slaves could be activated earlier, so we do it.
*/
read_lock(&bond->ptrlock);
oldcurrent = bond->current_slave;
read_unlock(&bond->ptrlock);
/* no active interface at the moment or need to bring up the primary */ reselect_active_interface(bond);
if (oldcurrent == NULL) { /* no active interface at the moment */ if (oldcurrent && !bond->current_slave) {
if (bestslave != NULL) { /* last chance to find one ? */
write_lock(&bond->ptrlock);
change_active_interface(bond, bestslave);
write_unlock(&bond->ptrlock);
} else if (slave_died) {
/* print this message only once a slave has just died */
printk(KERN_INFO printk(KERN_INFO
"%s: now running without any active interface !\n", "%s: now running without any active interface !\n",
master->name); master->name);
} }
write_unlock(&bond->ptrlock);
} }
read_unlock(&bond->lock); read_unlock(&bond->lock);
...@@ -2503,9 +2463,10 @@ static void bond_mii_monitor(struct net_device *master) ...@@ -2503,9 +2463,10 @@ static void bond_mii_monitor(struct net_device *master)
static void loadbalance_arp_monitor(struct net_device *master) static void loadbalance_arp_monitor(struct net_device *master)
{ {
bonding_t *bond; bonding_t *bond;
slave_t *slave; slave_t *slave, *oldcurrent;
int the_delta_in_ticks = arp_interval * HZ / 1000; int the_delta_in_ticks = arp_interval * HZ / 1000;
int next_timer = jiffies + (arp_interval * HZ / 1000); int next_timer = jiffies + (arp_interval * HZ / 1000);
int do_failover = 0;
bond = (struct bonding *) master->priv; bond = (struct bonding *) master->priv;
if (master->priv == NULL) { if (master->priv == NULL) {
...@@ -2529,6 +2490,10 @@ static void loadbalance_arp_monitor(struct net_device *master) ...@@ -2529,6 +2490,10 @@ static void loadbalance_arp_monitor(struct net_device *master)
read_lock(&bond->lock); read_lock(&bond->lock);
read_lock(&bond->ptrlock);
oldcurrent = bond->current_slave;
read_unlock(&bond->ptrlock);
/* see if any of the previous devices are up now (i.e. they have /* see if any of the previous devices are up now (i.e. they have
* xmt and rcv traffic). the current_slave does not come into * xmt and rcv traffic). the current_slave does not come into
* the picture unless it is null. also, slave->jiffies is not needed * the picture unless it is null. also, slave->jiffies is not needed
...@@ -2555,21 +2520,19 @@ static void loadbalance_arp_monitor(struct net_device *master) ...@@ -2555,21 +2520,19 @@ static void loadbalance_arp_monitor(struct net_device *master)
* current_slave being null after enslaving * current_slave being null after enslaving
* is closed. * is closed.
*/ */
write_lock(&bond->ptrlock); if (oldcurrent == NULL) {
if (bond->current_slave == NULL) {
printk(KERN_INFO printk(KERN_INFO
"%s: link status definitely up " "%s: link status definitely up "
"for interface %s, ", "for interface %s, ",
master->name, master->name,
slave->dev->name); slave->dev->name);
reselect_active_interface(bond); do_failover = 1;
} else { } else {
printk(KERN_INFO printk(KERN_INFO
"%s: interface %s is now up\n", "%s: interface %s is now up\n",
master->name, master->name,
slave->dev->name); slave->dev->name);
} }
write_unlock(&bond->ptrlock);
} }
} else { } else {
/* slave->link == BOND_LINK_UP */ /* slave->link == BOND_LINK_UP */
...@@ -2592,11 +2555,9 @@ static void loadbalance_arp_monitor(struct net_device *master) ...@@ -2592,11 +2555,9 @@ static void loadbalance_arp_monitor(struct net_device *master)
master->name, master->name,
slave->dev->name); slave->dev->name);
write_lock(&bond->ptrlock); if (slave == oldcurrent) {
if (slave == bond->current_slave) { do_failover = 1;
reselect_active_interface(bond);
} }
write_unlock(&bond->ptrlock);
} }
} }
...@@ -2612,6 +2573,19 @@ static void loadbalance_arp_monitor(struct net_device *master) ...@@ -2612,6 +2573,19 @@ static void loadbalance_arp_monitor(struct net_device *master)
} }
} }
if (do_failover) {
write_lock(&bond->ptrlock);
reselect_active_interface(bond);
if (oldcurrent && !bond->current_slave) {
printk(KERN_INFO
"%s: now running without any active interface !\n",
master->name);
}
write_unlock(&bond->ptrlock);
}
read_unlock(&bond->lock); read_unlock(&bond->lock);
rtnl_exunlock(); rtnl_exunlock();
rtnl_shunlock(); rtnl_shunlock();
......
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