|
@@ -92,12 +92,12 @@ static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;
|
|
|
/* Functions below help us manage 'deferrable' flag */
|
|
|
static inline unsigned int tbase_get_deferrable(struct tvec_base *base)
|
|
|
{
|
|
|
- return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG);
|
|
|
+ return ((unsigned int)(unsigned long)base & TIMER_DEFERRABLE);
|
|
|
}
|
|
|
|
|
|
static inline struct tvec_base *tbase_get_base(struct tvec_base *base)
|
|
|
{
|
|
|
- return ((struct tvec_base *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG));
|
|
|
+ return ((struct tvec_base *)((unsigned long)base & ~TIMER_FLAG_MASK));
|
|
|
}
|
|
|
|
|
|
static inline void timer_set_deferrable(struct timer_list *timer)
|
|
@@ -108,8 +108,9 @@ static inline void timer_set_deferrable(struct timer_list *timer)
|
|
|
static inline void
|
|
|
timer_set_base(struct timer_list *timer, struct tvec_base *new_base)
|
|
|
{
|
|
|
- timer->base = (struct tvec_base *)((unsigned long)(new_base) |
|
|
|
- tbase_get_deferrable(timer->base));
|
|
|
+ unsigned long flags = (unsigned long)timer->base & TIMER_FLAG_MASK;
|
|
|
+
|
|
|
+ timer->base = (struct tvec_base *)((unsigned long)(new_base) | flags);
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
{
|
|
|
detach_timer(timer, true);
|
|
|
if (!tbase_get_deferrable(timer->base))
|
|
|
- timer->base->active_timers--;
|
|
|
+ base->active_timers--;
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
|
|
|
detach_timer(timer, clear_pending);
|
|
|
if (!tbase_get_deferrable(timer->base)) {
|
|
|
- timer->base->active_timers--;
|
|
|
+ base->active_timers--;
|
|
|
if (timer->expires == base->next_timer)
|
|
|
base->next_timer = base->timer_jiffies;
|
|
|
}
|
|
@@ -1800,9 +1801,13 @@ static struct notifier_block __cpuinitdata timers_nb = {
|
|
|
|
|
|
void __init init_timers(void)
|
|
|
{
|
|
|
- int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
|
|
|
- (void *)(long)smp_processor_id());
|
|
|
+ int err;
|
|
|
+
|
|
|
+ /* ensure there are enough low bits for flags in timer->base pointer */
|
|
|
+ BUILD_BUG_ON(__alignof__(struct tvec_base) & TIMER_FLAG_MASK);
|
|
|
|
|
|
+ err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
|
|
|
+ (void *)(long)smp_processor_id());
|
|
|
init_timer_stats();
|
|
|
|
|
|
BUG_ON(err != NOTIFY_OK);
|