diff options
| author | Yong Zhang <yong.zhang@windriver.com> | 2010-10-20 18:57:31 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2010-10-22 08:46:25 -0400 |
| commit | 6f1bc451e6a79470b122a37ee1fc6bbca450f444 (patch) | |
| tree | b4393f6130ae3a9075de509a0e0e9328f3bd3430 | |
| parent | 20f33a03f0cf87e51165f7084f697acfb68e865b (diff) | |
timer: Make try_to_del_timer_sync() the same on SMP and UP
On UP try_to_del_timer_sync() is mapped to del_timer() which does not
take the running timer callback into account, so it has different
semantics.
Remove the SMP dependency of try_to_del_timer_sync() by using
base->running_timer in the UP case as well.
[ tglx: Removed set_running_timer() inline and tweaked the changelog ]
Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
| -rw-r--r-- | include/linux/timer.h | 4 | ||||
| -rw-r--r-- | kernel/timer.c | 17 |
2 files changed, 5 insertions, 16 deletions
diff --git a/include/linux/timer.h b/include/linux/timer.h index cbfb7a355d30..6abd9138beda 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h | |||
| @@ -274,11 +274,11 @@ static inline void timer_stats_timer_clear_start_info(struct timer_list *timer) | |||
| 274 | 274 | ||
| 275 | extern void add_timer(struct timer_list *timer); | 275 | extern void add_timer(struct timer_list *timer); |
| 276 | 276 | ||
| 277 | extern int try_to_del_timer_sync(struct timer_list *timer); | ||
| 278 | |||
| 277 | #ifdef CONFIG_SMP | 279 | #ifdef CONFIG_SMP |
| 278 | extern int try_to_del_timer_sync(struct timer_list *timer); | ||
| 279 | extern int del_timer_sync(struct timer_list *timer); | 280 | extern int del_timer_sync(struct timer_list *timer); |
| 280 | #else | 281 | #else |
| 281 | # define try_to_del_timer_sync(t) del_timer(t) | ||
| 282 | # define del_timer_sync(t) del_timer(t) | 282 | # define del_timer_sync(t) del_timer(t) |
| 283 | #endif | 283 | #endif |
| 284 | 284 | ||
diff --git a/kernel/timer.c b/kernel/timer.c index 72853b256ff2..47b86c1e3226 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -330,15 +330,6 @@ void set_timer_slack(struct timer_list *timer, int slack_hz) | |||
| 330 | } | 330 | } |
| 331 | EXPORT_SYMBOL_GPL(set_timer_slack); | 331 | EXPORT_SYMBOL_GPL(set_timer_slack); |
| 332 | 332 | ||
| 333 | |||
| 334 | static inline void set_running_timer(struct tvec_base *base, | ||
| 335 | struct timer_list *timer) | ||
| 336 | { | ||
| 337 | #ifdef CONFIG_SMP | ||
| 338 | base->running_timer = timer; | ||
| 339 | #endif | ||
| 340 | } | ||
| 341 | |||
| 342 | static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) | 333 | static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) |
| 343 | { | 334 | { |
| 344 | unsigned long expires = timer->expires; | 335 | unsigned long expires = timer->expires; |
| @@ -923,15 +914,12 @@ int del_timer(struct timer_list *timer) | |||
| 923 | } | 914 | } |
| 924 | EXPORT_SYMBOL(del_timer); | 915 | EXPORT_SYMBOL(del_timer); |
| 925 | 916 | ||
| 926 | #ifdef CONFIG_SMP | ||
| 927 | /** | 917 | /** |
| 928 | * try_to_del_timer_sync - Try to deactivate a timer | 918 | * try_to_del_timer_sync - Try to deactivate a timer |
| 929 | * @timer: timer do del | 919 | * @timer: timer do del |
| 930 | * | 920 | * |
| 931 | * This function tries to deactivate a timer. Upon successful (ret >= 0) | 921 | * This function tries to deactivate a timer. Upon successful (ret >= 0) |
| 932 | * exit the timer is not queued and the handler is not running on any CPU. | 922 | * exit the timer is not queued and the handler is not running on any CPU. |
| 933 | * | ||
| 934 | * It must not be called from interrupt contexts. | ||
| 935 | */ | 923 | */ |
| 936 | int try_to_del_timer_sync(struct timer_list *timer) | 924 | int try_to_del_timer_sync(struct timer_list *timer) |
| 937 | { | 925 | { |
| @@ -960,6 +948,7 @@ out: | |||
| 960 | } | 948 | } |
| 961 | EXPORT_SYMBOL(try_to_del_timer_sync); | 949 | EXPORT_SYMBOL(try_to_del_timer_sync); |
| 962 | 950 | ||
| 951 | #ifdef CONFIG_SMP | ||
| 963 | /** | 952 | /** |
| 964 | * del_timer_sync - deactivate a timer and wait for the handler to finish. | 953 | * del_timer_sync - deactivate a timer and wait for the handler to finish. |
| 965 | * @timer: the timer to be deactivated | 954 | * @timer: the timer to be deactivated |
| @@ -1098,7 +1087,7 @@ static inline void __run_timers(struct tvec_base *base) | |||
| 1098 | 1087 | ||
| 1099 | timer_stats_account_timer(timer); | 1088 | timer_stats_account_timer(timer); |
| 1100 | 1089 | ||
| 1101 | set_running_timer(base, timer); | 1090 | base->running_timer = timer; |
| 1102 | detach_timer(timer, 1); | 1091 | detach_timer(timer, 1); |
| 1103 | 1092 | ||
| 1104 | spin_unlock_irq(&base->lock); | 1093 | spin_unlock_irq(&base->lock); |
| @@ -1106,7 +1095,7 @@ static inline void __run_timers(struct tvec_base *base) | |||
| 1106 | spin_lock_irq(&base->lock); | 1095 | spin_lock_irq(&base->lock); |
| 1107 | } | 1096 | } |
| 1108 | } | 1097 | } |
| 1109 | set_running_timer(base, NULL); | 1098 | base->running_timer = NULL; |
| 1110 | spin_unlock_irq(&base->lock); | 1099 | spin_unlock_irq(&base->lock); |
| 1111 | } | 1100 | } |
| 1112 | 1101 | ||
