summaryrefslogtreecommitdiff
path: root/kernel/time/tick-common.c
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer@dabbelt.com>2025-06-05 11:11:21 -0700
committerPalmer Dabbelt <palmer@dabbelt.com>2025-06-05 12:26:06 -0700
commit9d3da7827536b8e41e4188185622816a105b46f7 (patch)
treea2b81c15a474f5ecff61fb182a3d3f21bbde3296 /kernel/time/tick-common.c
parent2f956db8b3b02256b21da4d1f26fedc63782adff (diff)
parentc39d53750ff96b282c869a0184a7c3ecfd298ca8 (diff)
Merge tag 'riscv-mw1-6.16-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/alexghiti/linux into for-next
riscv patches for 6.16-rc1 * Implement atomic patching support for ftrace which finally allows to get rid of stop_machine(). * Support for kexec_file_load() syscall * Improve module loading time by changing the algorithm that counts the number of plt/got entries in a module. * Zicbop is now used in the kernel to prefetch instructions [Palmer: There's been two rounds of surgery on this one, so as a result it's a bit different than the PR.] * alex-pr: (734 commits) riscv: Improve Kconfig help for RISCV_ISA_V_PREEMPTIVE MAINTAINERS: Update Atish's email address riscv: hwprobe: export Zabha extension riscv: Make regs_irqs_disabled() more clear perf symbols: Ignore mapping symbols on riscv RISC-V: Kconfig: Fix help text of CMDLINE_EXTEND riscv: module: Optimize PLT/GOT entry counting riscv: Add support for PUD THP riscv: xchg: Prefetch the destination word for sc.w riscv: Add ARCH_HAS_PREFETCH[W] support with Zicbop riscv: Add support for Zicbop riscv: Introduce Zicbop instructions riscv/kexec_file: Fix comment in purgatory relocator riscv: kexec_file: Support loading Image binary file riscv: kexec_file: Split the loading of kernel and others riscv: Documentation: add a description about dynamic ftrace riscv: ftrace: support direct call using call_ops riscv: Implement HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS riscv: ftrace: support PREEMPT riscv: add a data fence for CMODX in the kernel mode ... Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
Diffstat (limited to 'kernel/time/tick-common.c')
-rw-r--r--kernel/time/tick-common.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index a47bcf71defc..9a3859443c04 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -509,6 +509,7 @@ void tick_resume(void)
#ifdef CONFIG_SUSPEND
static DEFINE_RAW_SPINLOCK(tick_freeze_lock);
+static DEFINE_WAIT_OVERRIDE_MAP(tick_freeze_map, LD_WAIT_SLEEP);
static unsigned int tick_freeze_depth;
/**
@@ -528,9 +529,22 @@ void tick_freeze(void)
if (tick_freeze_depth == num_online_cpus()) {
trace_suspend_resume(TPS("timekeeping_freeze"),
smp_processor_id(), true);
+ /*
+ * All other CPUs have their interrupts disabled and are
+ * suspended to idle. Other tasks have been frozen so there
+ * is no scheduling happening. This means that there is no
+ * concurrency in the system at this point. Therefore it is
+ * okay to acquire a sleeping lock on PREEMPT_RT, such as a
+ * spinlock, because the lock cannot be held by other CPUs
+ * or threads and acquiring it cannot block.
+ *
+ * Inform lockdep about the situation.
+ */
+ lock_map_acquire_try(&tick_freeze_map);
system_state = SYSTEM_SUSPEND;
sched_clock_suspend();
timekeeping_suspend();
+ lock_map_release(&tick_freeze_map);
} else {
tick_suspend_local();
}
@@ -552,8 +566,16 @@ void tick_unfreeze(void)
raw_spin_lock(&tick_freeze_lock);
if (tick_freeze_depth == num_online_cpus()) {
+ /*
+ * Similar to tick_freeze(). On resumption the first CPU may
+ * acquire uncontended sleeping locks while other CPUs block on
+ * tick_freeze_lock.
+ */
+ lock_map_acquire_try(&tick_freeze_map);
timekeeping_resume();
sched_clock_resume();
+ lock_map_release(&tick_freeze_map);
+
system_state = SYSTEM_RUNNING;
trace_suspend_resume(TPS("timekeeping_freeze"),
smp_processor_id(), false);