[PATCH] timekeeping: Move debug sleep time accounting outside spinlock
From: Haofeng Li
Date: Tue Sep 09 2025 - 06:34:57 EST
From: Haofeng Li <lihaofeng@xxxxxxxxxx>
The function tk_debug_account_sleep_time() was called inside a spinlock
in __timekeeping_inject_sleeptime(), which could lead to potential
deadlocks, particularly when CONFIG_DEBUG_PM_SLEEP is enabled.
To prevent this, move the call to tk_debug_account_sleep_time() outside
the raw spinlock. Additionally, add a check to ensure it is only called
with a valid time delta, avoiding unnecessary debug accounting when the
time value is zero or invalid.
The same change is applied to timekeeping_inject_sleeptime64() and
timekeeping_resume() to maintain consistency and improve stability across
the timekeeping subsystem.
Signed-off-by: Haofeng Li <lihaofeng@xxxxxxxxxx>
---
kernel/time/timekeeping.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b6974fce800c..3c6eb5220149 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1865,7 +1865,6 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
tk_xtime_add(tk, delta);
tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, *delta));
tk_update_sleep_time(tk, timespec64_to_ktime(*delta));
- tk_debug_account_sleep_time(delta);
}
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
@@ -1926,6 +1925,9 @@ void timekeeping_inject_sleeptime64(const struct timespec64 *delta)
timekeeping_update_from_shadow(&tk_core, TK_UPDATE_ALL);
}
+ if (timespec64_valid_strict(delta))
+ tk_debug_account_sleep_time(delta);
+
/* Signal hrtimers about time change */
clock_was_set(CLOCK_SET_WALL | CLOCK_SET_BOOT);
}
@@ -1986,7 +1988,8 @@ void timekeeping_resume(void)
timekeeping_update_from_shadow(&tk_core, TK_CLOCK_WAS_SET);
raw_spin_unlock_irqrestore(&tk_core.lock, flags);
- touch_softlockup_watchdog();
+ if (inject_sleeptime && timespec64_valid_strict(&ts_delta))
+ tk_debug_account_sleep_time(&ts_delta);
/* Resume the clockevent device(s) and hrtimers */
tick_resume();
--
2.25.1