diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-04-15 00:56:02 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-04-15 00:56:02 +0200 |
commit | 2d9073922bc73f8cb847ce354f0896205f6981a1 (patch) | |
tree | f6a9db5cec30edd2a16ba79575cf2d28c5180b9a /net | |
parent | [ATM]: clip causes unregister hang (diff) | |
download | linux-2d9073922bc73f8cb847ce354f0896205f6981a1.tar.xz linux-2d9073922bc73f8cb847ce354f0896205f6981a1.zip |
[ATM]: Clip timer race.
By inspection, the clip idle timer code is racy on SMP.
Here is a safe version of timer management.
Untested, I don't have ATM hardware.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/atm/clip.c | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c index 5841c30384a4..b1f12f6c5fd6 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -54,8 +54,6 @@ static struct net_device *clip_devs; static struct atm_vcc *atmarpd; static struct neigh_table clip_tbl; static struct timer_list idle_timer; -static int start_timer = 1; - static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) { @@ -725,13 +723,8 @@ static int atm_init_atmarp(struct atm_vcc *vcc) return -EADDRINUSE; } - if (start_timer) { - start_timer = 0; - init_timer(&idle_timer); - idle_timer.expires = jiffies+CLIP_CHECK_INTERVAL*HZ; - idle_timer.function = idle_timer_check; - add_timer(&idle_timer); - } + mod_timer(&idle_timer, jiffies+CLIP_CHECK_INTERVAL*HZ); + atmarpd = vcc; set_bit(ATM_VF_META,&vcc->flags); set_bit(ATM_VF_READY,&vcc->flags); @@ -1002,6 +995,8 @@ static int __init atm_clip_init(void) register_netdevice_notifier(&clip_dev_notifier); register_inetaddr_notifier(&clip_inet_notifier); + setup_timer(&idle_timer, idle_timer_check, 0); + #ifdef CONFIG_PROC_FS { struct proc_dir_entry *p; @@ -1029,8 +1024,7 @@ static void __exit atm_clip_exit(void) /* First, stop the idle timer, so it stops banging * on the table. */ - if (start_timer == 0) - del_timer(&idle_timer); + del_timer_sync(&idle_timer); /* Next, purge the table, so that the device * unregister loop below does not hang due to |