]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
timekeeping: Register default clocksource before taking tk_core.lock
authorMikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Tue, 16 Jun 2026 07:09:14 +0000 (12:09 +0500)
committerThomas Gleixner <tglx@kernel.org>
Wed, 17 Jun 2026 14:55:26 +0000 (16:55 +0200)
Commit f24df84cbe05 ("time/jiffies: Register jiffies clocksource before
usage") moved the jiffies clocksource registration into
clocksource_default_clock(), so that it is registered lazily on the first
call. __clocksource_register() acquires clocksource_mutex, but the first
caller is timekeeping_init(), which invokes clocksource_default_clock()
while holding tk_core.lock, a raw spinlock.

Acquiring a sleeping mutex while holding a raw spinlock is invalid.

The default clocksource only has to be registered before
tk_setup_internals() consumes its mult/shift/maxadj. Neither
clocksource_default_clock(), the ->enable() callback, nor the registration
itself need tk_core.lock, so fetch and enable the clock before acquiring
the lock. This preserves the "register before usage" ordering while
keeping clocksource_mutex out of the raw spinlock section.

clocksource_default_clock() has a second caller,
clocksource_done_booting(), which invokes it with clocksource_mutex already
held. That path avoids a recursive lock because timekeeping_init() has
already run and set cs_jiffies_registered, so the registration is skipped
there. This change does not alter that; it only fixes the invalid wait
context in timekeeping_init().

Fixes: f24df84cbe05 ("time/jiffies: Register jiffies clocksource before usage")
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reported-by: Breno Leitao <leitao@debian.org>
Reported-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Breno Leitao <leitao@debian.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260616070914.65818-1-mikhail.v.gavrilov@gmail.com
kernel/time/timekeeping.c

index 0d5b67f609bbffb8b240e2381d361fe48e3f5f58..b1b5ec43c0f27be0b512d8ae6b50741251f07c1c 100644 (file)
@@ -2061,13 +2061,14 @@ void __init timekeeping_init(void)
         */
        wall_to_mono = timespec64_sub(boot_offset, wall_time);
 
+       clock = clocksource_default_clock();
+       if (clock->enable)
+               clock->enable(clock);
+
        guard(raw_spinlock_irqsave)(&tk_core.lock);
 
        ntp_init();
 
-       clock = clocksource_default_clock();
-       if (clock->enable)
-               clock->enable(clock);
        tk_setup_internals(tks, clock);
 
        tk_set_xtime(tks, &wall_time);