Re: [PATCH v7 3/7] timekeeping: Account for clocksource tick quantisation via NTP

From: Marek Szyprowski

Date: Thu Jul 09 2026 - 11:03:49 EST


On 09.07.2026 15:38, David Woodhouse wrote:
> On Thu, 2026-07-09 at 14:56 +0200, Marek Szyprowski wrote:
>> This patch landed yesterday in linux-next as commit e8bf3955dc2f
>> ("timekeeping: Account for clocksource tick quantisation via NTP").
>> In my tests I found that it breaks booting Raspberry Pi 3B and Pi 4B
>> boards in ARM 32bit mode with quite old (Debian 10) userspace. Booting
>> freezes just before getting a getty login prompt and no more kernel
>> or userspace messages are observed. If I start with init=/bin/bash in
>> kernel cmdline and then wait a while and do "exec /sbin/init" I get
>> the following additional kernel message:
>>
>> [  186.867605] Adjusting arch_sys_counter more than 11% (12136 vs 344864995)
>>
>> then booting freezes again before getting getty prompt.
>>
>> I can do some more tests, just let me know what will help debugging this
>> issue. Other ARM 32bit machines I have work fine with this patch.
>>
>> Reverting subject together with its dependencies on top of linux-next 
>> fixes the issue.
> Thank you.
>
> I'm confused at this, because it's basically adding the *same* delta to
> the tick, just in a different place.
>
> While I go and frown at the maths a bit more... would you mind testing
> if *just* the change from TK_CLOCK_WAS_SET to TK_UPDATE_ALL in
> timekeeping_init() is the culprit?
>
> Could you add some pr_info() of xtime_remainder and cs_tick_adj (in the
> before vs. after cases)?

I'm not sure if I got it right. Here are the results and diffs I've applied:

before:

[    0.458729] cs_tick_adj 100000 186a0

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 9e1cbc590988..1aef9434b5a3 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -369,6 +369,8 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
        tk->xtime_remainder = ntpinterval - tk->xtime_interval;
        tk->raw_interval = interval * clock->mult;

+       pr_info("cs_tick_adj %llu %llx\n", (unsigned long long)tk->xtime_remainder, (unsigned long long)tk->xtime_remainder);
+
        /* if changing clocks, convert xtime_nsec shift units */
        if (old_clock) {
                int shift_change = clock->shift - old_clock->shift;


after:

[ 0.458546] cs_tick_adj 14151718768290390016 c465013da12d6000 [ 0.464393] clocksource: Switched to clocksource arch_sys_counter

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index e9aff9752d55..c93f2e5e72a6 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -414,6 +414,8 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock) ((s64)NTP_INTERVAL_LENGTH << NTP_SCALE_SHIFT); tk->cs_tick_adj *= NTP_INTERVAL_FREQ; + pr_info("cs_tick_adj %llu %llx\n", (unsigned long long)tk->cs_tick_adj, (unsigned long long)tk->cs_tick_adj); + /* * The timekeeper keeps its own mult values for the currently * active clocksource. These value will be adjusted via NTP

Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland