bonding: Convert miimon to new locking

Convert mii (link state) monitor to acquire correct locks for
failover events. In particular, failovers generally require RTNL at a low
level (when manipulating device MAC addresses, for example) and no other
locks. The high level monitor is responsible for acquiring a known set
of locks, RTNL, the bond->lock for read and the slave_lock for write, and
the low level failover processing can then release appropriate locks as
needed. This patch provides the high level portion.

As it is undesirable to acquire RTNL for every monitor pass (which
may occur as often as every 10 ms), the miimon has been converted to
do conditional locking. A first pass inspects all slaves to determine
if any action is required, and if so, a second pass (after acquring RTNL)
is done to perform any actions (doing a complete rescan, as the situation
may have changed when all locks were released).

Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by Jay Vosburgh and committed by Jeff Garzik 0b0eef66 cf5f9044

+51 -19
+51 -19
drivers/net/bonding/bond_main.c
··· 2088 2089 /*-------------------------------- Monitoring -------------------------------*/ 2090 2091 - /* this function is called regularly to monitor each slave's link. */ 2092 - void bond_mii_monitor(struct work_struct *work) 2093 { 2094 - struct bonding *bond = container_of(work, struct bonding, 2095 - mii_work.work); 2096 struct slave *slave, *oldcurrent; 2097 int do_failover = 0; 2098 - int delta_in_ticks; 2099 int i; 2100 2101 - read_lock(&bond->lock); 2102 - 2103 - delta_in_ticks = (bond->params.miimon * HZ) / 1000; 2104 - 2105 - if (bond->kill_timers) { 2106 goto out; 2107 - } 2108 - 2109 - if (bond->slave_cnt == 0) { 2110 - goto re_arm; 2111 - } 2112 2113 /* we will try to read the link status of each of our slaves, and 2114 * set their IFF_RUNNING flag appropriately. For each slave not ··· 2173 if (link_state != BMSR_LSTATUS) { 2174 /* link stays down */ 2175 if (slave->delay <= 0) { 2176 /* link down for too long time */ 2177 slave->link = BOND_LINK_DOWN; 2178 ··· 2259 } else { 2260 /* link stays up */ 2261 if (slave->delay == 0) { 2262 /* now the link has been up for long time enough */ 2263 slave->link = BOND_LINK_UP; 2264 slave->jiffies = jiffies; ··· 2335 } else 2336 bond_set_carrier(bond); 2337 2338 - re_arm: 2339 - if (bond->params.miimon) 2340 - queue_delayed_work(bond->wq, &bond->mii_work, delta_in_ticks); 2341 out: 2342 - read_unlock(&bond->lock); 2343 } 2344 2345 2346 static __be32 bond_glean_dev_ip(struct net_device *dev) 2347 {
··· 2088 2089 /*-------------------------------- Monitoring -------------------------------*/ 2090 2091 + /* 2092 + * if !have_locks, return nonzero if a failover is necessary. if 2093 + * have_locks, do whatever failover activities are needed. 2094 + * 2095 + * This is to separate the inspection and failover steps for locking 2096 + * purposes; failover requires rtnl, but acquiring it for every 2097 + * inspection is undesirable, so a wrapper first does inspection, and 2098 + * the acquires the necessary locks and calls again to perform 2099 + * failover if needed. Since all locks are dropped, a complete 2100 + * restart is needed between calls. 2101 + */ 2102 + static int __bond_mii_monitor(struct bonding *bond, int have_locks) 2103 { 2104 struct slave *slave, *oldcurrent; 2105 int do_failover = 0; 2106 int i; 2107 2108 + if (bond->slave_cnt == 0) 2109 goto out; 2110 2111 /* we will try to read the link status of each of our slaves, and 2112 * set their IFF_RUNNING flag appropriately. For each slave not ··· 2175 if (link_state != BMSR_LSTATUS) { 2176 /* link stays down */ 2177 if (slave->delay <= 0) { 2178 + if (!have_locks) 2179 + return 1; 2180 + 2181 /* link down for too long time */ 2182 slave->link = BOND_LINK_DOWN; 2183 ··· 2258 } else { 2259 /* link stays up */ 2260 if (slave->delay == 0) { 2261 + if (!have_locks) 2262 + return 1; 2263 + 2264 /* now the link has been up for long time enough */ 2265 slave->link = BOND_LINK_UP; 2266 slave->jiffies = jiffies; ··· 2331 } else 2332 bond_set_carrier(bond); 2333 2334 out: 2335 + return 0; 2336 } 2337 2338 + /* 2339 + * bond_mii_monitor 2340 + * 2341 + * Really a wrapper that splits the mii monitor into two phases: an 2342 + * inspection, then (if inspection indicates something needs to be 2343 + * done) an acquisition of appropriate locks followed by another pass 2344 + * to implement whatever link state changes are indicated. 2345 + */ 2346 + void bond_mii_monitor(struct work_struct *work) 2347 + { 2348 + struct bonding *bond = container_of(work, struct bonding, 2349 + mii_work.work); 2350 + unsigned long delay; 2351 + 2352 + read_lock(&bond->lock); 2353 + if (bond->kill_timers) { 2354 + read_unlock(&bond->lock); 2355 + return; 2356 + } 2357 + if (__bond_mii_monitor(bond, 0)) { 2358 + read_unlock(&bond->lock); 2359 + rtnl_lock(); 2360 + read_lock(&bond->lock); 2361 + __bond_mii_monitor(bond, 1); 2362 + rtnl_unlock(); 2363 + } 2364 + 2365 + delay = ((bond->params.miimon * HZ) / 1000) ? : 1; 2366 + read_unlock(&bond->lock); 2367 + queue_delayed_work(bond->wq, &bond->mii_work, delay); 2368 + } 2369 2370 static __be32 bond_glean_dev_ip(struct net_device *dev) 2371 {