Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Yong Zhang and committed by
Thomas Gleixner
6f1bc451 20f33a03

+5 -16
+2 -2
include/linux/timer.h
··· 274 274 275 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 279 #ifdef CONFIG_SMP 278 - extern int try_to_del_timer_sync(struct timer_list *timer); 279 280 extern int del_timer_sync(struct timer_list *timer); 280 281 #else 281 - # define try_to_del_timer_sync(t) del_timer(t) 282 282 # define del_timer_sync(t) del_timer(t) 283 283 #endif 284 284
+3 -14
kernel/timer.c
··· 330 330 } 331 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 333 static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) 343 334 { 344 335 unsigned long expires = timer->expires; ··· 914 923 } 915 924 EXPORT_SYMBOL(del_timer); 916 925 917 - #ifdef CONFIG_SMP 918 926 /** 919 927 * try_to_del_timer_sync - Try to deactivate a timer 920 928 * @timer: timer do del 921 929 * 922 930 * This function tries to deactivate a timer. Upon successful (ret >= 0) 923 931 * exit the timer is not queued and the handler is not running on any CPU. 924 - * 925 - * It must not be called from interrupt contexts. 926 932 */ 927 933 int try_to_del_timer_sync(struct timer_list *timer) 928 934 { ··· 948 960 } 949 961 EXPORT_SYMBOL(try_to_del_timer_sync); 950 962 963 + #ifdef CONFIG_SMP 951 964 /** 952 965 * del_timer_sync - deactivate a timer and wait for the handler to finish. 953 966 * @timer: the timer to be deactivated ··· 1087 1098 1088 1099 timer_stats_account_timer(timer); 1089 1100 1090 - set_running_timer(base, timer); 1101 + base->running_timer = timer; 1091 1102 detach_timer(timer, 1); 1092 1103 1093 1104 spin_unlock_irq(&base->lock); ··· 1095 1106 spin_lock_irq(&base->lock); 1096 1107 } 1097 1108 } 1098 - set_running_timer(base, NULL); 1109 + base->running_timer = NULL; 1099 1110 spin_unlock_irq(&base->lock); 1100 1111 } 1101 1112