Re: [PATCH v3 2/2] cpufreq: update capacity_freq_ref when the boost state changes
From: Dietmar Eggemann <dietmar.eggemann@arm.com>
Date: 2026-09-17 09:58:04
Also in:
driver-core, linux-pm, linux-riscv, lkml
On 10.09.26 08:34, Oleg Keri wrote:
capacity_freq_ref is latched from policy->cpuinfo.max_freq by init_cpu_capacity_callback() on CPUFREQ_CREATE_POLICY, and never updated afterwards. cpufreq_frequency_table_cpuinfo() excludes CPUFREQ_BOOST_FREQ entries while boost is disabled, so on a system that boots with boost off the latched value is the non-boost maximum. Enabling boost later raises policy->cpuinfo.max_freq but leaves capacity_freq_ref behind. Two things then go wrong on arm64, where the AMU drives frequency invariance. amu_scale_freq_tick() caps the computed scale at SCHED_CAPACITY_SCALE, so a CPU running above capacity_freq_ref saturates at 1024: the scheduler cannot tell a boosted CPU from one at the sustained maximum, and utilisation is underestimated. And
IMHO, this is where the concept of 'cpufreq pressure' on CPU capacity
comes in.
The cpu_capacity value is calculated based on highest_perf. (1)
In case you start with 'boost == 0' nominal_perf might might be lower
than highest_perf.
cpufreq_update_pressure() calculates this value:
cpufreq_pressure = Cmax * (1 - fcapped - fmax) (2)
[ fcapped = policy->max, fmax = capacity_freq_ref ]
Example on RADXA Orion 06 CPU10:
$ grep . /sys/devices/system/cpu/cpu10/acpi_cppc/*
...
/sys/devices/system/cpu/cpu10/acpi_cppc/highest_perf:7876
/sys/devices/system/cpu/cpu10/acpi_cppc/lowest_freq:800
/sys/devices/system/cpu/cpu10/acpi_cppc/lowest_nonlinear_perf:2520
/sys/devices/system/cpu/cpu10/acpi_cppc/lowest_perf:2520
/sys/devices/system/cpu/cpu10/acpi_cppc/nominal_freq:2500
/sys/devices/system/cpu/cpu10/acpi_cppc/nominal_perf:6600 <-- hacked
/sys/devices/system/cpu/cpu10/acpi_cppc/reference_perf:1000
...
# cat /sys/devices/system/cpu/cpu10/cpu_capacity <-- (1)
984
# cat /sys/devices/system/cpu/cpu10/cpufreq/boost
0
dmesg (added log)
[ 8.065337] cpufreq_update_pressure(): policy->related_cpus=[10-11]
policy->max=2500000 pressure=173 <-- (2)
# echo 1 > /sys/devices/system/cpu/cpufreq/boost
# cat /sys/devices/system/cpu/cpu10/cpufreq/boost
1
dmesg (added log)
[38137.194134] cpufreq_update_pressure(): policy->related_cpus=[10-11]
policy->max=3031666 pressure=0 <-- (2)
The task scheduler gets informed via:
get_actual_cpu_capacity(int cpu)
capacity = arch_scale_cpu_capacity(cpu);
capacity -= max(hw_load_avg(cpu_rq(cpu)), cpufreq_get_pressure(cpu));
^^^^^^^^^^^^^^^^^^^^
return capacity;
[...]