diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-23 21:56:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-23 21:56:54 -0400 |
commit | 5a0e554b62dc77709ceebb6326b292bdd8d2c342 (patch) | |
tree | e3c960a526b13a27b6de33a5bc3be580ac0fa231 /drivers/net/bonding/bond_main.c | |
parent | c09b360a2b0779e08bacb88d3fcd8458ebc49658 (diff) | |
parent | 2c800093c7375e358f28eeb132512eb57b6389e3 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (39 commits)
Remove Andrew Morton from list of net driver maintainers.
bonding: Acquire correct locks in alb for promisc change
bonding: Convert more locks to _bh, acquire rtnl, for new locking
bonding: Convert locks to _bh, rework alb locking for new locking
bonding: Convert miimon to new locking
bonding: Convert balance-rr transmit to new locking
Convert bonding timers to workqueues
Update MAINTAINERS to reflect my (jgarzik's) current efforts.
pasemi_mac: fix typo
defxx.c: dfx_bus_init() is __devexit not __devinit
s390 MAINTAINERS
remove header_ops bug in qeth driver
sky2: crash on remove
MIPSnet: Delete all the useless debugging printks.
AR7 ethernet: small post-merge cleanups and fixes
mv643xx_eth: Hook up mv643xx_get_sset_count
mv643xx_eth: Remove obsolete checksum offload comment
mv643xx_eth: Merge drivers/net/mv643xx_eth.h into mv643xx_eth.c
mv643xx_eth: Remove unused register defines
mv643xx_eth: Clean up mv643xx_eth.h
...
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 330 |
1 files changed, 201 insertions, 129 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6f85cc31f8a2..6909becb10f6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1590,15 +1590,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1590 | case BOND_MODE_TLB: | 1590 | case BOND_MODE_TLB: |
1591 | case BOND_MODE_ALB: | 1591 | case BOND_MODE_ALB: |
1592 | new_slave->state = BOND_STATE_ACTIVE; | 1592 | new_slave->state = BOND_STATE_ACTIVE; |
1593 | if ((!bond->curr_active_slave) && | 1593 | bond_set_slave_inactive_flags(new_slave); |
1594 | (new_slave->link != BOND_LINK_DOWN)) { | ||
1595 | /* first slave or no active slave yet, and this link | ||
1596 | * is OK, so make this interface the active one | ||
1597 | */ | ||
1598 | bond_change_active_slave(bond, new_slave); | ||
1599 | } else { | ||
1600 | bond_set_slave_inactive_flags(new_slave); | ||
1601 | } | ||
1602 | break; | 1594 | break; |
1603 | default: | 1595 | default: |
1604 | dprintk("This slave is always active in trunk mode\n"); | 1596 | dprintk("This slave is always active in trunk mode\n"); |
@@ -1754,9 +1746,23 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1754 | bond_alb_deinit_slave(bond, slave); | 1746 | bond_alb_deinit_slave(bond, slave); |
1755 | } | 1747 | } |
1756 | 1748 | ||
1757 | if (oldcurrent == slave) | 1749 | if (oldcurrent == slave) { |
1750 | /* | ||
1751 | * Note that we hold RTNL over this sequence, so there | ||
1752 | * is no concern that another slave add/remove event | ||
1753 | * will interfere. | ||
1754 | */ | ||
1755 | write_unlock_bh(&bond->lock); | ||
1756 | read_lock(&bond->lock); | ||
1757 | write_lock_bh(&bond->curr_slave_lock); | ||
1758 | |||
1758 | bond_select_active_slave(bond); | 1759 | bond_select_active_slave(bond); |
1759 | 1760 | ||
1761 | write_unlock_bh(&bond->curr_slave_lock); | ||
1762 | read_unlock(&bond->lock); | ||
1763 | write_lock_bh(&bond->lock); | ||
1764 | } | ||
1765 | |||
1760 | if (bond->slave_cnt == 0) { | 1766 | if (bond->slave_cnt == 0) { |
1761 | bond_set_carrier(bond); | 1767 | bond_set_carrier(bond); |
1762 | 1768 | ||
@@ -1840,9 +1846,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1840 | */ | 1846 | */ |
1841 | void bond_destroy(struct bonding *bond) | 1847 | void bond_destroy(struct bonding *bond) |
1842 | { | 1848 | { |
1849 | unregister_netdevice(bond->dev); | ||
1843 | bond_deinit(bond->dev); | 1850 | bond_deinit(bond->dev); |
1844 | bond_destroy_sysfs_entry(bond); | 1851 | bond_destroy_sysfs_entry(bond); |
1845 | unregister_netdevice(bond->dev); | ||
1846 | } | 1852 | } |
1847 | 1853 | ||
1848 | /* | 1854 | /* |
@@ -2012,16 +2018,19 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi | |||
2012 | return -EINVAL; | 2018 | return -EINVAL; |
2013 | } | 2019 | } |
2014 | 2020 | ||
2015 | write_lock_bh(&bond->lock); | 2021 | read_lock(&bond->lock); |
2016 | 2022 | ||
2023 | read_lock(&bond->curr_slave_lock); | ||
2017 | old_active = bond->curr_active_slave; | 2024 | old_active = bond->curr_active_slave; |
2025 | read_unlock(&bond->curr_slave_lock); | ||
2026 | |||
2018 | new_active = bond_get_slave_by_dev(bond, slave_dev); | 2027 | new_active = bond_get_slave_by_dev(bond, slave_dev); |
2019 | 2028 | ||
2020 | /* | 2029 | /* |
2021 | * Changing to the current active: do nothing; return success. | 2030 | * Changing to the current active: do nothing; return success. |
2022 | */ | 2031 | */ |
2023 | if (new_active && (new_active == old_active)) { | 2032 | if (new_active && (new_active == old_active)) { |
2024 | write_unlock_bh(&bond->lock); | 2033 | read_unlock(&bond->lock); |
2025 | return 0; | 2034 | return 0; |
2026 | } | 2035 | } |
2027 | 2036 | ||
@@ -2029,12 +2038,14 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi | |||
2029 | (old_active) && | 2038 | (old_active) && |
2030 | (new_active->link == BOND_LINK_UP) && | 2039 | (new_active->link == BOND_LINK_UP) && |
2031 | IS_UP(new_active->dev)) { | 2040 | IS_UP(new_active->dev)) { |
2041 | write_lock_bh(&bond->curr_slave_lock); | ||
2032 | bond_change_active_slave(bond, new_active); | 2042 | bond_change_active_slave(bond, new_active); |
2043 | write_unlock_bh(&bond->curr_slave_lock); | ||
2033 | } else { | 2044 | } else { |
2034 | res = -EINVAL; | 2045 | res = -EINVAL; |
2035 | } | 2046 | } |
2036 | 2047 | ||
2037 | write_unlock_bh(&bond->lock); | 2048 | read_unlock(&bond->lock); |
2038 | 2049 | ||
2039 | return res; | 2050 | return res; |
2040 | } | 2051 | } |
@@ -2046,9 +2057,9 @@ static int bond_info_query(struct net_device *bond_dev, struct ifbond *info) | |||
2046 | info->bond_mode = bond->params.mode; | 2057 | info->bond_mode = bond->params.mode; |
2047 | info->miimon = bond->params.miimon; | 2058 | info->miimon = bond->params.miimon; |
2048 | 2059 | ||
2049 | read_lock_bh(&bond->lock); | 2060 | read_lock(&bond->lock); |
2050 | info->num_slaves = bond->slave_cnt; | 2061 | info->num_slaves = bond->slave_cnt; |
2051 | read_unlock_bh(&bond->lock); | 2062 | read_unlock(&bond->lock); |
2052 | 2063 | ||
2053 | return 0; | 2064 | return 0; |
2054 | } | 2065 | } |
@@ -2063,7 +2074,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in | |||
2063 | return -ENODEV; | 2074 | return -ENODEV; |
2064 | } | 2075 | } |
2065 | 2076 | ||
2066 | read_lock_bh(&bond->lock); | 2077 | read_lock(&bond->lock); |
2067 | 2078 | ||
2068 | bond_for_each_slave(bond, slave, i) { | 2079 | bond_for_each_slave(bond, slave, i) { |
2069 | if (i == (int)info->slave_id) { | 2080 | if (i == (int)info->slave_id) { |
@@ -2072,7 +2083,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in | |||
2072 | } | 2083 | } |
2073 | } | 2084 | } |
2074 | 2085 | ||
2075 | read_unlock_bh(&bond->lock); | 2086 | read_unlock(&bond->lock); |
2076 | 2087 | ||
2077 | if (found) { | 2088 | if (found) { |
2078 | strcpy(info->slave_name, slave->dev->name); | 2089 | strcpy(info->slave_name, slave->dev->name); |
@@ -2088,26 +2099,25 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in | |||
2088 | 2099 | ||
2089 | /*-------------------------------- Monitoring -------------------------------*/ | 2100 | /*-------------------------------- Monitoring -------------------------------*/ |
2090 | 2101 | ||
2091 | /* this function is called regularly to monitor each slave's link. */ | 2102 | /* |
2092 | void bond_mii_monitor(struct net_device *bond_dev) | 2103 | * if !have_locks, return nonzero if a failover is necessary. if |
2104 | * have_locks, do whatever failover activities are needed. | ||
2105 | * | ||
2106 | * This is to separate the inspection and failover steps for locking | ||
2107 | * purposes; failover requires rtnl, but acquiring it for every | ||
2108 | * inspection is undesirable, so a wrapper first does inspection, and | ||
2109 | * the acquires the necessary locks and calls again to perform | ||
2110 | * failover if needed. Since all locks are dropped, a complete | ||
2111 | * restart is needed between calls. | ||
2112 | */ | ||
2113 | static int __bond_mii_monitor(struct bonding *bond, int have_locks) | ||
2093 | { | 2114 | { |
2094 | struct bonding *bond = bond_dev->priv; | ||
2095 | struct slave *slave, *oldcurrent; | 2115 | struct slave *slave, *oldcurrent; |
2096 | int do_failover = 0; | 2116 | int do_failover = 0; |
2097 | int delta_in_ticks; | ||
2098 | int i; | 2117 | int i; |
2099 | 2118 | ||
2100 | read_lock(&bond->lock); | 2119 | if (bond->slave_cnt == 0) |
2101 | |||
2102 | delta_in_ticks = (bond->params.miimon * HZ) / 1000; | ||
2103 | |||
2104 | if (bond->kill_timers) { | ||
2105 | goto out; | 2120 | goto out; |
2106 | } | ||
2107 | |||
2108 | if (bond->slave_cnt == 0) { | ||
2109 | goto re_arm; | ||
2110 | } | ||
2111 | 2121 | ||
2112 | /* we will try to read the link status of each of our slaves, and | 2122 | /* we will try to read the link status of each of our slaves, and |
2113 | * set their IFF_RUNNING flag appropriately. For each slave not | 2123 | * set their IFF_RUNNING flag appropriately. For each slave not |
@@ -2141,7 +2151,11 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2141 | switch (slave->link) { | 2151 | switch (slave->link) { |
2142 | case BOND_LINK_UP: /* the link was up */ | 2152 | case BOND_LINK_UP: /* the link was up */ |
2143 | if (link_state == BMSR_LSTATUS) { | 2153 | if (link_state == BMSR_LSTATUS) { |
2144 | /* link stays up, nothing more to do */ | 2154 | if (!oldcurrent) { |
2155 | if (!have_locks) | ||
2156 | return 1; | ||
2157 | do_failover = 1; | ||
2158 | } | ||
2145 | break; | 2159 | break; |
2146 | } else { /* link going down */ | 2160 | } else { /* link going down */ |
2147 | slave->link = BOND_LINK_FAIL; | 2161 | slave->link = BOND_LINK_FAIL; |
@@ -2156,7 +2170,7 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2156 | ": %s: link status down for %s " | 2170 | ": %s: link status down for %s " |
2157 | "interface %s, disabling it in " | 2171 | "interface %s, disabling it in " |
2158 | "%d ms.\n", | 2172 | "%d ms.\n", |
2159 | bond_dev->name, | 2173 | bond->dev->name, |
2160 | IS_UP(slave_dev) | 2174 | IS_UP(slave_dev) |
2161 | ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) | 2175 | ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) |
2162 | ? ((slave == oldcurrent) | 2176 | ? ((slave == oldcurrent) |
@@ -2174,6 +2188,9 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2174 | if (link_state != BMSR_LSTATUS) { | 2188 | if (link_state != BMSR_LSTATUS) { |
2175 | /* link stays down */ | 2189 | /* link stays down */ |
2176 | if (slave->delay <= 0) { | 2190 | if (slave->delay <= 0) { |
2191 | if (!have_locks) | ||
2192 | return 1; | ||
2193 | |||
2177 | /* link down for too long time */ | 2194 | /* link down for too long time */ |
2178 | slave->link = BOND_LINK_DOWN; | 2195 | slave->link = BOND_LINK_DOWN; |
2179 | 2196 | ||
@@ -2189,7 +2206,7 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2189 | ": %s: link status definitely " | 2206 | ": %s: link status definitely " |
2190 | "down for interface %s, " | 2207 | "down for interface %s, " |
2191 | "disabling it\n", | 2208 | "disabling it\n", |
2192 | bond_dev->name, | 2209 | bond->dev->name, |
2193 | slave_dev->name); | 2210 | slave_dev->name); |
2194 | 2211 | ||
2195 | /* notify ad that the link status has changed */ | 2212 | /* notify ad that the link status has changed */ |
@@ -2215,7 +2232,7 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2215 | printk(KERN_INFO DRV_NAME | 2232 | printk(KERN_INFO DRV_NAME |
2216 | ": %s: link status up again after %d " | 2233 | ": %s: link status up again after %d " |
2217 | "ms for interface %s.\n", | 2234 | "ms for interface %s.\n", |
2218 | bond_dev->name, | 2235 | bond->dev->name, |
2219 | (bond->params.downdelay - slave->delay) * bond->params.miimon, | 2236 | (bond->params.downdelay - slave->delay) * bond->params.miimon, |
2220 | slave_dev->name); | 2237 | slave_dev->name); |
2221 | } | 2238 | } |
@@ -2235,7 +2252,7 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2235 | ": %s: link status up for " | 2252 | ": %s: link status up for " |
2236 | "interface %s, enabling it " | 2253 | "interface %s, enabling it " |
2237 | "in %d ms.\n", | 2254 | "in %d ms.\n", |
2238 | bond_dev->name, | 2255 | bond->dev->name, |
2239 | slave_dev->name, | 2256 | slave_dev->name, |
2240 | bond->params.updelay * bond->params.miimon); | 2257 | bond->params.updelay * bond->params.miimon); |
2241 | } | 2258 | } |
@@ -2251,12 +2268,15 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2251 | printk(KERN_INFO DRV_NAME | 2268 | printk(KERN_INFO DRV_NAME |
2252 | ": %s: link status down again after %d " | 2269 | ": %s: link status down again after %d " |
2253 | "ms for interface %s.\n", | 2270 | "ms for interface %s.\n", |
2254 | bond_dev->name, | 2271 | bond->dev->name, |
2255 | (bond->params.updelay - slave->delay) * bond->params.miimon, | 2272 | (bond->params.updelay - slave->delay) * bond->params.miimon, |
2256 | slave_dev->name); | 2273 | slave_dev->name); |
2257 | } else { | 2274 | } else { |
2258 | /* link stays up */ | 2275 | /* link stays up */ |
2259 | if (slave->delay == 0) { | 2276 | if (slave->delay == 0) { |
2277 | if (!have_locks) | ||
2278 | return 1; | ||
2279 | |||
2260 | /* now the link has been up for long time enough */ | 2280 | /* now the link has been up for long time enough */ |
2261 | slave->link = BOND_LINK_UP; | 2281 | slave->link = BOND_LINK_UP; |
2262 | slave->jiffies = jiffies; | 2282 | slave->jiffies = jiffies; |
@@ -2275,7 +2295,7 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2275 | printk(KERN_INFO DRV_NAME | 2295 | printk(KERN_INFO DRV_NAME |
2276 | ": %s: link status definitely " | 2296 | ": %s: link status definitely " |
2277 | "up for interface %s.\n", | 2297 | "up for interface %s.\n", |
2278 | bond_dev->name, | 2298 | bond->dev->name, |
2279 | slave_dev->name); | 2299 | slave_dev->name); |
2280 | 2300 | ||
2281 | /* notify ad that the link status has changed */ | 2301 | /* notify ad that the link status has changed */ |
@@ -2301,7 +2321,7 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2301 | /* Should not happen */ | 2321 | /* Should not happen */ |
2302 | printk(KERN_ERR DRV_NAME | 2322 | printk(KERN_ERR DRV_NAME |
2303 | ": %s: Error: %s Illegal value (link=%d)\n", | 2323 | ": %s: Error: %s Illegal value (link=%d)\n", |
2304 | bond_dev->name, | 2324 | bond->dev->name, |
2305 | slave->dev->name, | 2325 | slave->dev->name, |
2306 | slave->link); | 2326 | slave->link); |
2307 | goto out; | 2327 | goto out; |
@@ -2322,22 +2342,52 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2322 | } /* end of for */ | 2342 | } /* end of for */ |
2323 | 2343 | ||
2324 | if (do_failover) { | 2344 | if (do_failover) { |
2325 | write_lock(&bond->curr_slave_lock); | 2345 | ASSERT_RTNL(); |
2346 | |||
2347 | write_lock_bh(&bond->curr_slave_lock); | ||
2326 | 2348 | ||
2327 | bond_select_active_slave(bond); | 2349 | bond_select_active_slave(bond); |
2328 | 2350 | ||
2329 | write_unlock(&bond->curr_slave_lock); | 2351 | write_unlock_bh(&bond->curr_slave_lock); |
2352 | |||
2330 | } else | 2353 | } else |
2331 | bond_set_carrier(bond); | 2354 | bond_set_carrier(bond); |
2332 | 2355 | ||
2333 | re_arm: | ||
2334 | if (bond->params.miimon) { | ||
2335 | mod_timer(&bond->mii_timer, jiffies + delta_in_ticks); | ||
2336 | } | ||
2337 | out: | 2356 | out: |
2338 | read_unlock(&bond->lock); | 2357 | return 0; |
2339 | } | 2358 | } |
2340 | 2359 | ||
2360 | /* | ||
2361 | * bond_mii_monitor | ||
2362 | * | ||
2363 | * Really a wrapper that splits the mii monitor into two phases: an | ||
2364 | * inspection, then (if inspection indicates something needs to be | ||
2365 | * done) an acquisition of appropriate locks followed by another pass | ||
2366 | * to implement whatever link state changes are indicated. | ||
2367 | */ | ||
2368 | void bond_mii_monitor(struct work_struct *work) | ||
2369 | { | ||
2370 | struct bonding *bond = container_of(work, struct bonding, | ||
2371 | mii_work.work); | ||
2372 | unsigned long delay; | ||
2373 | |||
2374 | read_lock(&bond->lock); | ||
2375 | if (bond->kill_timers) { | ||
2376 | read_unlock(&bond->lock); | ||
2377 | return; | ||
2378 | } | ||
2379 | if (__bond_mii_monitor(bond, 0)) { | ||
2380 | read_unlock(&bond->lock); | ||
2381 | rtnl_lock(); | ||
2382 | read_lock(&bond->lock); | ||
2383 | __bond_mii_monitor(bond, 1); | ||
2384 | rtnl_unlock(); | ||
2385 | } | ||
2386 | |||
2387 | delay = ((bond->params.miimon * HZ) / 1000) ? : 1; | ||
2388 | read_unlock(&bond->lock); | ||
2389 | queue_delayed_work(bond->wq, &bond->mii_work, delay); | ||
2390 | } | ||
2341 | 2391 | ||
2342 | static __be32 bond_glean_dev_ip(struct net_device *dev) | 2392 | static __be32 bond_glean_dev_ip(struct net_device *dev) |
2343 | { | 2393 | { |
@@ -2636,9 +2686,10 @@ out: | |||
2636 | * arp is transmitted to generate traffic. see activebackup_arp_monitor for | 2686 | * arp is transmitted to generate traffic. see activebackup_arp_monitor for |
2637 | * arp monitoring in active backup mode. | 2687 | * arp monitoring in active backup mode. |
2638 | */ | 2688 | */ |
2639 | void bond_loadbalance_arp_mon(struct net_device *bond_dev) | 2689 | void bond_loadbalance_arp_mon(struct work_struct *work) |
2640 | { | 2690 | { |
2641 | struct bonding *bond = bond_dev->priv; | 2691 | struct bonding *bond = container_of(work, struct bonding, |
2692 | arp_work.work); | ||
2642 | struct slave *slave, *oldcurrent; | 2693 | struct slave *slave, *oldcurrent; |
2643 | int do_failover = 0; | 2694 | int do_failover = 0; |
2644 | int delta_in_ticks; | 2695 | int delta_in_ticks; |
@@ -2685,13 +2736,13 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev) | |||
2685 | printk(KERN_INFO DRV_NAME | 2736 | printk(KERN_INFO DRV_NAME |
2686 | ": %s: link status definitely " | 2737 | ": %s: link status definitely " |
2687 | "up for interface %s, ", | 2738 | "up for interface %s, ", |
2688 | bond_dev->name, | 2739 | bond->dev->name, |
2689 | slave->dev->name); | 2740 | slave->dev->name); |
2690 | do_failover = 1; | 2741 | do_failover = 1; |
2691 | } else { | 2742 | } else { |
2692 | printk(KERN_INFO DRV_NAME | 2743 | printk(KERN_INFO DRV_NAME |
2693 | ": %s: interface %s is now up\n", | 2744 | ": %s: interface %s is now up\n", |
2694 | bond_dev->name, | 2745 | bond->dev->name, |
2695 | slave->dev->name); | 2746 | slave->dev->name); |
2696 | } | 2747 | } |
2697 | } | 2748 | } |
@@ -2715,7 +2766,7 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev) | |||
2715 | 2766 | ||
2716 | printk(KERN_INFO DRV_NAME | 2767 | printk(KERN_INFO DRV_NAME |
2717 | ": %s: interface %s is now down.\n", | 2768 | ": %s: interface %s is now down.\n", |
2718 | bond_dev->name, | 2769 | bond->dev->name, |
2719 | slave->dev->name); | 2770 | slave->dev->name); |
2720 | 2771 | ||
2721 | if (slave == oldcurrent) { | 2772 | if (slave == oldcurrent) { |
@@ -2737,17 +2788,19 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev) | |||
2737 | } | 2788 | } |
2738 | 2789 | ||
2739 | if (do_failover) { | 2790 | if (do_failover) { |
2740 | write_lock(&bond->curr_slave_lock); | 2791 | rtnl_lock(); |
2792 | write_lock_bh(&bond->curr_slave_lock); | ||
2741 | 2793 | ||
2742 | bond_select_active_slave(bond); | 2794 | bond_select_active_slave(bond); |
2743 | 2795 | ||
2744 | write_unlock(&bond->curr_slave_lock); | 2796 | write_unlock_bh(&bond->curr_slave_lock); |
2797 | rtnl_unlock(); | ||
2798 | |||
2745 | } | 2799 | } |
2746 | 2800 | ||
2747 | re_arm: | 2801 | re_arm: |
2748 | if (bond->params.arp_interval) { | 2802 | if (bond->params.arp_interval) |
2749 | mod_timer(&bond->arp_timer, jiffies + delta_in_ticks); | 2803 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
2750 | } | ||
2751 | out: | 2804 | out: |
2752 | read_unlock(&bond->lock); | 2805 | read_unlock(&bond->lock); |
2753 | } | 2806 | } |
@@ -2767,9 +2820,10 @@ out: | |||
2767 | * may have received. | 2820 | * may have received. |
2768 | * see loadbalance_arp_monitor for arp monitoring in load balancing mode | 2821 | * see loadbalance_arp_monitor for arp monitoring in load balancing mode |
2769 | */ | 2822 | */ |
2770 | void bond_activebackup_arp_mon(struct net_device *bond_dev) | 2823 | void bond_activebackup_arp_mon(struct work_struct *work) |
2771 | { | 2824 | { |
2772 | struct bonding *bond = bond_dev->priv; | 2825 | struct bonding *bond = container_of(work, struct bonding, |
2826 | arp_work.work); | ||
2773 | struct slave *slave; | 2827 | struct slave *slave; |
2774 | int delta_in_ticks; | 2828 | int delta_in_ticks; |
2775 | int i; | 2829 | int i; |
@@ -2798,7 +2852,9 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2798 | 2852 | ||
2799 | slave->link = BOND_LINK_UP; | 2853 | slave->link = BOND_LINK_UP; |
2800 | 2854 | ||
2801 | write_lock(&bond->curr_slave_lock); | 2855 | rtnl_lock(); |
2856 | |||
2857 | write_lock_bh(&bond->curr_slave_lock); | ||
2802 | 2858 | ||
2803 | if ((!bond->curr_active_slave) && | 2859 | if ((!bond->curr_active_slave) && |
2804 | ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) { | 2860 | ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) { |
@@ -2821,18 +2877,19 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2821 | printk(KERN_INFO DRV_NAME | 2877 | printk(KERN_INFO DRV_NAME |
2822 | ": %s: %s is up and now the " | 2878 | ": %s: %s is up and now the " |
2823 | "active interface\n", | 2879 | "active interface\n", |
2824 | bond_dev->name, | 2880 | bond->dev->name, |
2825 | slave->dev->name); | 2881 | slave->dev->name); |
2826 | netif_carrier_on(bond->dev); | 2882 | netif_carrier_on(bond->dev); |
2827 | } else { | 2883 | } else { |
2828 | printk(KERN_INFO DRV_NAME | 2884 | printk(KERN_INFO DRV_NAME |
2829 | ": %s: backup interface %s is " | 2885 | ": %s: backup interface %s is " |
2830 | "now up\n", | 2886 | "now up\n", |
2831 | bond_dev->name, | 2887 | bond->dev->name, |
2832 | slave->dev->name); | 2888 | slave->dev->name); |
2833 | } | 2889 | } |
2834 | 2890 | ||
2835 | write_unlock(&bond->curr_slave_lock); | 2891 | write_unlock_bh(&bond->curr_slave_lock); |
2892 | rtnl_unlock(); | ||
2836 | } | 2893 | } |
2837 | } else { | 2894 | } else { |
2838 | read_lock(&bond->curr_slave_lock); | 2895 | read_lock(&bond->curr_slave_lock); |
@@ -2864,7 +2921,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2864 | 2921 | ||
2865 | printk(KERN_INFO DRV_NAME | 2922 | printk(KERN_INFO DRV_NAME |
2866 | ": %s: backup interface %s is now down\n", | 2923 | ": %s: backup interface %s is now down\n", |
2867 | bond_dev->name, | 2924 | bond->dev->name, |
2868 | slave->dev->name); | 2925 | slave->dev->name); |
2869 | } else { | 2926 | } else { |
2870 | read_unlock(&bond->curr_slave_lock); | 2927 | read_unlock(&bond->curr_slave_lock); |
@@ -2899,15 +2956,18 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2899 | printk(KERN_INFO DRV_NAME | 2956 | printk(KERN_INFO DRV_NAME |
2900 | ": %s: link status down for active interface " | 2957 | ": %s: link status down for active interface " |
2901 | "%s, disabling it\n", | 2958 | "%s, disabling it\n", |
2902 | bond_dev->name, | 2959 | bond->dev->name, |
2903 | slave->dev->name); | 2960 | slave->dev->name); |
2904 | 2961 | ||
2905 | write_lock(&bond->curr_slave_lock); | 2962 | rtnl_lock(); |
2963 | write_lock_bh(&bond->curr_slave_lock); | ||
2906 | 2964 | ||
2907 | bond_select_active_slave(bond); | 2965 | bond_select_active_slave(bond); |
2908 | slave = bond->curr_active_slave; | 2966 | slave = bond->curr_active_slave; |
2909 | 2967 | ||
2910 | write_unlock(&bond->curr_slave_lock); | 2968 | write_unlock_bh(&bond->curr_slave_lock); |
2969 | |||
2970 | rtnl_unlock(); | ||
2911 | 2971 | ||
2912 | bond->current_arp_slave = slave; | 2972 | bond->current_arp_slave = slave; |
2913 | 2973 | ||
@@ -2921,14 +2981,17 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2921 | printk(KERN_INFO DRV_NAME | 2981 | printk(KERN_INFO DRV_NAME |
2922 | ": %s: changing from interface %s to primary " | 2982 | ": %s: changing from interface %s to primary " |
2923 | "interface %s\n", | 2983 | "interface %s\n", |
2924 | bond_dev->name, | 2984 | bond->dev->name, |
2925 | slave->dev->name, | 2985 | slave->dev->name, |
2926 | bond->primary_slave->dev->name); | 2986 | bond->primary_slave->dev->name); |
2927 | 2987 | ||
2928 | /* primary is up so switch to it */ | 2988 | /* primary is up so switch to it */ |
2929 | write_lock(&bond->curr_slave_lock); | 2989 | rtnl_lock(); |
2990 | write_lock_bh(&bond->curr_slave_lock); | ||
2930 | bond_change_active_slave(bond, bond->primary_slave); | 2991 | bond_change_active_slave(bond, bond->primary_slave); |
2931 | write_unlock(&bond->curr_slave_lock); | 2992 | write_unlock_bh(&bond->curr_slave_lock); |
2993 | |||
2994 | rtnl_unlock(); | ||
2932 | 2995 | ||
2933 | slave = bond->primary_slave; | 2996 | slave = bond->primary_slave; |
2934 | slave->jiffies = jiffies; | 2997 | slave->jiffies = jiffies; |
@@ -2985,7 +3048,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2985 | printk(KERN_INFO DRV_NAME | 3048 | printk(KERN_INFO DRV_NAME |
2986 | ": %s: backup interface %s is " | 3049 | ": %s: backup interface %s is " |
2987 | "now down.\n", | 3050 | "now down.\n", |
2988 | bond_dev->name, | 3051 | bond->dev->name, |
2989 | slave->dev->name); | 3052 | slave->dev->name); |
2990 | } | 3053 | } |
2991 | } | 3054 | } |
@@ -2994,7 +3057,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2994 | 3057 | ||
2995 | re_arm: | 3058 | re_arm: |
2996 | if (bond->params.arp_interval) { | 3059 | if (bond->params.arp_interval) { |
2997 | mod_timer(&bond->arp_timer, jiffies + delta_in_ticks); | 3060 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
2998 | } | 3061 | } |
2999 | out: | 3062 | out: |
3000 | read_unlock(&bond->lock); | 3063 | read_unlock(&bond->lock); |
@@ -3015,7 +3078,7 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) | |||
3015 | 3078 | ||
3016 | /* make sure the bond won't be taken away */ | 3079 | /* make sure the bond won't be taken away */ |
3017 | read_lock(&dev_base_lock); | 3080 | read_lock(&dev_base_lock); |
3018 | read_lock_bh(&bond->lock); | 3081 | read_lock(&bond->lock); |
3019 | 3082 | ||
3020 | if (*pos == 0) { | 3083 | if (*pos == 0) { |
3021 | return SEQ_START_TOKEN; | 3084 | return SEQ_START_TOKEN; |
@@ -3049,7 +3112,7 @@ static void bond_info_seq_stop(struct seq_file *seq, void *v) | |||
3049 | { | 3112 | { |
3050 | struct bonding *bond = seq->private; | 3113 | struct bonding *bond = seq->private; |
3051 | 3114 | ||
3052 | read_unlock_bh(&bond->lock); | 3115 | read_unlock(&bond->lock); |
3053 | read_unlock(&dev_base_lock); | 3116 | read_unlock(&dev_base_lock); |
3054 | } | 3117 | } |
3055 | 3118 | ||
@@ -3582,15 +3645,11 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, | |||
3582 | static int bond_open(struct net_device *bond_dev) | 3645 | static int bond_open(struct net_device *bond_dev) |
3583 | { | 3646 | { |
3584 | struct bonding *bond = bond_dev->priv; | 3647 | struct bonding *bond = bond_dev->priv; |
3585 | struct timer_list *mii_timer = &bond->mii_timer; | ||
3586 | struct timer_list *arp_timer = &bond->arp_timer; | ||
3587 | 3648 | ||
3588 | bond->kill_timers = 0; | 3649 | bond->kill_timers = 0; |
3589 | 3650 | ||
3590 | if ((bond->params.mode == BOND_MODE_TLB) || | 3651 | if ((bond->params.mode == BOND_MODE_TLB) || |
3591 | (bond->params.mode == BOND_MODE_ALB)) { | 3652 | (bond->params.mode == BOND_MODE_ALB)) { |
3592 | struct timer_list *alb_timer = &(BOND_ALB_INFO(bond).alb_timer); | ||
3593 | |||
3594 | /* bond_alb_initialize must be called before the timer | 3653 | /* bond_alb_initialize must be called before the timer |
3595 | * is started. | 3654 | * is started. |
3596 | */ | 3655 | */ |
@@ -3599,44 +3658,31 @@ static int bond_open(struct net_device *bond_dev) | |||
3599 | return -1; | 3658 | return -1; |
3600 | } | 3659 | } |
3601 | 3660 | ||
3602 | init_timer(alb_timer); | 3661 | INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); |
3603 | alb_timer->expires = jiffies + 1; | 3662 | queue_delayed_work(bond->wq, &bond->alb_work, 0); |
3604 | alb_timer->data = (unsigned long)bond; | ||
3605 | alb_timer->function = (void *)&bond_alb_monitor; | ||
3606 | add_timer(alb_timer); | ||
3607 | } | 3663 | } |
3608 | 3664 | ||
3609 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3665 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ |
3610 | init_timer(mii_timer); | 3666 | INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); |
3611 | mii_timer->expires = jiffies + 1; | 3667 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
3612 | mii_timer->data = (unsigned long)bond_dev; | ||
3613 | mii_timer->function = (void *)&bond_mii_monitor; | ||
3614 | add_timer(mii_timer); | ||
3615 | } | 3668 | } |
3616 | 3669 | ||
3617 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | 3670 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
3618 | init_timer(arp_timer); | 3671 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) |
3619 | arp_timer->expires = jiffies + 1; | 3672 | INIT_DELAYED_WORK(&bond->arp_work, |
3620 | arp_timer->data = (unsigned long)bond_dev; | 3673 | bond_activebackup_arp_mon); |
3621 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { | 3674 | else |
3622 | arp_timer->function = (void *)&bond_activebackup_arp_mon; | 3675 | INIT_DELAYED_WORK(&bond->arp_work, |
3623 | } else { | 3676 | bond_loadbalance_arp_mon); |
3624 | arp_timer->function = (void *)&bond_loadbalance_arp_mon; | 3677 | |
3625 | } | 3678 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
3626 | if (bond->params.arp_validate) | 3679 | if (bond->params.arp_validate) |
3627 | bond_register_arp(bond); | 3680 | bond_register_arp(bond); |
3628 | |||
3629 | add_timer(arp_timer); | ||
3630 | } | 3681 | } |
3631 | 3682 | ||
3632 | if (bond->params.mode == BOND_MODE_8023AD) { | 3683 | if (bond->params.mode == BOND_MODE_8023AD) { |
3633 | struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer); | 3684 | INIT_DELAYED_WORK(&bond->ad_work, bond_alb_monitor); |
3634 | init_timer(ad_timer); | 3685 | queue_delayed_work(bond->wq, &bond->ad_work, 0); |
3635 | ad_timer->expires = jiffies + 1; | ||
3636 | ad_timer->data = (unsigned long)bond; | ||
3637 | ad_timer->function = (void *)&bond_3ad_state_machine_handler; | ||
3638 | add_timer(ad_timer); | ||
3639 | |||
3640 | /* register to receive LACPDUs */ | 3686 | /* register to receive LACPDUs */ |
3641 | bond_register_lacpdu(bond); | 3687 | bond_register_lacpdu(bond); |
3642 | } | 3688 | } |
@@ -3664,25 +3710,21 @@ static int bond_close(struct net_device *bond_dev) | |||
3664 | 3710 | ||
3665 | write_unlock_bh(&bond->lock); | 3711 | write_unlock_bh(&bond->lock); |
3666 | 3712 | ||
3667 | /* del_timer_sync must run without holding the bond->lock | ||
3668 | * because a running timer might be trying to hold it too | ||
3669 | */ | ||
3670 | |||
3671 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3713 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ |
3672 | del_timer_sync(&bond->mii_timer); | 3714 | cancel_delayed_work(&bond->mii_work); |
3673 | } | 3715 | } |
3674 | 3716 | ||
3675 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | 3717 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
3676 | del_timer_sync(&bond->arp_timer); | 3718 | cancel_delayed_work(&bond->arp_work); |
3677 | } | 3719 | } |
3678 | 3720 | ||
3679 | switch (bond->params.mode) { | 3721 | switch (bond->params.mode) { |
3680 | case BOND_MODE_8023AD: | 3722 | case BOND_MODE_8023AD: |
3681 | del_timer_sync(&(BOND_AD_INFO(bond).ad_timer)); | 3723 | cancel_delayed_work(&bond->ad_work); |
3682 | break; | 3724 | break; |
3683 | case BOND_MODE_TLB: | 3725 | case BOND_MODE_TLB: |
3684 | case BOND_MODE_ALB: | 3726 | case BOND_MODE_ALB: |
3685 | del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer)); | 3727 | cancel_delayed_work(&bond->alb_work); |
3686 | break; | 3728 | break; |
3687 | default: | 3729 | default: |
3688 | break; | 3730 | break; |
@@ -3779,13 +3821,13 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
3779 | if (mii->reg_num == 1) { | 3821 | if (mii->reg_num == 1) { |
3780 | struct bonding *bond = bond_dev->priv; | 3822 | struct bonding *bond = bond_dev->priv; |
3781 | mii->val_out = 0; | 3823 | mii->val_out = 0; |
3782 | read_lock_bh(&bond->lock); | 3824 | read_lock(&bond->lock); |
3783 | read_lock(&bond->curr_slave_lock); | 3825 | read_lock(&bond->curr_slave_lock); |
3784 | if (netif_carrier_ok(bond->dev)) { | 3826 | if (netif_carrier_ok(bond->dev)) { |
3785 | mii->val_out = BMSR_LSTATUS; | 3827 | mii->val_out = BMSR_LSTATUS; |
3786 | } | 3828 | } |
3787 | read_unlock(&bond->curr_slave_lock); | 3829 | read_unlock(&bond->curr_slave_lock); |
3788 | read_unlock_bh(&bond->lock); | 3830 | read_unlock(&bond->lock); |
3789 | } | 3831 | } |
3790 | 3832 | ||
3791 | return 0; | 3833 | return 0; |
@@ -4077,8 +4119,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev | |||
4077 | { | 4119 | { |
4078 | struct bonding *bond = bond_dev->priv; | 4120 | struct bonding *bond = bond_dev->priv; |
4079 | struct slave *slave, *start_at; | 4121 | struct slave *slave, *start_at; |
4080 | int i; | 4122 | int i, slave_no, res = 1; |
4081 | int res = 1; | ||
4082 | 4123 | ||
4083 | read_lock(&bond->lock); | 4124 | read_lock(&bond->lock); |
4084 | 4125 | ||
@@ -4086,29 +4127,29 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev | |||
4086 | goto out; | 4127 | goto out; |
4087 | } | 4128 | } |
4088 | 4129 | ||
4089 | read_lock(&bond->curr_slave_lock); | 4130 | /* |
4090 | slave = start_at = bond->curr_active_slave; | 4131 | * Concurrent TX may collide on rr_tx_counter; we accept that |
4091 | read_unlock(&bond->curr_slave_lock); | 4132 | * as being rare enough not to justify using an atomic op here |
4133 | */ | ||
4134 | slave_no = bond->rr_tx_counter++ % bond->slave_cnt; | ||
4092 | 4135 | ||
4093 | if (!slave) { | 4136 | bond_for_each_slave(bond, slave, i) { |
4094 | goto out; | 4137 | slave_no--; |
4138 | if (slave_no < 0) { | ||
4139 | break; | ||
4140 | } | ||
4095 | } | 4141 | } |
4096 | 4142 | ||
4143 | start_at = slave; | ||
4097 | bond_for_each_slave_from(bond, slave, i, start_at) { | 4144 | bond_for_each_slave_from(bond, slave, i, start_at) { |
4098 | if (IS_UP(slave->dev) && | 4145 | if (IS_UP(slave->dev) && |
4099 | (slave->link == BOND_LINK_UP) && | 4146 | (slave->link == BOND_LINK_UP) && |
4100 | (slave->state == BOND_STATE_ACTIVE)) { | 4147 | (slave->state == BOND_STATE_ACTIVE)) { |
4101 | res = bond_dev_queue_xmit(bond, skb, slave->dev); | 4148 | res = bond_dev_queue_xmit(bond, skb, slave->dev); |
4102 | |||
4103 | write_lock(&bond->curr_slave_lock); | ||
4104 | bond->curr_active_slave = slave->next; | ||
4105 | write_unlock(&bond->curr_slave_lock); | ||
4106 | |||
4107 | break; | 4149 | break; |
4108 | } | 4150 | } |
4109 | } | 4151 | } |
4110 | 4152 | ||
4111 | |||
4112 | out: | 4153 | out: |
4113 | if (res) { | 4154 | if (res) { |
4114 | /* no suitable interface, frame not sent */ | 4155 | /* no suitable interface, frame not sent */ |
@@ -4340,6 +4381,10 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
4340 | 4381 | ||
4341 | bond->params = *params; /* copy params struct */ | 4382 | bond->params = *params; /* copy params struct */ |
4342 | 4383 | ||
4384 | bond->wq = create_singlethread_workqueue(bond_dev->name); | ||
4385 | if (!bond->wq) | ||
4386 | return -ENOMEM; | ||
4387 | |||
4343 | /* Initialize pointers */ | 4388 | /* Initialize pointers */ |
4344 | bond->first_slave = NULL; | 4389 | bond->first_slave = NULL; |
4345 | bond->curr_active_slave = NULL; | 4390 | bond->curr_active_slave = NULL; |
@@ -4428,8 +4473,8 @@ static void bond_free_all(void) | |||
4428 | bond_mc_list_destroy(bond); | 4473 | bond_mc_list_destroy(bond); |
4429 | /* Release the bonded slaves */ | 4474 | /* Release the bonded slaves */ |
4430 | bond_release_all(bond_dev); | 4475 | bond_release_all(bond_dev); |
4431 | bond_deinit(bond_dev); | ||
4432 | unregister_netdevice(bond_dev); | 4476 | unregister_netdevice(bond_dev); |
4477 | bond_deinit(bond_dev); | ||
4433 | } | 4478 | } |
4434 | 4479 | ||
4435 | #ifdef CONFIG_PROC_FS | 4480 | #ifdef CONFIG_PROC_FS |
@@ -4826,10 +4871,32 @@ out_rtnl: | |||
4826 | return res; | 4871 | return res; |
4827 | } | 4872 | } |
4828 | 4873 | ||
4874 | static void bond_work_cancel_all(struct bonding *bond) | ||
4875 | { | ||
4876 | write_lock_bh(&bond->lock); | ||
4877 | bond->kill_timers = 1; | ||
4878 | write_unlock_bh(&bond->lock); | ||
4879 | |||
4880 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | ||
4881 | cancel_delayed_work(&bond->mii_work); | ||
4882 | |||
4883 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | ||
4884 | cancel_delayed_work(&bond->arp_work); | ||
4885 | |||
4886 | if (bond->params.mode == BOND_MODE_ALB && | ||
4887 | delayed_work_pending(&bond->alb_work)) | ||
4888 | cancel_delayed_work(&bond->alb_work); | ||
4889 | |||
4890 | if (bond->params.mode == BOND_MODE_8023AD && | ||
4891 | delayed_work_pending(&bond->ad_work)) | ||
4892 | cancel_delayed_work(&bond->ad_work); | ||
4893 | } | ||
4894 | |||
4829 | static int __init bonding_init(void) | 4895 | static int __init bonding_init(void) |
4830 | { | 4896 | { |
4831 | int i; | 4897 | int i; |
4832 | int res; | 4898 | int res; |
4899 | struct bonding *bond, *nxt; | ||
4833 | 4900 | ||
4834 | printk(KERN_INFO "%s", version); | 4901 | printk(KERN_INFO "%s", version); |
4835 | 4902 | ||
@@ -4856,6 +4923,11 @@ static int __init bonding_init(void) | |||
4856 | 4923 | ||
4857 | goto out; | 4924 | goto out; |
4858 | err: | 4925 | err: |
4926 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { | ||
4927 | bond_work_cancel_all(bond); | ||
4928 | destroy_workqueue(bond->wq); | ||
4929 | } | ||
4930 | |||
4859 | rtnl_lock(); | 4931 | rtnl_lock(); |
4860 | bond_free_all(); | 4932 | bond_free_all(); |
4861 | bond_destroy_sysfs(); | 4933 | bond_destroy_sysfs(); |