diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2012-05-25 18:08:57 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2012-06-06 07:49:01 -0400 |
commit | ec44bc7acc3687ba6ae8154b4b5a845b70279237 (patch) | |
tree | 56149499de97126be42cfb302a2f1da420dd55c5 /kernel/timer.c | |
parent | eea5b5510fc5545d15b69da8e485a7424ae388cf (diff) |
timers: Create detach_if_pending() and use it
Most callers of detach_timer() have the same pattern around
them. Check whether the timer is pending and eventually updating
base->next_timer.
Create detach_if_pending() and replace the duplicated code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Gilad Ben-Yossef <gilad@benyossef.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Link: http://lkml.kernel.org/r/20120525214819.131246037@linutronix.de
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 56 |
1 files changed, 23 insertions, 33 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 6ec7e7e0db43..0f70deb20151 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -654,8 +654,7 @@ void init_timer_deferrable_key(struct timer_list *timer, | |||
654 | } | 654 | } |
655 | EXPORT_SYMBOL(init_timer_deferrable_key); | 655 | EXPORT_SYMBOL(init_timer_deferrable_key); |
656 | 656 | ||
657 | static inline void detach_timer(struct timer_list *timer, | 657 | static inline void detach_timer(struct timer_list *timer, bool clear_pending) |
658 | int clear_pending) | ||
659 | { | 658 | { |
660 | struct list_head *entry = &timer->entry; | 659 | struct list_head *entry = &timer->entry; |
661 | 660 | ||
@@ -667,6 +666,19 @@ static inline void detach_timer(struct timer_list *timer, | |||
667 | entry->prev = LIST_POISON2; | 666 | entry->prev = LIST_POISON2; |
668 | } | 667 | } |
669 | 668 | ||
669 | static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, | ||
670 | bool clear_pending) | ||
671 | { | ||
672 | if (!timer_pending(timer)) | ||
673 | return 0; | ||
674 | |||
675 | detach_timer(timer, clear_pending); | ||
676 | if (timer->expires == base->next_timer && | ||
677 | !tbase_get_deferrable(timer->base)) | ||
678 | base->next_timer = base->timer_jiffies; | ||
679 | return 1; | ||
680 | } | ||
681 | |||
670 | /* | 682 | /* |
671 | * We are using hashed locking: holding per_cpu(tvec_bases).lock | 683 | * We are using hashed locking: holding per_cpu(tvec_bases).lock |
672 | * means that all timers which are tied to this base via timer->base are | 684 | * means that all timers which are tied to this base via timer->base are |
@@ -712,16 +724,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires, | |||
712 | 724 | ||
713 | base = lock_timer_base(timer, &flags); | 725 | base = lock_timer_base(timer, &flags); |
714 | 726 | ||
715 | if (timer_pending(timer)) { | 727 | ret = detach_if_pending(timer, base, false); |
716 | detach_timer(timer, 0); | 728 | if (!ret && pending_only) |
717 | if (timer->expires == base->next_timer && | 729 | goto out_unlock; |
718 | !tbase_get_deferrable(timer->base)) | ||
719 | base->next_timer = base->timer_jiffies; | ||
720 | ret = 1; | ||
721 | } else { | ||
722 | if (pending_only) | ||
723 | goto out_unlock; | ||
724 | } | ||
725 | 730 | ||
726 | debug_activate(timer, expires); | 731 | debug_activate(timer, expires); |
727 | 732 | ||
@@ -959,13 +964,7 @@ int del_timer(struct timer_list *timer) | |||
959 | timer_stats_timer_clear_start_info(timer); | 964 | timer_stats_timer_clear_start_info(timer); |
960 | if (timer_pending(timer)) { | 965 | if (timer_pending(timer)) { |
961 | base = lock_timer_base(timer, &flags); | 966 | base = lock_timer_base(timer, &flags); |
962 | if (timer_pending(timer)) { | 967 | ret = detach_if_pending(timer, base, true); |
963 | detach_timer(timer, 1); | ||
964 | if (timer->expires == base->next_timer && | ||
965 | !tbase_get_deferrable(timer->base)) | ||
966 | base->next_timer = base->timer_jiffies; | ||
967 | ret = 1; | ||
968 | } | ||
969 | spin_unlock_irqrestore(&base->lock, flags); | 968 | spin_unlock_irqrestore(&base->lock, flags); |
970 | } | 969 | } |
971 | 970 | ||
@@ -990,19 +989,10 @@ int try_to_del_timer_sync(struct timer_list *timer) | |||
990 | 989 | ||
991 | base = lock_timer_base(timer, &flags); | 990 | base = lock_timer_base(timer, &flags); |
992 | 991 | ||
993 | if (base->running_timer == timer) | 992 | if (base->running_timer != timer) { |
994 | goto out; | 993 | timer_stats_timer_clear_start_info(timer); |
995 | 994 | ret = detach_if_pending(timer, base, true); | |
996 | timer_stats_timer_clear_start_info(timer); | ||
997 | ret = 0; | ||
998 | if (timer_pending(timer)) { | ||
999 | detach_timer(timer, 1); | ||
1000 | if (timer->expires == base->next_timer && | ||
1001 | !tbase_get_deferrable(timer->base)) | ||
1002 | base->next_timer = base->timer_jiffies; | ||
1003 | ret = 1; | ||
1004 | } | 995 | } |
1005 | out: | ||
1006 | spin_unlock_irqrestore(&base->lock, flags); | 996 | spin_unlock_irqrestore(&base->lock, flags); |
1007 | 997 | ||
1008 | return ret; | 998 | return ret; |
@@ -1178,7 +1168,7 @@ static inline void __run_timers(struct tvec_base *base) | |||
1178 | timer_stats_account_timer(timer); | 1168 | timer_stats_account_timer(timer); |
1179 | 1169 | ||
1180 | base->running_timer = timer; | 1170 | base->running_timer = timer; |
1181 | detach_timer(timer, 1); | 1171 | detach_timer(timer, true); |
1182 | 1172 | ||
1183 | spin_unlock_irq(&base->lock); | 1173 | spin_unlock_irq(&base->lock); |
1184 | call_timer_fn(timer, fn, data); | 1174 | call_timer_fn(timer, fn, data); |
@@ -1714,7 +1704,7 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea | |||
1714 | 1704 | ||
1715 | while (!list_empty(head)) { | 1705 | while (!list_empty(head)) { |
1716 | timer = list_first_entry(head, struct timer_list, entry); | 1706 | timer = list_first_entry(head, struct timer_list, entry); |
1717 | detach_timer(timer, 0); | 1707 | detach_timer(timer, false); |
1718 | timer_set_base(timer, new_base); | 1708 | timer_set_base(timer, new_base); |
1719 | if (time_before(timer->expires, new_base->next_timer) && | 1709 | if (time_before(timer->expires, new_base->next_timer) && |
1720 | !tbase_get_deferrable(timer->base)) | 1710 | !tbase_get_deferrable(timer->base)) |