mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:04:43 +01:00
arm64: topology: Fix false warning in counters_read_on_cpu() for same-CPU reads
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: 997c021abc ("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>
This commit is contained in:
parent
e5cb94ba5f
commit
df6e4ab654
1 changed files with 15 additions and 6 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue