aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2007-10-17 20:37:45 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-23 20:32:00 -0400
commit1b76b31693d4a6088dec104ff6a6ead54081a3c2 (patch)
treed6353be6b4654ec85ab6cfe42d2c78fac9a755c8 /drivers
parent15df5806c6fc94e607632bba70328194905e988f (diff)
Convert bonding timers to workqueues
Convert bonding timers to workqueues. This converts the various monitor functions to run in periodic work queues instead of timers. This patch introduces the framework and convers the calls, but does not resolve various locking issues, and does not stand alone. 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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bonding/bond_3ad.c6
-rw-r--r--drivers/net/bonding/bond_3ad.h2
-rw-r--r--drivers/net/bonding/bond_alb.c6
-rw-r--r--drivers/net/bonding/bond_alb.h2
-rw-r--r--drivers/net/bonding/bond_main.c147
-rw-r--r--drivers/net/bonding/bond_sysfs.c63
-rw-r--r--drivers/net/bonding/bonding.h13
7 files changed, 117 insertions, 122 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 084f0292ea6e..cb3c6faa7888 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2076,8 +2076,10 @@ void bond_3ad_unbind_slave(struct slave *slave)
2076 * times out, and it selects an aggregator for the ports that are yet not 2076 * times out, and it selects an aggregator for the ports that are yet not
2077 * related to any aggregator, and selects the active aggregator for a bond. 2077 * related to any aggregator, and selects the active aggregator for a bond.
2078 */ 2078 */
2079void bond_3ad_state_machine_handler(struct bonding *bond) 2079void bond_3ad_state_machine_handler(struct work_struct *work)
2080{ 2080{
2081 struct bonding *bond = container_of(work, struct bonding,
2082 ad_work.work);
2081 struct port *port; 2083 struct port *port;
2082 struct aggregator *aggregator; 2084 struct aggregator *aggregator;
2083 2085
@@ -2128,7 +2130,7 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
2128 } 2130 }
2129 2131
2130re_arm: 2132re_arm:
2131 mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + ad_delta_in_ticks); 2133 queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks);
2132out: 2134out:
2133 read_unlock(&bond->lock); 2135 read_unlock(&bond->lock);
2134} 2136}
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index f16557264944..b5ee45f6d55a 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -276,7 +276,7 @@ struct ad_slave_info {
276void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast); 276void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast);
277int bond_3ad_bind_slave(struct slave *slave); 277int bond_3ad_bind_slave(struct slave *slave);
278void bond_3ad_unbind_slave(struct slave *slave); 278void bond_3ad_unbind_slave(struct slave *slave);
279void bond_3ad_state_machine_handler(struct bonding *bond); 279void bond_3ad_state_machine_handler(struct work_struct *);
280void bond_3ad_adapter_speed_changed(struct slave *slave); 280void bond_3ad_adapter_speed_changed(struct slave *slave);
281void bond_3ad_adapter_duplex_changed(struct slave *slave); 281void bond_3ad_adapter_duplex_changed(struct slave *slave);
282void bond_3ad_handle_link_change(struct slave *slave, char link); 282void bond_3ad_handle_link_change(struct slave *slave, char link);
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index aea2217c56eb..eb320c3cbdde 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1375,8 +1375,10 @@ out:
1375 return 0; 1375 return 0;
1376} 1376}
1377 1377
1378void bond_alb_monitor(struct bonding *bond) 1378void bond_alb_monitor(struct work_struct *work)
1379{ 1379{
1380 struct bonding *bond = container_of(work, struct bonding,
1381 alb_work.work);
1380 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 1382 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
1381 struct slave *slave; 1383 struct slave *slave;
1382 int i; 1384 int i;
@@ -1479,7 +1481,7 @@ void bond_alb_monitor(struct bonding *bond)
1479 } 1481 }
1480 1482
1481re_arm: 1483re_arm:
1482 mod_timer(&(bond_info->alb_timer), jiffies + alb_delta_in_ticks); 1484 queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks);
1483out: 1485out:
1484 read_unlock(&bond->lock); 1486 read_unlock(&bond->lock);
1485} 1487}
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index fd8726429890..50968f8196cf 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -125,7 +125,7 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
125void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link); 125void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
126void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave); 126void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
127int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev); 127int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
128void bond_alb_monitor(struct bonding *bond); 128void bond_alb_monitor(struct work_struct *);
129int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr); 129int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
130void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id); 130void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
131#endif /* __BOND_ALB_H__ */ 131#endif /* __BOND_ALB_H__ */
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6f85cc31f8a2..ed361d62d702 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2089,9 +2089,10 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
2089/*-------------------------------- Monitoring -------------------------------*/ 2089/*-------------------------------- Monitoring -------------------------------*/
2090 2090
2091/* this function is called regularly to monitor each slave's link. */ 2091/* this function is called regularly to monitor each slave's link. */
2092void bond_mii_monitor(struct net_device *bond_dev) 2092void bond_mii_monitor(struct work_struct *work)
2093{ 2093{
2094 struct bonding *bond = bond_dev->priv; 2094 struct bonding *bond = container_of(work, struct bonding,
2095 mii_work.work);
2095 struct slave *slave, *oldcurrent; 2096 struct slave *slave, *oldcurrent;
2096 int do_failover = 0; 2097 int do_failover = 0;
2097 int delta_in_ticks; 2098 int delta_in_ticks;
@@ -2156,7 +2157,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
2156 ": %s: link status down for %s " 2157 ": %s: link status down for %s "
2157 "interface %s, disabling it in " 2158 "interface %s, disabling it in "
2158 "%d ms.\n", 2159 "%d ms.\n",
2159 bond_dev->name, 2160 bond->dev->name,
2160 IS_UP(slave_dev) 2161 IS_UP(slave_dev)
2161 ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) 2162 ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP)
2162 ? ((slave == oldcurrent) 2163 ? ((slave == oldcurrent)
@@ -2189,7 +2190,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
2189 ": %s: link status definitely " 2190 ": %s: link status definitely "
2190 "down for interface %s, " 2191 "down for interface %s, "
2191 "disabling it\n", 2192 "disabling it\n",
2192 bond_dev->name, 2193 bond->dev->name,
2193 slave_dev->name); 2194 slave_dev->name);
2194 2195
2195 /* notify ad that the link status has changed */ 2196 /* notify ad that the link status has changed */
@@ -2215,7 +2216,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
2215 printk(KERN_INFO DRV_NAME 2216 printk(KERN_INFO DRV_NAME
2216 ": %s: link status up again after %d " 2217 ": %s: link status up again after %d "
2217 "ms for interface %s.\n", 2218 "ms for interface %s.\n",
2218 bond_dev->name, 2219 bond->dev->name,
2219 (bond->params.downdelay - slave->delay) * bond->params.miimon, 2220 (bond->params.downdelay - slave->delay) * bond->params.miimon,
2220 slave_dev->name); 2221 slave_dev->name);
2221 } 2222 }
@@ -2235,7 +2236,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
2235 ": %s: link status up for " 2236 ": %s: link status up for "
2236 "interface %s, enabling it " 2237 "interface %s, enabling it "
2237 "in %d ms.\n", 2238 "in %d ms.\n",
2238 bond_dev->name, 2239 bond->dev->name,
2239 slave_dev->name, 2240 slave_dev->name,
2240 bond->params.updelay * bond->params.miimon); 2241 bond->params.updelay * bond->params.miimon);
2241 } 2242 }
@@ -2251,7 +2252,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
2251 printk(KERN_INFO DRV_NAME 2252 printk(KERN_INFO DRV_NAME
2252 ": %s: link status down again after %d " 2253 ": %s: link status down again after %d "
2253 "ms for interface %s.\n", 2254 "ms for interface %s.\n",
2254 bond_dev->name, 2255 bond->dev->name,
2255 (bond->params.updelay - slave->delay) * bond->params.miimon, 2256 (bond->params.updelay - slave->delay) * bond->params.miimon,
2256 slave_dev->name); 2257 slave_dev->name);
2257 } else { 2258 } else {
@@ -2275,7 +2276,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
2275 printk(KERN_INFO DRV_NAME 2276 printk(KERN_INFO DRV_NAME
2276 ": %s: link status definitely " 2277 ": %s: link status definitely "
2277 "up for interface %s.\n", 2278 "up for interface %s.\n",
2278 bond_dev->name, 2279 bond->dev->name,
2279 slave_dev->name); 2280 slave_dev->name);
2280 2281
2281 /* notify ad that the link status has changed */ 2282 /* notify ad that the link status has changed */
@@ -2301,7 +2302,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
2301 /* Should not happen */ 2302 /* Should not happen */
2302 printk(KERN_ERR DRV_NAME 2303 printk(KERN_ERR DRV_NAME
2303 ": %s: Error: %s Illegal value (link=%d)\n", 2304 ": %s: Error: %s Illegal value (link=%d)\n",
2304 bond_dev->name, 2305 bond->dev->name,
2305 slave->dev->name, 2306 slave->dev->name,
2306 slave->link); 2307 slave->link);
2307 goto out; 2308 goto out;
@@ -2331,9 +2332,8 @@ void bond_mii_monitor(struct net_device *bond_dev)
2331 bond_set_carrier(bond); 2332 bond_set_carrier(bond);
2332 2333
2333re_arm: 2334re_arm:
2334 if (bond->params.miimon) { 2335 if (bond->params.miimon)
2335 mod_timer(&bond->mii_timer, jiffies + delta_in_ticks); 2336 queue_delayed_work(bond->wq, &bond->mii_work, delta_in_ticks);
2336 }
2337out: 2337out:
2338 read_unlock(&bond->lock); 2338 read_unlock(&bond->lock);
2339} 2339}
@@ -2636,9 +2636,10 @@ out:
2636 * arp is transmitted to generate traffic. see activebackup_arp_monitor for 2636 * arp is transmitted to generate traffic. see activebackup_arp_monitor for
2637 * arp monitoring in active backup mode. 2637 * arp monitoring in active backup mode.
2638 */ 2638 */
2639void bond_loadbalance_arp_mon(struct net_device *bond_dev) 2639void bond_loadbalance_arp_mon(struct work_struct *work)
2640{ 2640{
2641 struct bonding *bond = bond_dev->priv; 2641 struct bonding *bond = container_of(work, struct bonding,
2642 arp_work.work);
2642 struct slave *slave, *oldcurrent; 2643 struct slave *slave, *oldcurrent;
2643 int do_failover = 0; 2644 int do_failover = 0;
2644 int delta_in_ticks; 2645 int delta_in_ticks;
@@ -2685,13 +2686,13 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
2685 printk(KERN_INFO DRV_NAME 2686 printk(KERN_INFO DRV_NAME
2686 ": %s: link status definitely " 2687 ": %s: link status definitely "
2687 "up for interface %s, ", 2688 "up for interface %s, ",
2688 bond_dev->name, 2689 bond->dev->name,
2689 slave->dev->name); 2690 slave->dev->name);
2690 do_failover = 1; 2691 do_failover = 1;
2691 } else { 2692 } else {
2692 printk(KERN_INFO DRV_NAME 2693 printk(KERN_INFO DRV_NAME
2693 ": %s: interface %s is now up\n", 2694 ": %s: interface %s is now up\n",
2694 bond_dev->name, 2695 bond->dev->name,
2695 slave->dev->name); 2696 slave->dev->name);
2696 } 2697 }
2697 } 2698 }
@@ -2715,7 +2716,7 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
2715 2716
2716 printk(KERN_INFO DRV_NAME 2717 printk(KERN_INFO DRV_NAME
2717 ": %s: interface %s is now down.\n", 2718 ": %s: interface %s is now down.\n",
2718 bond_dev->name, 2719 bond->dev->name,
2719 slave->dev->name); 2720 slave->dev->name);
2720 2721
2721 if (slave == oldcurrent) { 2722 if (slave == oldcurrent) {
@@ -2745,9 +2746,8 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
2745 } 2746 }
2746 2747
2747re_arm: 2748re_arm:
2748 if (bond->params.arp_interval) { 2749 if (bond->params.arp_interval)
2749 mod_timer(&bond->arp_timer, jiffies + delta_in_ticks); 2750 queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
2750 }
2751out: 2751out:
2752 read_unlock(&bond->lock); 2752 read_unlock(&bond->lock);
2753} 2753}
@@ -2767,9 +2767,10 @@ out:
2767 * may have received. 2767 * may have received.
2768 * see loadbalance_arp_monitor for arp monitoring in load balancing mode 2768 * see loadbalance_arp_monitor for arp monitoring in load balancing mode
2769 */ 2769 */
2770void bond_activebackup_arp_mon(struct net_device *bond_dev) 2770void bond_activebackup_arp_mon(struct work_struct *work)
2771{ 2771{
2772 struct bonding *bond = bond_dev->priv; 2772 struct bonding *bond = container_of(work, struct bonding,
2773 arp_work.work);
2773 struct slave *slave; 2774 struct slave *slave;
2774 int delta_in_ticks; 2775 int delta_in_ticks;
2775 int i; 2776 int i;
@@ -2821,14 +2822,14 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2821 printk(KERN_INFO DRV_NAME 2822 printk(KERN_INFO DRV_NAME
2822 ": %s: %s is up and now the " 2823 ": %s: %s is up and now the "
2823 "active interface\n", 2824 "active interface\n",
2824 bond_dev->name, 2825 bond->dev->name,
2825 slave->dev->name); 2826 slave->dev->name);
2826 netif_carrier_on(bond->dev); 2827 netif_carrier_on(bond->dev);
2827 } else { 2828 } else {
2828 printk(KERN_INFO DRV_NAME 2829 printk(KERN_INFO DRV_NAME
2829 ": %s: backup interface %s is " 2830 ": %s: backup interface %s is "
2830 "now up\n", 2831 "now up\n",
2831 bond_dev->name, 2832 bond->dev->name,
2832 slave->dev->name); 2833 slave->dev->name);
2833 } 2834 }
2834 2835
@@ -2864,7 +2865,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2864 2865
2865 printk(KERN_INFO DRV_NAME 2866 printk(KERN_INFO DRV_NAME
2866 ": %s: backup interface %s is now down\n", 2867 ": %s: backup interface %s is now down\n",
2867 bond_dev->name, 2868 bond->dev->name,
2868 slave->dev->name); 2869 slave->dev->name);
2869 } else { 2870 } else {
2870 read_unlock(&bond->curr_slave_lock); 2871 read_unlock(&bond->curr_slave_lock);
@@ -2899,7 +2900,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2899 printk(KERN_INFO DRV_NAME 2900 printk(KERN_INFO DRV_NAME
2900 ": %s: link status down for active interface " 2901 ": %s: link status down for active interface "
2901 "%s, disabling it\n", 2902 "%s, disabling it\n",
2902 bond_dev->name, 2903 bond->dev->name,
2903 slave->dev->name); 2904 slave->dev->name);
2904 2905
2905 write_lock(&bond->curr_slave_lock); 2906 write_lock(&bond->curr_slave_lock);
@@ -2921,7 +2922,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2921 printk(KERN_INFO DRV_NAME 2922 printk(KERN_INFO DRV_NAME
2922 ": %s: changing from interface %s to primary " 2923 ": %s: changing from interface %s to primary "
2923 "interface %s\n", 2924 "interface %s\n",
2924 bond_dev->name, 2925 bond->dev->name,
2925 slave->dev->name, 2926 slave->dev->name,
2926 bond->primary_slave->dev->name); 2927 bond->primary_slave->dev->name);
2927 2928
@@ -2985,7 +2986,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2985 printk(KERN_INFO DRV_NAME 2986 printk(KERN_INFO DRV_NAME
2986 ": %s: backup interface %s is " 2987 ": %s: backup interface %s is "
2987 "now down.\n", 2988 "now down.\n",
2988 bond_dev->name, 2989 bond->dev->name,
2989 slave->dev->name); 2990 slave->dev->name);
2990 } 2991 }
2991 } 2992 }
@@ -2994,7 +2995,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2994 2995
2995re_arm: 2996re_arm:
2996 if (bond->params.arp_interval) { 2997 if (bond->params.arp_interval) {
2997 mod_timer(&bond->arp_timer, jiffies + delta_in_ticks); 2998 queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
2998 } 2999 }
2999out: 3000out:
3000 read_unlock(&bond->lock); 3001 read_unlock(&bond->lock);
@@ -3582,15 +3583,11 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
3582static int bond_open(struct net_device *bond_dev) 3583static int bond_open(struct net_device *bond_dev)
3583{ 3584{
3584 struct bonding *bond = bond_dev->priv; 3585 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 3586
3588 bond->kill_timers = 0; 3587 bond->kill_timers = 0;
3589 3588
3590 if ((bond->params.mode == BOND_MODE_TLB) || 3589 if ((bond->params.mode == BOND_MODE_TLB) ||
3591 (bond->params.mode == BOND_MODE_ALB)) { 3590 (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 3591 /* bond_alb_initialize must be called before the timer
3595 * is started. 3592 * is started.
3596 */ 3593 */
@@ -3599,44 +3596,31 @@ static int bond_open(struct net_device *bond_dev)
3599 return -1; 3596 return -1;
3600 } 3597 }
3601 3598
3602 init_timer(alb_timer); 3599 INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
3603 alb_timer->expires = jiffies + 1; 3600 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 } 3601 }
3608 3602
3609 if (bond->params.miimon) { /* link check interval, in milliseconds. */ 3603 if (bond->params.miimon) { /* link check interval, in milliseconds. */
3610 init_timer(mii_timer); 3604 INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
3611 mii_timer->expires = jiffies + 1; 3605 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 } 3606 }
3616 3607
3617 if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ 3608 if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
3618 init_timer(arp_timer); 3609 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
3619 arp_timer->expires = jiffies + 1; 3610 INIT_DELAYED_WORK(&bond->arp_work,
3620 arp_timer->data = (unsigned long)bond_dev; 3611 bond_activebackup_arp_mon);
3621 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { 3612 else
3622 arp_timer->function = (void *)&bond_activebackup_arp_mon; 3613 INIT_DELAYED_WORK(&bond->arp_work,
3623 } else { 3614 bond_loadbalance_arp_mon);
3624 arp_timer->function = (void *)&bond_loadbalance_arp_mon; 3615
3625 } 3616 queue_delayed_work(bond->wq, &bond->arp_work, 0);
3626 if (bond->params.arp_validate) 3617 if (bond->params.arp_validate)
3627 bond_register_arp(bond); 3618 bond_register_arp(bond);
3628
3629 add_timer(arp_timer);
3630 } 3619 }
3631 3620
3632 if (bond->params.mode == BOND_MODE_8023AD) { 3621 if (bond->params.mode == BOND_MODE_8023AD) {
3633 struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer); 3622 INIT_DELAYED_WORK(&bond->ad_work, bond_alb_monitor);
3634 init_timer(ad_timer); 3623 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 */ 3624 /* register to receive LACPDUs */
3641 bond_register_lacpdu(bond); 3625 bond_register_lacpdu(bond);
3642 } 3626 }
@@ -3664,25 +3648,21 @@ static int bond_close(struct net_device *bond_dev)
3664 3648
3665 write_unlock_bh(&bond->lock); 3649 write_unlock_bh(&bond->lock);
3666 3650
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. */ 3651 if (bond->params.miimon) { /* link check interval, in milliseconds. */
3672 del_timer_sync(&bond->mii_timer); 3652 cancel_delayed_work(&bond->mii_work);
3673 } 3653 }
3674 3654
3675 if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ 3655 if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
3676 del_timer_sync(&bond->arp_timer); 3656 cancel_delayed_work(&bond->arp_work);
3677 } 3657 }
3678 3658
3679 switch (bond->params.mode) { 3659 switch (bond->params.mode) {
3680 case BOND_MODE_8023AD: 3660 case BOND_MODE_8023AD:
3681 del_timer_sync(&(BOND_AD_INFO(bond).ad_timer)); 3661 cancel_delayed_work(&bond->ad_work);
3682 break; 3662 break;
3683 case BOND_MODE_TLB: 3663 case BOND_MODE_TLB:
3684 case BOND_MODE_ALB: 3664 case BOND_MODE_ALB:
3685 del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer)); 3665 cancel_delayed_work(&bond->alb_work);
3686 break; 3666 break;
3687 default: 3667 default:
3688 break; 3668 break;
@@ -4340,6 +4320,10 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
4340 4320
4341 bond->params = *params; /* copy params struct */ 4321 bond->params = *params; /* copy params struct */
4342 4322
4323 bond->wq = create_singlethread_workqueue(bond_dev->name);
4324 if (!bond->wq)
4325 return -ENOMEM;
4326
4343 /* Initialize pointers */ 4327 /* Initialize pointers */
4344 bond->first_slave = NULL; 4328 bond->first_slave = NULL;
4345 bond->curr_active_slave = NULL; 4329 bond->curr_active_slave = NULL;
@@ -4826,10 +4810,32 @@ out_rtnl:
4826 return res; 4810 return res;
4827} 4811}
4828 4812
4813static void bond_work_cancel_all(struct bonding *bond)
4814{
4815 write_lock_bh(&bond->lock);
4816 bond->kill_timers = 1;
4817 write_unlock_bh(&bond->lock);
4818
4819 if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
4820 cancel_delayed_work(&bond->mii_work);
4821
4822 if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
4823 cancel_delayed_work(&bond->arp_work);
4824
4825 if (bond->params.mode == BOND_MODE_ALB &&
4826 delayed_work_pending(&bond->alb_work))
4827 cancel_delayed_work(&bond->alb_work);
4828
4829 if (bond->params.mode == BOND_MODE_8023AD &&
4830 delayed_work_pending(&bond->ad_work))
4831 cancel_delayed_work(&bond->ad_work);
4832}
4833
4829static int __init bonding_init(void) 4834static int __init bonding_init(void)
4830{ 4835{
4831 int i; 4836 int i;
4832 int res; 4837 int res;
4838 struct bonding *bond, *nxt;
4833 4839
4834 printk(KERN_INFO "%s", version); 4840 printk(KERN_INFO "%s", version);
4835 4841
@@ -4856,6 +4862,11 @@ static int __init bonding_init(void)
4856 4862
4857 goto out; 4863 goto out;
4858err: 4864err:
4865 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
4866 bond_work_cancel_all(bond);
4867 destroy_workqueue(bond->wq);
4868 }
4869
4859 rtnl_lock(); 4870 rtnl_lock();
4860 bond_free_all(); 4871 bond_free_all();
4861 bond_destroy_sysfs(); 4872 bond_destroy_sysfs();
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 855dc10ffa1b..19d970e0cbb8 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -662,12 +662,9 @@ static ssize_t bonding_store_arp_interval(struct device *d,
662 "%s Disabling MII monitoring.\n", 662 "%s Disabling MII monitoring.\n",
663 bond->dev->name, bond->dev->name); 663 bond->dev->name, bond->dev->name);
664 bond->params.miimon = 0; 664 bond->params.miimon = 0;
665 /* Kill MII timer, else it brings bond's link down */ 665 if (delayed_work_pending(&bond->mii_work)) {
666 if (bond->arp_timer.function) { 666 cancel_delayed_work(&bond->mii_work);
667 printk(KERN_INFO DRV_NAME 667 flush_workqueue(bond->wq);
668 ": %s: Kill MII timer, else it brings bond's link down...\n",
669 bond->dev->name);
670 del_timer_sync(&bond->mii_timer);
671 } 668 }
672 } 669 }
673 if (!bond->params.arp_targets[0]) { 670 if (!bond->params.arp_targets[0]) {
@@ -682,25 +679,15 @@ static ssize_t bonding_store_arp_interval(struct device *d,
682 * timer will get fired off when the open function 679 * timer will get fired off when the open function
683 * is called. 680 * is called.
684 */ 681 */
685 if (bond->arp_timer.function) { 682 if (!delayed_work_pending(&bond->arp_work)) {
686 /* The timer's already set up, so fire it off */ 683 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
687 mod_timer(&bond->arp_timer, jiffies + 1); 684 INIT_DELAYED_WORK(&bond->arp_work,
688 } else { 685 bond_activebackup_arp_mon);
689 /* Set up the timer. */ 686 else
690 init_timer(&bond->arp_timer); 687 INIT_DELAYED_WORK(&bond->arp_work,
691 bond->arp_timer.expires = jiffies + 1; 688 bond_loadbalance_arp_mon);
692 bond->arp_timer.data = 689
693 (unsigned long) bond->dev; 690 queue_delayed_work(bond->wq, &bond->arp_work, 0);
694 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
695 bond->arp_timer.function =
696 (void *)
697 &bond_activebackup_arp_mon;
698 } else {
699 bond->arp_timer.function =
700 (void *)
701 &bond_loadbalance_arp_mon;
702 }
703 add_timer(&bond->arp_timer);
704 } 691 }
705 } 692 }
706 693
@@ -1056,12 +1043,9 @@ static ssize_t bonding_store_miimon(struct device *d,
1056 bond->params.arp_validate = 1043 bond->params.arp_validate =
1057 BOND_ARP_VALIDATE_NONE; 1044 BOND_ARP_VALIDATE_NONE;
1058 } 1045 }
1059 /* Kill ARP timer, else it brings bond's link down */ 1046 if (delayed_work_pending(&bond->arp_work)) {
1060 if (bond->mii_timer.function) { 1047 cancel_delayed_work(&bond->arp_work);
1061 printk(KERN_INFO DRV_NAME 1048 flush_workqueue(bond->wq);
1062 ": %s: Kill ARP timer, else it brings bond's link down...\n",
1063 bond->dev->name);
1064 del_timer_sync(&bond->arp_timer);
1065 } 1049 }
1066 } 1050 }
1067 1051
@@ -1071,18 +1055,11 @@ static ssize_t bonding_store_miimon(struct device *d,
1071 * timer will get fired off when the open function 1055 * timer will get fired off when the open function
1072 * is called. 1056 * is called.
1073 */ 1057 */
1074 if (bond->mii_timer.function) { 1058 if (!delayed_work_pending(&bond->mii_work)) {
1075 /* The timer's already set up, so fire it off */ 1059 INIT_DELAYED_WORK(&bond->mii_work,
1076 mod_timer(&bond->mii_timer, jiffies + 1); 1060 bond_mii_monitor);
1077 } else { 1061 queue_delayed_work(bond->wq,
1078 /* Set up the timer. */ 1062 &bond->mii_work, 0);
1079 init_timer(&bond->mii_timer);
1080 bond->mii_timer.expires = jiffies + 1;
1081 bond->mii_timer.data =
1082 (unsigned long) bond->dev;
1083 bond->mii_timer.function =
1084 (void *) &bond_mii_monitor;
1085 add_timer(&bond->mii_timer);
1086 } 1063 }
1087 } 1064 }
1088 } 1065 }
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index b8180600a309..a8f2384f550d 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -184,8 +184,6 @@ struct bonding {
184 s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ 184 s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
185 rwlock_t lock; 185 rwlock_t lock;
186 rwlock_t curr_slave_lock; 186 rwlock_t curr_slave_lock;
187 struct timer_list mii_timer;
188 struct timer_list arp_timer;
189 s8 kill_timers; 187 s8 kill_timers;
190 s8 send_grat_arp; 188 s8 send_grat_arp;
191 s8 setup_by_slave; 189 s8 setup_by_slave;
@@ -205,6 +203,11 @@ struct bonding {
205 struct list_head vlan_list; 203 struct list_head vlan_list;
206 struct vlan_group *vlgrp; 204 struct vlan_group *vlgrp;
207 struct packet_type arp_mon_pt; 205 struct packet_type arp_mon_pt;
206 struct workqueue_struct *wq;
207 struct delayed_work mii_work;
208 struct delayed_work arp_work;
209 struct delayed_work alb_work;
210 struct delayed_work ad_work;
208}; 211};
209 212
210/** 213/**
@@ -307,9 +310,9 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
307void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave); 310void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
308int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); 311int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
309int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); 312int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
310void bond_mii_monitor(struct net_device *bond_dev); 313void bond_mii_monitor(struct work_struct *);
311void bond_loadbalance_arp_mon(struct net_device *bond_dev); 314void bond_loadbalance_arp_mon(struct work_struct *);
312void bond_activebackup_arp_mon(struct net_device *bond_dev); 315void bond_activebackup_arp_mon(struct work_struct *);
313void bond_set_mode_ops(struct bonding *bond, int mode); 316void bond_set_mode_ops(struct bonding *bond, int mode);
314int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl); 317int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
315void bond_select_active_slave(struct bonding *bond); 318void bond_select_active_slave(struct bonding *bond);