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>

authored by Jay Vosburgh and committed by Jeff Garzik 1b76b316 15df5806

+117 -122
+4 -2
drivers/net/bonding/bond_3ad.c
··· 2076 2076 * times out, and it selects an aggregator for the ports that are yet not 2077 2077 * related to any aggregator, and selects the active aggregator for a bond. 2078 2078 */ 2079 - void bond_3ad_state_machine_handler(struct bonding *bond) 2079 + void 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 2083 struct port *port; 2082 2084 struct aggregator *aggregator; 2083 2085 ··· 2130 2128 } 2131 2129 2132 2130 re_arm: 2133 - mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + ad_delta_in_ticks); 2131 + queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); 2134 2132 out: 2135 2133 read_unlock(&bond->lock); 2136 2134 }
+1 -1
drivers/net/bonding/bond_3ad.h
··· 276 276 void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast); 277 277 int bond_3ad_bind_slave(struct slave *slave); 278 278 void bond_3ad_unbind_slave(struct slave *slave); 279 - void bond_3ad_state_machine_handler(struct bonding *bond); 279 + void bond_3ad_state_machine_handler(struct work_struct *); 280 280 void bond_3ad_adapter_speed_changed(struct slave *slave); 281 281 void bond_3ad_adapter_duplex_changed(struct slave *slave); 282 282 void bond_3ad_handle_link_change(struct slave *slave, char link);
+4 -2
drivers/net/bonding/bond_alb.c
··· 1375 1375 return 0; 1376 1376 } 1377 1377 1378 - void bond_alb_monitor(struct bonding *bond) 1378 + void bond_alb_monitor(struct work_struct *work) 1379 1379 { 1380 + struct bonding *bond = container_of(work, struct bonding, 1381 + alb_work.work); 1380 1382 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 1381 1383 struct slave *slave; 1382 1384 int i; ··· 1481 1479 } 1482 1480 1483 1481 re_arm: 1484 - mod_timer(&(bond_info->alb_timer), jiffies + alb_delta_in_ticks); 1482 + queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks); 1485 1483 out: 1486 1484 read_unlock(&bond->lock); 1487 1485 }
+1 -1
drivers/net/bonding/bond_alb.h
··· 125 125 void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link); 126 126 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave); 127 127 int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev); 128 - void bond_alb_monitor(struct bonding *bond); 128 + void bond_alb_monitor(struct work_struct *); 129 129 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr); 130 130 void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id); 131 131 #endif /* __BOND_ALB_H__ */
+79 -68
drivers/net/bonding/bond_main.c
··· 2089 2089 /*-------------------------------- Monitoring -------------------------------*/ 2090 2090 2091 2091 /* this function is called regularly to monitor each slave's link. */ 2092 - void bond_mii_monitor(struct net_device *bond_dev) 2092 + void 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 2096 struct slave *slave, *oldcurrent; 2096 2097 int do_failover = 0; 2097 2098 int delta_in_ticks; ··· 2157 2156 ": %s: link status down for %s " 2158 2157 "interface %s, disabling it in " 2159 2158 "%d ms.\n", 2160 - bond_dev->name, 2159 + bond->dev->name, 2161 2160 IS_UP(slave_dev) 2162 2161 ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) 2163 2162 ? ((slave == oldcurrent) ··· 2190 2189 ": %s: link status definitely " 2191 2190 "down for interface %s, " 2192 2191 "disabling it\n", 2193 - bond_dev->name, 2192 + bond->dev->name, 2194 2193 slave_dev->name); 2195 2194 2196 2195 /* notify ad that the link status has changed */ ··· 2216 2215 printk(KERN_INFO DRV_NAME 2217 2216 ": %s: link status up again after %d " 2218 2217 "ms for interface %s.\n", 2219 - bond_dev->name, 2218 + bond->dev->name, 2220 2219 (bond->params.downdelay - slave->delay) * bond->params.miimon, 2221 2220 slave_dev->name); 2222 2221 } ··· 2236 2235 ": %s: link status up for " 2237 2236 "interface %s, enabling it " 2238 2237 "in %d ms.\n", 2239 - bond_dev->name, 2238 + bond->dev->name, 2240 2239 slave_dev->name, 2241 2240 bond->params.updelay * bond->params.miimon); 2242 2241 } ··· 2252 2251 printk(KERN_INFO DRV_NAME 2253 2252 ": %s: link status down again after %d " 2254 2253 "ms for interface %s.\n", 2255 - bond_dev->name, 2254 + bond->dev->name, 2256 2255 (bond->params.updelay - slave->delay) * bond->params.miimon, 2257 2256 slave_dev->name); 2258 2257 } else { ··· 2276 2275 printk(KERN_INFO DRV_NAME 2277 2276 ": %s: link status definitely " 2278 2277 "up for interface %s.\n", 2279 - bond_dev->name, 2278 + bond->dev->name, 2280 2279 slave_dev->name); 2281 2280 2282 2281 /* notify ad that the link status has changed */ ··· 2302 2301 /* Should not happen */ 2303 2302 printk(KERN_ERR DRV_NAME 2304 2303 ": %s: Error: %s Illegal value (link=%d)\n", 2305 - bond_dev->name, 2304 + bond->dev->name, 2306 2305 slave->dev->name, 2307 2306 slave->link); 2308 2307 goto out; ··· 2332 2331 bond_set_carrier(bond); 2333 2332 2334 2333 re_arm: 2335 - if (bond->params.miimon) { 2336 - mod_timer(&bond->mii_timer, jiffies + delta_in_ticks); 2337 - } 2334 + if (bond->params.miimon) 2335 + queue_delayed_work(bond->wq, &bond->mii_work, delta_in_ticks); 2338 2336 out: 2339 2337 read_unlock(&bond->lock); 2340 2338 } ··· 2636 2636 * arp is transmitted to generate traffic. see activebackup_arp_monitor for 2637 2637 * arp monitoring in active backup mode. 2638 2638 */ 2639 - void bond_loadbalance_arp_mon(struct net_device *bond_dev) 2639 + void 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 2643 struct slave *slave, *oldcurrent; 2643 2644 int do_failover = 0; 2644 2645 int delta_in_ticks; ··· 2686 2685 printk(KERN_INFO DRV_NAME 2687 2686 ": %s: link status definitely " 2688 2687 "up for interface %s, ", 2689 - bond_dev->name, 2688 + bond->dev->name, 2690 2689 slave->dev->name); 2691 2690 do_failover = 1; 2692 2691 } else { 2693 2692 printk(KERN_INFO DRV_NAME 2694 2693 ": %s: interface %s is now up\n", 2695 - bond_dev->name, 2694 + bond->dev->name, 2696 2695 slave->dev->name); 2697 2696 } 2698 2697 } ··· 2716 2715 2717 2716 printk(KERN_INFO DRV_NAME 2718 2717 ": %s: interface %s is now down.\n", 2719 - bond_dev->name, 2718 + bond->dev->name, 2720 2719 slave->dev->name); 2721 2720 2722 2721 if (slave == oldcurrent) { ··· 2746 2745 } 2747 2746 2748 2747 re_arm: 2749 - if (bond->params.arp_interval) { 2750 - mod_timer(&bond->arp_timer, jiffies + delta_in_ticks); 2751 - } 2748 + if (bond->params.arp_interval) 2749 + queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); 2752 2750 out: 2753 2751 read_unlock(&bond->lock); 2754 2752 } ··· 2767 2767 * may have received. 2768 2768 * see loadbalance_arp_monitor for arp monitoring in load balancing mode 2769 2769 */ 2770 - void bond_activebackup_arp_mon(struct net_device *bond_dev) 2770 + void 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 2774 struct slave *slave; 2774 2775 int delta_in_ticks; 2775 2776 int i; ··· 2822 2821 printk(KERN_INFO DRV_NAME 2823 2822 ": %s: %s is up and now the " 2824 2823 "active interface\n", 2825 - bond_dev->name, 2824 + bond->dev->name, 2826 2825 slave->dev->name); 2827 2826 netif_carrier_on(bond->dev); 2828 2827 } else { 2829 2828 printk(KERN_INFO DRV_NAME 2830 2829 ": %s: backup interface %s is " 2831 2830 "now up\n", 2832 - bond_dev->name, 2831 + bond->dev->name, 2833 2832 slave->dev->name); 2834 2833 } 2835 2834 ··· 2865 2864 2866 2865 printk(KERN_INFO DRV_NAME 2867 2866 ": %s: backup interface %s is now down\n", 2868 - bond_dev->name, 2867 + bond->dev->name, 2869 2868 slave->dev->name); 2870 2869 } else { 2871 2870 read_unlock(&bond->curr_slave_lock); ··· 2900 2899 printk(KERN_INFO DRV_NAME 2901 2900 ": %s: link status down for active interface " 2902 2901 "%s, disabling it\n", 2903 - bond_dev->name, 2902 + bond->dev->name, 2904 2903 slave->dev->name); 2905 2904 2906 2905 write_lock(&bond->curr_slave_lock); ··· 2922 2921 printk(KERN_INFO DRV_NAME 2923 2922 ": %s: changing from interface %s to primary " 2924 2923 "interface %s\n", 2925 - bond_dev->name, 2924 + bond->dev->name, 2926 2925 slave->dev->name, 2927 2926 bond->primary_slave->dev->name); 2928 2927 ··· 2986 2985 printk(KERN_INFO DRV_NAME 2987 2986 ": %s: backup interface %s is " 2988 2987 "now down.\n", 2989 - bond_dev->name, 2988 + bond->dev->name, 2990 2989 slave->dev->name); 2991 2990 } 2992 2991 } ··· 2995 2994 2996 2995 re_arm: 2997 2996 if (bond->params.arp_interval) { 2998 - mod_timer(&bond->arp_timer, jiffies + delta_in_ticks); 2997 + queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); 2999 2998 } 3000 2999 out: 3001 3000 read_unlock(&bond->lock); ··· 3583 3582 static int bond_open(struct net_device *bond_dev) 3584 3583 { 3585 3584 struct bonding *bond = bond_dev->priv; 3586 - struct timer_list *mii_timer = &bond->mii_timer; 3587 - struct timer_list *arp_timer = &bond->arp_timer; 3588 3585 3589 3586 bond->kill_timers = 0; 3590 3587 3591 3588 if ((bond->params.mode == BOND_MODE_TLB) || 3592 3589 (bond->params.mode == BOND_MODE_ALB)) { 3593 - struct timer_list *alb_timer = &(BOND_ALB_INFO(bond).alb_timer); 3594 - 3595 3590 /* bond_alb_initialize must be called before the timer 3596 3591 * is started. 3597 3592 */ ··· 3596 3599 return -1; 3597 3600 } 3598 3601 3599 - init_timer(alb_timer); 3600 - alb_timer->expires = jiffies + 1; 3601 - alb_timer->data = (unsigned long)bond; 3602 - alb_timer->function = (void *)&bond_alb_monitor; 3603 - add_timer(alb_timer); 3602 + INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); 3603 + queue_delayed_work(bond->wq, &bond->alb_work, 0); 3604 3604 } 3605 3605 3606 3606 if (bond->params.miimon) { /* link check interval, in milliseconds. */ 3607 - init_timer(mii_timer); 3608 - mii_timer->expires = jiffies + 1; 3609 - mii_timer->data = (unsigned long)bond_dev; 3610 - mii_timer->function = (void *)&bond_mii_monitor; 3611 - add_timer(mii_timer); 3607 + INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); 3608 + queue_delayed_work(bond->wq, &bond->mii_work, 0); 3612 3609 } 3613 3610 3614 3611 if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ 3615 - init_timer(arp_timer); 3616 - arp_timer->expires = jiffies + 1; 3617 - arp_timer->data = (unsigned long)bond_dev; 3618 - if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { 3619 - arp_timer->function = (void *)&bond_activebackup_arp_mon; 3620 - } else { 3621 - arp_timer->function = (void *)&bond_loadbalance_arp_mon; 3622 - } 3612 + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) 3613 + INIT_DELAYED_WORK(&bond->arp_work, 3614 + bond_activebackup_arp_mon); 3615 + else 3616 + INIT_DELAYED_WORK(&bond->arp_work, 3617 + bond_loadbalance_arp_mon); 3618 + 3619 + queue_delayed_work(bond->wq, &bond->arp_work, 0); 3623 3620 if (bond->params.arp_validate) 3624 3621 bond_register_arp(bond); 3625 - 3626 - add_timer(arp_timer); 3627 3622 } 3628 3623 3629 3624 if (bond->params.mode == BOND_MODE_8023AD) { 3630 - struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer); 3631 - init_timer(ad_timer); 3632 - ad_timer->expires = jiffies + 1; 3633 - ad_timer->data = (unsigned long)bond; 3634 - ad_timer->function = (void *)&bond_3ad_state_machine_handler; 3635 - add_timer(ad_timer); 3636 - 3625 + INIT_DELAYED_WORK(&bond->ad_work, bond_alb_monitor); 3626 + queue_delayed_work(bond->wq, &bond->ad_work, 0); 3637 3627 /* register to receive LACPDUs */ 3638 3628 bond_register_lacpdu(bond); 3639 3629 } ··· 3648 3664 3649 3665 write_unlock_bh(&bond->lock); 3650 3666 3651 - /* del_timer_sync must run without holding the bond->lock 3652 - * because a running timer might be trying to hold it too 3653 - */ 3654 - 3655 3667 if (bond->params.miimon) { /* link check interval, in milliseconds. */ 3656 - del_timer_sync(&bond->mii_timer); 3668 + cancel_delayed_work(&bond->mii_work); 3657 3669 } 3658 3670 3659 3671 if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ 3660 - del_timer_sync(&bond->arp_timer); 3672 + cancel_delayed_work(&bond->arp_work); 3661 3673 } 3662 3674 3663 3675 switch (bond->params.mode) { 3664 3676 case BOND_MODE_8023AD: 3665 - del_timer_sync(&(BOND_AD_INFO(bond).ad_timer)); 3677 + cancel_delayed_work(&bond->ad_work); 3666 3678 break; 3667 3679 case BOND_MODE_TLB: 3668 3680 case BOND_MODE_ALB: 3669 - del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer)); 3681 + cancel_delayed_work(&bond->alb_work); 3670 3682 break; 3671 3683 default: 3672 3684 break; ··· 4320 4340 4321 4341 bond->params = *params; /* copy params struct */ 4322 4342 4343 + bond->wq = create_singlethread_workqueue(bond_dev->name); 4344 + if (!bond->wq) 4345 + return -ENOMEM; 4346 + 4323 4347 /* Initialize pointers */ 4324 4348 bond->first_slave = NULL; 4325 4349 bond->curr_active_slave = NULL; ··· 4810 4826 return res; 4811 4827 } 4812 4828 4829 + static void bond_work_cancel_all(struct bonding *bond) 4830 + { 4831 + write_lock_bh(&bond->lock); 4832 + bond->kill_timers = 1; 4833 + write_unlock_bh(&bond->lock); 4834 + 4835 + if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) 4836 + cancel_delayed_work(&bond->mii_work); 4837 + 4838 + if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) 4839 + cancel_delayed_work(&bond->arp_work); 4840 + 4841 + if (bond->params.mode == BOND_MODE_ALB && 4842 + delayed_work_pending(&bond->alb_work)) 4843 + cancel_delayed_work(&bond->alb_work); 4844 + 4845 + if (bond->params.mode == BOND_MODE_8023AD && 4846 + delayed_work_pending(&bond->ad_work)) 4847 + cancel_delayed_work(&bond->ad_work); 4848 + } 4849 + 4813 4850 static int __init bonding_init(void) 4814 4851 { 4815 4852 int i; 4816 4853 int res; 4854 + struct bonding *bond, *nxt; 4817 4855 4818 4856 printk(KERN_INFO "%s", version); 4819 4857 ··· 4862 4856 4863 4857 goto out; 4864 4858 err: 4859 + list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { 4860 + bond_work_cancel_all(bond); 4861 + destroy_workqueue(bond->wq); 4862 + } 4863 + 4865 4864 rtnl_lock(); 4866 4865 bond_free_all(); 4867 4866 bond_destroy_sysfs();
+20 -43
drivers/net/bonding/bond_sysfs.c
··· 662 662 "%s Disabling MII monitoring.\n", 663 663 bond->dev->name, bond->dev->name); 664 664 bond->params.miimon = 0; 665 - /* Kill MII timer, else it brings bond's link down */ 666 - if (bond->arp_timer.function) { 667 - printk(KERN_INFO DRV_NAME 668 - ": %s: Kill MII timer, else it brings bond's link down...\n", 669 - bond->dev->name); 670 - del_timer_sync(&bond->mii_timer); 665 + if (delayed_work_pending(&bond->mii_work)) { 666 + cancel_delayed_work(&bond->mii_work); 667 + flush_workqueue(bond->wq); 671 668 } 672 669 } 673 670 if (!bond->params.arp_targets[0]) { ··· 679 682 * timer will get fired off when the open function 680 683 * is called. 681 684 */ 682 - if (bond->arp_timer.function) { 683 - /* The timer's already set up, so fire it off */ 684 - mod_timer(&bond->arp_timer, jiffies + 1); 685 - } else { 686 - /* Set up the timer. */ 687 - init_timer(&bond->arp_timer); 688 - bond->arp_timer.expires = jiffies + 1; 689 - bond->arp_timer.data = 690 - (unsigned long) bond->dev; 691 - if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { 692 - bond->arp_timer.function = 693 - (void *) 694 - &bond_activebackup_arp_mon; 695 - } else { 696 - bond->arp_timer.function = 697 - (void *) 698 - &bond_loadbalance_arp_mon; 699 - } 700 - add_timer(&bond->arp_timer); 685 + if (!delayed_work_pending(&bond->arp_work)) { 686 + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) 687 + INIT_DELAYED_WORK(&bond->arp_work, 688 + bond_activebackup_arp_mon); 689 + else 690 + INIT_DELAYED_WORK(&bond->arp_work, 691 + bond_loadbalance_arp_mon); 692 + 693 + queue_delayed_work(bond->wq, &bond->arp_work, 0); 701 694 } 702 695 } 703 696 ··· 1043 1056 bond->params.arp_validate = 1044 1057 BOND_ARP_VALIDATE_NONE; 1045 1058 } 1046 - /* Kill ARP timer, else it brings bond's link down */ 1047 - if (bond->mii_timer.function) { 1048 - printk(KERN_INFO DRV_NAME 1049 - ": %s: Kill ARP timer, else it brings bond's link down...\n", 1050 - bond->dev->name); 1051 - del_timer_sync(&bond->arp_timer); 1059 + if (delayed_work_pending(&bond->arp_work)) { 1060 + cancel_delayed_work(&bond->arp_work); 1061 + flush_workqueue(bond->wq); 1052 1062 } 1053 1063 } 1054 1064 ··· 1055 1071 * timer will get fired off when the open function 1056 1072 * is called. 1057 1073 */ 1058 - if (bond->mii_timer.function) { 1059 - /* The timer's already set up, so fire it off */ 1060 - mod_timer(&bond->mii_timer, jiffies + 1); 1061 - } else { 1062 - /* Set up the timer. */ 1063 - init_timer(&bond->mii_timer); 1064 - bond->mii_timer.expires = jiffies + 1; 1065 - bond->mii_timer.data = 1066 - (unsigned long) bond->dev; 1067 - bond->mii_timer.function = 1068 - (void *) &bond_mii_monitor; 1069 - add_timer(&bond->mii_timer); 1074 + if (!delayed_work_pending(&bond->mii_work)) { 1075 + INIT_DELAYED_WORK(&bond->mii_work, 1076 + bond_mii_monitor); 1077 + queue_delayed_work(bond->wq, 1078 + &bond->mii_work, 0); 1070 1079 } 1071 1080 } 1072 1081 }
+8 -5
drivers/net/bonding/bonding.h
··· 184 184 s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ 185 185 rwlock_t lock; 186 186 rwlock_t curr_slave_lock; 187 - struct timer_list mii_timer; 188 - struct timer_list arp_timer; 189 187 s8 kill_timers; 190 188 s8 send_grat_arp; 191 189 s8 setup_by_slave; ··· 203 205 struct list_head vlan_list; 204 206 struct vlan_group *vlgrp; 205 207 struct packet_type arp_mon_pt; 208 + struct workqueue_struct *wq; 209 + struct delayed_work mii_work; 210 + struct delayed_work arp_work; 211 + struct delayed_work alb_work; 212 + struct delayed_work ad_work; 206 213 }; 207 214 208 215 /** ··· 310 307 void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave); 311 308 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); 312 309 int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); 313 - void bond_mii_monitor(struct net_device *bond_dev); 314 - void bond_loadbalance_arp_mon(struct net_device *bond_dev); 315 - void bond_activebackup_arp_mon(struct net_device *bond_dev); 310 + void bond_mii_monitor(struct work_struct *); 311 + void bond_loadbalance_arp_mon(struct work_struct *); 312 + void bond_activebackup_arp_mon(struct work_struct *); 316 313 void bond_set_mode_ops(struct bonding *bond, int mode); 317 314 int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl); 318 315 void bond_select_active_slave(struct bonding *bond);