[PATCH v3 2/2] cpufreq: update capacity_freq_ref when the boost state changes
Dietmar Eggemann
dietmar.eggemann at arm.com
Thu Sep 17 02:57:57 PDT 2026
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;
[...]
More information about the linux-arm-kernel
mailing list