diff options
author | Tejun Heo <tj@kernel.org> | 2012-08-08 14:10:25 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2012-08-21 10:28:30 -0400 |
commit | e52b1db37b89b69ceb08b521a808bd2cf4724481 (patch) | |
tree | 9f37d5060e57f1b2746047c204b1c96725463f39 /kernel/timer.c | |
parent | eec19d1a0d04c80e66eef634f7b8f460f2ca5643 (diff) |
timer: Generalize timer->base flags handling
To prepare for addition of another flag, generalize timer->base flags
handling.
* Rename from TBASE_*_FLAG to TIMER_* and make them LU constants.
* Define and use TIMER_FLAG_MASK for flags masking so that multiple
flags can be handled correctly.
* Don't dereference timer->base directly even if
!tbase_get_deferrable(). All two such places are already passed in
@base, so use it instead.
* Make sure tvec_base's alignment is large enough for timer->base
flags using BUILD_BUG_ON().
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: torvalds@linux-foundation.org
Cc: peterz@infradead.org
Link: http://lkml.kernel.org/r/1344449428-24962-2-git-send-email-tj@kernel.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index a61c09374eba..cf7af56940b7 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -92,12 +92,12 @@ static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases; | |||
92 | /* Functions below help us manage 'deferrable' flag */ | 92 | /* Functions below help us manage 'deferrable' flag */ |
93 | static inline unsigned int tbase_get_deferrable(struct tvec_base *base) | 93 | static inline unsigned int tbase_get_deferrable(struct tvec_base *base) |
94 | { | 94 | { |
95 | return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG); | 95 | return ((unsigned int)(unsigned long)base & TIMER_DEFERRABLE); |
96 | } | 96 | } |
97 | 97 | ||
98 | static inline struct tvec_base *tbase_get_base(struct tvec_base *base) | 98 | static inline struct tvec_base *tbase_get_base(struct tvec_base *base) |
99 | { | 99 | { |
100 | return ((struct tvec_base *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG)); | 100 | return ((struct tvec_base *)((unsigned long)base & ~TIMER_FLAG_MASK)); |
101 | } | 101 | } |
102 | 102 | ||
103 | static inline void timer_set_deferrable(struct timer_list *timer) | 103 | static inline void timer_set_deferrable(struct timer_list *timer) |
@@ -108,8 +108,9 @@ static inline void timer_set_deferrable(struct timer_list *timer) | |||
108 | static inline void | 108 | static inline void |
109 | timer_set_base(struct timer_list *timer, struct tvec_base *new_base) | 109 | timer_set_base(struct timer_list *timer, struct tvec_base *new_base) |
110 | { | 110 | { |
111 | timer->base = (struct tvec_base *)((unsigned long)(new_base) | | 111 | unsigned long flags = (unsigned long)timer->base & TIMER_FLAG_MASK; |
112 | tbase_get_deferrable(timer->base)); | 112 | |
113 | timer->base = (struct tvec_base *)((unsigned long)(new_base) | flags); | ||
113 | } | 114 | } |
114 | 115 | ||
115 | static unsigned long round_jiffies_common(unsigned long j, int cpu, | 116 | static unsigned long round_jiffies_common(unsigned long j, int cpu, |
@@ -686,7 +687,7 @@ detach_expired_timer(struct timer_list *timer, struct tvec_base *base) | |||
686 | { | 687 | { |
687 | detach_timer(timer, true); | 688 | detach_timer(timer, true); |
688 | if (!tbase_get_deferrable(timer->base)) | 689 | if (!tbase_get_deferrable(timer->base)) |
689 | timer->base->active_timers--; | 690 | base->active_timers--; |
690 | } | 691 | } |
691 | 692 | ||
692 | static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, | 693 | static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, |
@@ -697,7 +698,7 @@ static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, | |||
697 | 698 | ||
698 | detach_timer(timer, clear_pending); | 699 | detach_timer(timer, clear_pending); |
699 | if (!tbase_get_deferrable(timer->base)) { | 700 | if (!tbase_get_deferrable(timer->base)) { |
700 | timer->base->active_timers--; | 701 | base->active_timers--; |
701 | if (timer->expires == base->next_timer) | 702 | if (timer->expires == base->next_timer) |
702 | base->next_timer = base->timer_jiffies; | 703 | base->next_timer = base->timer_jiffies; |
703 | } | 704 | } |
@@ -1800,9 +1801,13 @@ static struct notifier_block __cpuinitdata timers_nb = { | |||
1800 | 1801 | ||
1801 | void __init init_timers(void) | 1802 | void __init init_timers(void) |
1802 | { | 1803 | { |
1803 | int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, | 1804 | int err; |
1804 | (void *)(long)smp_processor_id()); | 1805 | |
1806 | /* ensure there are enough low bits for flags in timer->base pointer */ | ||
1807 | BUILD_BUG_ON(__alignof__(struct tvec_base) & TIMER_FLAG_MASK); | ||
1805 | 1808 | ||
1809 | err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, | ||
1810 | (void *)(long)smp_processor_id()); | ||
1806 | init_timer_stats(); | 1811 | init_timer_stats(); |
1807 | 1812 | ||
1808 | BUG_ON(err != NOTIFY_OK); | 1813 | BUG_ON(err != NOTIFY_OK); |