aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_3ad.c1
-rw-r--r--drivers/net/bonding/bond_main.c394
-rw-r--r--drivers/net/bonding/bond_sysfs.c3
3 files changed, 173 insertions, 225 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index ebb539e090c3..6106660a4a44 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2107,6 +2107,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
2107 aggregator = __get_first_agg(port); 2107 aggregator = __get_first_agg(port);
2108 ad_agg_selection_logic(aggregator); 2108 ad_agg_selection_logic(aggregator);
2109 } 2109 }
2110 bond_3ad_set_carrier(bond);
2110 } 2111 }
2111 2112
2112 // for each port run the state machines 2113 // for each port run the state machines
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a641eeaa2a2f..c792138511e6 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2223,272 +2223,217 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
2223 2223
2224/*-------------------------------- Monitoring -------------------------------*/ 2224/*-------------------------------- Monitoring -------------------------------*/
2225 2225
2226/*
2227 * if !have_locks, return nonzero if a failover is necessary. if
2228 * have_locks, do whatever failover activities are needed.
2229 *
2230 * This is to separate the inspection and failover steps for locking
2231 * purposes; failover requires rtnl, but acquiring it for every
2232 * inspection is undesirable, so a wrapper first does inspection, and
2233 * the acquires the necessary locks and calls again to perform
2234 * failover if needed. Since all locks are dropped, a complete
2235 * restart is needed between calls.
2236 */
2237static int __bond_mii_monitor(struct bonding *bond, int have_locks)
2238{
2239 struct slave *slave, *oldcurrent;
2240 int do_failover = 0;
2241 int i;
2242
2243 if (bond->slave_cnt == 0)
2244 goto out;
2245 2226
2246 /* we will try to read the link status of each of our slaves, and 2227static int bond_miimon_inspect(struct bonding *bond)
2247 * set their IFF_RUNNING flag appropriately. For each slave not 2228{
2248 * supporting MII status, we won't do anything so that a user-space 2229 struct slave *slave;
2249 * program could monitor the link itself if needed. 2230 int i, link_state, commit = 0;
2250 */
2251
2252 read_lock(&bond->curr_slave_lock);
2253 oldcurrent = bond->curr_active_slave;
2254 read_unlock(&bond->curr_slave_lock);
2255 2231
2256 bond_for_each_slave(bond, slave, i) { 2232 bond_for_each_slave(bond, slave, i) {
2257 struct net_device *slave_dev = slave->dev; 2233 slave->new_link = BOND_LINK_NOCHANGE;
2258 int link_state;
2259 u16 old_speed = slave->speed;
2260 u8 old_duplex = slave->duplex;
2261 2234
2262 link_state = bond_check_dev_link(bond, slave_dev, 0); 2235 link_state = bond_check_dev_link(bond, slave->dev, 0);
2263 2236
2264 switch (slave->link) { 2237 switch (slave->link) {
2265 case BOND_LINK_UP: /* the link was up */ 2238 case BOND_LINK_UP:
2266 if (link_state == BMSR_LSTATUS) { 2239 if (link_state)
2267 if (!oldcurrent) { 2240 continue;
2268 if (!have_locks)
2269 return 1;
2270 do_failover = 1;
2271 }
2272 break;
2273 } else { /* link going down */
2274 slave->link = BOND_LINK_FAIL;
2275 slave->delay = bond->params.downdelay;
2276
2277 if (slave->link_failure_count < UINT_MAX) {
2278 slave->link_failure_count++;
2279 }
2280 2241
2281 if (bond->params.downdelay) { 2242 slave->link = BOND_LINK_FAIL;
2282 printk(KERN_INFO DRV_NAME 2243 slave->delay = bond->params.downdelay;
2283 ": %s: link status down for %s " 2244 if (slave->delay) {
2284 "interface %s, disabling it in " 2245 printk(KERN_INFO DRV_NAME
2285 "%d ms.\n", 2246 ": %s: link status down for %s"
2286 bond->dev->name, 2247 "interface %s, disabling it in %d ms.\n",
2287 IS_UP(slave_dev) 2248 bond->dev->name,
2288 ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) 2249 (bond->params.mode ==
2289 ? ((slave == oldcurrent) 2250 BOND_MODE_ACTIVEBACKUP) ?
2290 ? "active " : "backup ") 2251 ((slave->state == BOND_STATE_ACTIVE) ?
2291 : "") 2252 "active " : "backup ") : "",
2292 : "idle ", 2253 slave->dev->name,
2293 slave_dev->name, 2254 bond->params.downdelay * bond->params.miimon);
2294 bond->params.downdelay * bond->params.miimon);
2295 }
2296 } 2255 }
2297 /* no break ! fall through the BOND_LINK_FAIL test to 2256 /*FALLTHRU*/
2298 ensure proper action to be taken 2257 case BOND_LINK_FAIL:
2299 */ 2258 if (link_state) {
2300 case BOND_LINK_FAIL: /* the link has just gone down */ 2259 /*
2301 if (link_state != BMSR_LSTATUS) { 2260 * recovered before downdelay expired
2302 /* link stays down */ 2261 */
2303 if (slave->delay <= 0) { 2262 slave->link = BOND_LINK_UP;
2304 if (!have_locks)
2305 return 1;
2306
2307 /* link down for too long time */
2308 slave->link = BOND_LINK_DOWN;
2309
2310 /* in active/backup mode, we must
2311 * completely disable this interface
2312 */
2313 if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) ||
2314 (bond->params.mode == BOND_MODE_8023AD)) {
2315 bond_set_slave_inactive_flags(slave);
2316 }
2317
2318 printk(KERN_INFO DRV_NAME
2319 ": %s: link status definitely "
2320 "down for interface %s, "
2321 "disabling it\n",
2322 bond->dev->name,
2323 slave_dev->name);
2324
2325 /* notify ad that the link status has changed */
2326 if (bond->params.mode == BOND_MODE_8023AD) {
2327 bond_3ad_handle_link_change(slave, BOND_LINK_DOWN);
2328 }
2329
2330 if ((bond->params.mode == BOND_MODE_TLB) ||
2331 (bond->params.mode == BOND_MODE_ALB)) {
2332 bond_alb_handle_link_change(bond, slave, BOND_LINK_DOWN);
2333 }
2334
2335 if (slave == oldcurrent) {
2336 do_failover = 1;
2337 }
2338 } else {
2339 slave->delay--;
2340 }
2341 } else {
2342 /* link up again */
2343 slave->link = BOND_LINK_UP;
2344 slave->jiffies = jiffies; 2263 slave->jiffies = jiffies;
2345 printk(KERN_INFO DRV_NAME 2264 printk(KERN_INFO DRV_NAME
2346 ": %s: link status up again after %d " 2265 ": %s: link status up again after %d "
2347 "ms for interface %s.\n", 2266 "ms for interface %s.\n",
2348 bond->dev->name, 2267 bond->dev->name,
2349 (bond->params.downdelay - slave->delay) * bond->params.miimon, 2268 (bond->params.downdelay - slave->delay) *
2350 slave_dev->name); 2269 bond->params.miimon,
2270 slave->dev->name);
2271 continue;
2351 } 2272 }
2352 break;
2353 case BOND_LINK_DOWN: /* the link was down */
2354 if (link_state != BMSR_LSTATUS) {
2355 /* the link stays down, nothing more to do */
2356 break;
2357 } else { /* link going up */
2358 slave->link = BOND_LINK_BACK;
2359 slave->delay = bond->params.updelay;
2360 2273
2361 if (bond->params.updelay) { 2274 if (slave->delay <= 0) {
2362 /* if updelay == 0, no need to 2275 slave->new_link = BOND_LINK_DOWN;
2363 advertise about a 0 ms delay */ 2276 commit++;
2364 printk(KERN_INFO DRV_NAME 2277 continue;
2365 ": %s: link status up for "
2366 "interface %s, enabling it "
2367 "in %d ms.\n",
2368 bond->dev->name,
2369 slave_dev->name,
2370 bond->params.updelay * bond->params.miimon);
2371 }
2372 } 2278 }
2373 /* no break ! fall through the BOND_LINK_BACK state in
2374 case there's something to do.
2375 */
2376 case BOND_LINK_BACK: /* the link has just come back */
2377 if (link_state != BMSR_LSTATUS) {
2378 /* link down again */
2379 slave->link = BOND_LINK_DOWN;
2380 2279
2280 slave->delay--;
2281 break;
2282
2283 case BOND_LINK_DOWN:
2284 if (!link_state)
2285 continue;
2286
2287 slave->link = BOND_LINK_BACK;
2288 slave->delay = bond->params.updelay;
2289
2290 if (slave->delay) {
2291 printk(KERN_INFO DRV_NAME
2292 ": %s: link status up for "
2293 "interface %s, enabling it in %d ms.\n",
2294 bond->dev->name, slave->dev->name,
2295 bond->params.updelay *
2296 bond->params.miimon);
2297 }
2298 /*FALLTHRU*/
2299 case BOND_LINK_BACK:
2300 if (!link_state) {
2301 slave->link = BOND_LINK_DOWN;
2381 printk(KERN_INFO DRV_NAME 2302 printk(KERN_INFO DRV_NAME
2382 ": %s: link status down again after %d " 2303 ": %s: link status down again after %d "
2383 "ms for interface %s.\n", 2304 "ms for interface %s.\n",
2384 bond->dev->name, 2305 bond->dev->name,
2385 (bond->params.updelay - slave->delay) * bond->params.miimon, 2306 (bond->params.updelay - slave->delay) *
2386 slave_dev->name); 2307 bond->params.miimon,
2387 } else { 2308 slave->dev->name);
2388 /* link stays up */
2389 if (slave->delay == 0) {
2390 if (!have_locks)
2391 return 1;
2392
2393 /* now the link has been up for long time enough */
2394 slave->link = BOND_LINK_UP;
2395 slave->jiffies = jiffies;
2396
2397 if (bond->params.mode == BOND_MODE_8023AD) {
2398 /* prevent it from being the active one */
2399 slave->state = BOND_STATE_BACKUP;
2400 } else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
2401 /* make it immediately active */
2402 slave->state = BOND_STATE_ACTIVE;
2403 } else if (slave != bond->primary_slave) {
2404 /* prevent it from being the active one */
2405 slave->state = BOND_STATE_BACKUP;
2406 }
2407 2309
2408 printk(KERN_INFO DRV_NAME 2310 continue;
2409 ": %s: link status definitely "
2410 "up for interface %s.\n",
2411 bond->dev->name,
2412 slave_dev->name);
2413
2414 /* notify ad that the link status has changed */
2415 if (bond->params.mode == BOND_MODE_8023AD) {
2416 bond_3ad_handle_link_change(slave, BOND_LINK_UP);
2417 }
2418
2419 if ((bond->params.mode == BOND_MODE_TLB) ||
2420 (bond->params.mode == BOND_MODE_ALB)) {
2421 bond_alb_handle_link_change(bond, slave, BOND_LINK_UP);
2422 }
2423
2424 if ((!oldcurrent) ||
2425 (slave == bond->primary_slave)) {
2426 do_failover = 1;
2427 }
2428 } else {
2429 slave->delay--;
2430 }
2431 } 2311 }
2312
2313 if (slave->delay <= 0) {
2314 slave->new_link = BOND_LINK_UP;
2315 commit++;
2316 continue;
2317 }
2318
2319 slave->delay--;
2432 break; 2320 break;
2433 default: 2321 }
2434 /* Should not happen */ 2322 }
2435 printk(KERN_ERR DRV_NAME
2436 ": %s: Error: %s Illegal value (link=%d)\n",
2437 bond->dev->name,
2438 slave->dev->name,
2439 slave->link);
2440 goto out;
2441 } /* end of switch (slave->link) */
2442 2323
2443 bond_update_speed_duplex(slave); 2324 return commit;
2325}
2444 2326
2445 if (bond->params.mode == BOND_MODE_8023AD) { 2327static void bond_miimon_commit(struct bonding *bond)
2446 if (old_speed != slave->speed) { 2328{
2447 bond_3ad_adapter_speed_changed(slave); 2329 struct slave *slave;
2448 } 2330 int i;
2331
2332 bond_for_each_slave(bond, slave, i) {
2333 switch (slave->new_link) {
2334 case BOND_LINK_NOCHANGE:
2335 continue;
2336
2337 case BOND_LINK_UP:
2338 slave->link = BOND_LINK_UP;
2339 slave->jiffies = jiffies;
2449 2340
2450 if (old_duplex != slave->duplex) { 2341 if (bond->params.mode == BOND_MODE_8023AD) {
2451 bond_3ad_adapter_duplex_changed(slave); 2342 /* prevent it from being the active one */
2343 slave->state = BOND_STATE_BACKUP;
2344 } else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
2345 /* make it immediately active */
2346 slave->state = BOND_STATE_ACTIVE;
2347 } else if (slave != bond->primary_slave) {
2348 /* prevent it from being the active one */
2349 slave->state = BOND_STATE_BACKUP;
2452 } 2350 }
2453 }
2454 2351
2455 } /* end of for */ 2352 printk(KERN_INFO DRV_NAME
2353 ": %s: link status definitely "
2354 "up for interface %s.\n",
2355 bond->dev->name, slave->dev->name);
2456 2356
2457 if (do_failover) { 2357 /* notify ad that the link status has changed */
2458 ASSERT_RTNL(); 2358 if (bond->params.mode == BOND_MODE_8023AD)
2359 bond_3ad_handle_link_change(slave, BOND_LINK_UP);
2459 2360
2460 write_lock_bh(&bond->curr_slave_lock); 2361 if ((bond->params.mode == BOND_MODE_TLB) ||
2362 (bond->params.mode == BOND_MODE_ALB))
2363 bond_alb_handle_link_change(bond, slave,
2364 BOND_LINK_UP);
2461 2365
2462 bond_select_active_slave(bond); 2366 if (!bond->curr_active_slave ||
2367 (slave == bond->primary_slave))
2368 goto do_failover;
2463 2369
2464 write_unlock_bh(&bond->curr_slave_lock); 2370 continue;
2465 2371
2466 } else 2372 case BOND_LINK_DOWN:
2467 bond_set_carrier(bond); 2373 slave->link = BOND_LINK_DOWN;
2468 2374
2469out: 2375 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP ||
2470 return 0; 2376 bond->params.mode == BOND_MODE_8023AD)
2377 bond_set_slave_inactive_flags(slave);
2378
2379 printk(KERN_INFO DRV_NAME
2380 ": %s: link status definitely down for "
2381 "interface %s, disabling it\n",
2382 bond->dev->name, slave->dev->name);
2383
2384 if (bond->params.mode == BOND_MODE_8023AD)
2385 bond_3ad_handle_link_change(slave,
2386 BOND_LINK_DOWN);
2387
2388 if (bond->params.mode == BOND_MODE_TLB ||
2389 bond->params.mode == BOND_MODE_ALB)
2390 bond_alb_handle_link_change(bond, slave,
2391 BOND_LINK_DOWN);
2392
2393 if (slave == bond->curr_active_slave)
2394 goto do_failover;
2395
2396 continue;
2397
2398 default:
2399 printk(KERN_ERR DRV_NAME
2400 ": %s: invalid new link %d on slave %s\n",
2401 bond->dev->name, slave->new_link,
2402 slave->dev->name);
2403 slave->new_link = BOND_LINK_NOCHANGE;
2404
2405 continue;
2406 }
2407
2408do_failover:
2409 ASSERT_RTNL();
2410 write_lock_bh(&bond->curr_slave_lock);
2411 bond_select_active_slave(bond);
2412 write_unlock_bh(&bond->curr_slave_lock);
2413 }
2414
2415 bond_set_carrier(bond);
2471} 2416}
2472 2417
2473/* 2418/*
2474 * bond_mii_monitor 2419 * bond_mii_monitor
2475 * 2420 *
2476 * Really a wrapper that splits the mii monitor into two phases: an 2421 * Really a wrapper that splits the mii monitor into two phases: an
2477 * inspection, then (if inspection indicates something needs to be 2422 * inspection, then (if inspection indicates something needs to be done)
2478 * done) an acquisition of appropriate locks followed by another pass 2423 * an acquisition of appropriate locks followed by a commit phase to
2479 * to implement whatever link state changes are indicated. 2424 * implement whatever link state changes are indicated.
2480 */ 2425 */
2481void bond_mii_monitor(struct work_struct *work) 2426void bond_mii_monitor(struct work_struct *work)
2482{ 2427{
2483 struct bonding *bond = container_of(work, struct bonding, 2428 struct bonding *bond = container_of(work, struct bonding,
2484 mii_work.work); 2429 mii_work.work);
2485 unsigned long delay;
2486 2430
2487 read_lock(&bond->lock); 2431 read_lock(&bond->lock);
2488 if (bond->kill_timers) { 2432 if (bond->kill_timers)
2489 read_unlock(&bond->lock); 2433 goto out;
2490 return; 2434
2491 } 2435 if (bond->slave_cnt == 0)
2436 goto re_arm;
2492 2437
2493 if (bond->send_grat_arp) { 2438 if (bond->send_grat_arp) {
2494 read_lock(&bond->curr_slave_lock); 2439 read_lock(&bond->curr_slave_lock);
@@ -2496,19 +2441,24 @@ void bond_mii_monitor(struct work_struct *work)
2496 read_unlock(&bond->curr_slave_lock); 2441 read_unlock(&bond->curr_slave_lock);
2497 } 2442 }
2498 2443
2499 if (__bond_mii_monitor(bond, 0)) { 2444 if (bond_miimon_inspect(bond)) {
2500 read_unlock(&bond->lock); 2445 read_unlock(&bond->lock);
2501 rtnl_lock(); 2446 rtnl_lock();
2502 read_lock(&bond->lock); 2447 read_lock(&bond->lock);
2503 __bond_mii_monitor(bond, 1); 2448
2449 bond_miimon_commit(bond);
2450
2504 read_unlock(&bond->lock); 2451 read_unlock(&bond->lock);
2505 rtnl_unlock(); /* might sleep, hold no other locks */ 2452 rtnl_unlock(); /* might sleep, hold no other locks */
2506 read_lock(&bond->lock); 2453 read_lock(&bond->lock);
2507 } 2454 }
2508 2455
2509 delay = msecs_to_jiffies(bond->params.miimon); 2456re_arm:
2457 if (bond->params.miimon)
2458 queue_delayed_work(bond->wq, &bond->mii_work,
2459 msecs_to_jiffies(bond->params.miimon));
2460out:
2510 read_unlock(&bond->lock); 2461 read_unlock(&bond->lock);
2511 queue_delayed_work(bond->wq, &bond->mii_work, delay);
2512} 2462}
2513 2463
2514static __be32 bond_glean_dev_ip(struct net_device *dev) 2464static __be32 bond_glean_dev_ip(struct net_device *dev)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 6caac0ffb2f2..3bdb47382521 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -350,9 +350,6 @@ static ssize_t bonding_store_slaves(struct device *d,
350 if (dev) { 350 if (dev) {
351 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n", 351 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
352 bond->dev->name, dev->name); 352 bond->dev->name, dev->name);
353 if (bond->setup_by_slave)
354 res = bond_release_and_destroy(bond->dev, dev);
355 else
356 res = bond_release(bond->dev, dev); 353 res = bond_release(bond->dev, dev);
357 if (res) { 354 if (res) {
358 ret = res; 355 ret = res;