Skip to content

Commit e9523a0

Browse files
Sebastian Andrzej SiewiorKAGA-KOKO
authored andcommitted
tick/common: Align tick period with the HZ tick.
With HIGHRES enabled tick_sched_timer() is programmed every jiffy to expire the timer_list timers. This timer is programmed accurate in respect to CLOCK_MONOTONIC so that 0 seconds and nanoseconds is the first tick and the next one is 1000/CONFIG_HZ ms later. For HZ=250 it is every 4 ms and so based on the current time the next tick can be computed. This accuracy broke since the commit mentioned below because the jiffy based clocksource is initialized with higher accuracy in read_persistent_wall_and_boot_offset(). This higher accuracy is inherited during the setup in tick_setup_device(). The timer still fires every 4ms with HZ=250 but timer is no longer aligned with CLOCK_MONOTONIC with 0 as it origin but has an offset in the us/ns part of the timestamp. The offset differs with every boot and makes it impossible for user land to align with the tick. Align the tick period with CLOCK_MONOTONIC ensuring that it is always a multiple of 1000/CONFIG_HZ ms. Fixes: 857baa8 ("sched/clock: Enable sched clock early") Reported-by: Gusenleitner Klaus <gus@keba.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/20230406095735.0_14edn3@linutronix.de Link: https://lore.kernel.org/r/20230418122639.ikgfvu3f@linutronix.de
1 parent e797203 commit e9523a0

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

kernel/time/tick-common.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,19 @@ static void tick_setup_device(struct tick_device *td,
218218
* this cpu:
219219
*/
220220
if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) {
221+
ktime_t next_p;
222+
u32 rem;
223+
221224
tick_do_timer_cpu = cpu;
222225

223-
tick_next_period = ktime_get();
226+
next_p = ktime_get();
227+
div_u64_rem(next_p, TICK_NSEC, &rem);
228+
if (rem) {
229+
next_p -= rem;
230+
next_p += TICK_NSEC;
231+
}
232+
233+
tick_next_period = next_p;
224234
#ifdef CONFIG_NO_HZ_FULL
225235
/*
226236
* The boot CPU may be nohz_full, in which case set

0 commit comments

Comments
 (0)