In lowres mode, hrtimers are serviced by the tick. But when a hrtimer is enqueued on a idle or full dynticks target, we need to kick it in order to make it reconsider the next tick to schedule, to correctly handle the hrtimer's expiring time.
Now while this kick is correctly performed for periodic timers, hrtimers were a bit neglected.
To prepare for fixing this, we need __hrtimer_start_range_ns() to be able to resolve the CPU target associated to a hrtimer's object 'cpu_base' so that the kick can be centralized there.
So lets store it in the 'struct hrtimer_cpu_base' to resolve the CPU without much overhead. It is set at CPU's online notification.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- include/linux/hrtimer.h | 2 ++ kernel/hrtimer.c | 1 + 2 files changed, 3 insertions(+)
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index e7a8d3f..bb4ffff 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -165,6 +165,7 @@ enum hrtimer_base_type { * struct hrtimer_cpu_base - the per cpu clock bases * @lock: lock protecting the base and associated clock bases * and timers + * @cpu: cpu number * @active_bases: Bitfield to mark bases with active timers * @clock_was_set: Indicates that clock was set from irq context. * @expires_next: absolute time of the next event which was scheduled @@ -179,6 +180,7 @@ enum hrtimer_base_type { */ struct hrtimer_cpu_base { raw_spinlock_t lock; + unsigned int cpu; unsigned int active_bases; unsigned int clock_was_set; #ifdef CONFIG_HIGH_RES_TIMERS diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index e0501fe..dd6fb1d 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1679,6 +1679,7 @@ static void init_hrtimers_cpu(int cpu) timerqueue_init_head(&cpu_base->clock_base[i].active); }
+ cpu_base->cpu = cpu; hrtimer_init_hres(cpu_base); }