diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-04-14 18:56:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-04-14 18:56:02 -0400 |
commit | 2d9073922bc73f8cb847ce354f0896205f6981a1 (patch) | |
tree | f6a9db5cec30edd2a16ba79575cf2d28c5180b9a /net/atm | |
parent | f3a0592b37b83e56a7f47826f552b35a2c3b2fc9 (diff) |
[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/atm')
-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; | |||
54 | static struct atm_vcc *atmarpd; | 54 | static struct atm_vcc *atmarpd; |
55 | static struct neigh_table clip_tbl; | 55 | static struct neigh_table clip_tbl; |
56 | static struct timer_list idle_timer; | 56 | static struct timer_list idle_timer; |
57 | static int start_timer = 1; | ||
58 | |||
59 | 57 | ||
60 | static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) | 58 | static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) |
61 | { | 59 | { |
@@ -725,13 +723,8 @@ static int atm_init_atmarp(struct atm_vcc *vcc) | |||
725 | return -EADDRINUSE; | 723 | return -EADDRINUSE; |
726 | } | 724 | } |
727 | 725 | ||
728 | if (start_timer) { | 726 | mod_timer(&idle_timer, jiffies+CLIP_CHECK_INTERVAL*HZ); |
729 | start_timer = 0; | 727 | |
730 | init_timer(&idle_timer); | ||
731 | idle_timer.expires = jiffies+CLIP_CHECK_INTERVAL*HZ; | ||
732 | idle_timer.function = idle_timer_check; | ||
733 | add_timer(&idle_timer); | ||
734 | } | ||
735 | atmarpd = vcc; | 728 | atmarpd = vcc; |
736 | set_bit(ATM_VF_META,&vcc->flags); | 729 | set_bit(ATM_VF_META,&vcc->flags); |
737 | set_bit(ATM_VF_READY,&vcc->flags); | 730 | set_bit(ATM_VF_READY,&vcc->flags); |
@@ -1002,6 +995,8 @@ static int __init atm_clip_init(void) | |||
1002 | register_netdevice_notifier(&clip_dev_notifier); | 995 | register_netdevice_notifier(&clip_dev_notifier); |
1003 | register_inetaddr_notifier(&clip_inet_notifier); | 996 | register_inetaddr_notifier(&clip_inet_notifier); |
1004 | 997 | ||
998 | setup_timer(&idle_timer, idle_timer_check, 0); | ||
999 | |||
1005 | #ifdef CONFIG_PROC_FS | 1000 | #ifdef CONFIG_PROC_FS |
1006 | { | 1001 | { |
1007 | struct proc_dir_entry *p; | 1002 | struct proc_dir_entry *p; |
@@ -1029,8 +1024,7 @@ static void __exit atm_clip_exit(void) | |||
1029 | /* First, stop the idle timer, so it stops banging | 1024 | /* First, stop the idle timer, so it stops banging |
1030 | * on the table. | 1025 | * on the table. |
1031 | */ | 1026 | */ |
1032 | if (start_timer == 0) | 1027 | del_timer_sync(&idle_timer); |
1033 | del_timer(&idle_timer); | ||
1034 | 1028 | ||
1035 | /* Next, purge the table, so that the device | 1029 | /* Next, purge the table, so that the device |
1036 | * unregister loop below does not hang due to | 1030 | * unregister loop below does not hang due to |