]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64: topology: Fix false warning in counters_read_on_cpu() for same-CPU reads
authorSumit Gupta <sumitg@nvidia.com>
Thu, 26 Feb 2026 11:59:11 +0000 (17:29 +0530)
committerWill Deacon <will@kernel.org>
Thu, 26 Feb 2026 18:27:15 +0000 (18:27 +0000)
The counters_read_on_cpu() function warns when called with IRQs
disabled to prevent deadlock in smp_call_function_single(). However,
this warning is spurious when reading counters on the current CPU,
since no IPI is needed for same CPU reads.

Commit 12eb8f4fff24 ("cpufreq: CPPC: Update FIE arch_freq_scale in
ticks for non-PCC regs") changed the CPPC Frequency Invariance Engine
to read AMU counters directly from the scheduler tick for non-PCC
register spaces (like FFH), instead of deferring to a kthread. This
means counters_read_on_cpu() is now called with IRQs disabled from the
tick handler, triggering the warning.

Fix this by restructuring the logic: when IRQs are disabled (tick
context), call the function directly for same-CPU reads. Otherwise
use smp_call_function_single().

Fixes: 997c021abc6e ("cpufreq: CPPC: Update FIE arch_freq_scale in ticks for non-PCC regs")
Suggested-by: Will Deacon <will@kernel.org>
Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kernel/topology.c

index 3fe1faab03620e783e405b7959dc81338085df1a..b32f13358fbb1becde3d0945a6e3eba286628f5d 100644 (file)
@@ -400,16 +400,25 @@ static inline
 int counters_read_on_cpu(int cpu, smp_call_func_t func, u64 *val)
 {
        /*
-        * Abort call on counterless CPU or when interrupts are
-        * disabled - can lead to deadlock in smp sync call.
+        * Abort call on counterless CPU.
         */
        if (!cpu_has_amu_feat(cpu))
                return -EOPNOTSUPP;
 
-       if (WARN_ON_ONCE(irqs_disabled()))
-               return -EPERM;
-
-       smp_call_function_single(cpu, func, val, 1);
+       if (irqs_disabled()) {
+               /*
+                * When IRQs are disabled (tick path: sched_tick ->
+                * topology_scale_freq_tick or cppc_scale_freq_tick), only local
+                * CPU counter reads are allowed. Remote CPU counter read would
+                * require smp_call_function_single() which is unsafe with IRQs
+                * disabled.
+                */
+               if (WARN_ON_ONCE(cpu != smp_processor_id()))
+                       return -EPERM;
+               func(val);
+       } else {
+               smp_call_function_single(cpu, func, val, 1);
+       }
 
        return 0;
 }