summaryrefslogtreecommitdiff
path: root/kernel/time
diff options
context:
space:
mode:
authorMikhail Gavrilov <mikhail.v.gavrilov@gmail.com>2026-06-16 12:09:14 +0500
committerThomas Gleixner <tglx@kernel.org>2026-06-17 16:55:26 +0200
commit8fa30821180a9a19e78e9f4df1c0ba710252801e (patch)
tree7bcf0017129febe8ec9ed124b8383f3e02600b76 /kernel/time
parent66affa37cfac0aec061cc4bcf4a065b0c52f7e19 (diff)
downloadlinux-next-8fa30821180a9a19e78e9f4df1c0ba710252801e.tar.gz
linux-next-8fa30821180a9a19e78e9f4df1c0ba710252801e.zip
timekeeping: Register default clocksource before taking tk_core.lock
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
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/timekeeping.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 0d5b67f609bb..b1b5ec43c0f2 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -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);