aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
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/net/bonding/bond_main.c
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/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c147
1 files changed, 79 insertions, 68 deletions
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();