Re: [PATCH] sched/fair: Only apply cpufreq pressure where frequency is invariant
Hongyan Xia <[email protected]>
| Newsgroups | org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm |
|---|---|
| Message-ID | <[email protected]> |
On 8/21/2026 3:39 PM, Jianyong Wu wrote:
> cpufreq pressure lowers a CPU's capacity by the ratio between the highest
> frequency it may reach and the highest one it can reach right now.
> Utilization carries the matching scaling only where the architecture is
> frequency invariant; without it a fully busy CPU accumulates the whole
> SCHED_CAPACITY_SCALE whatever frequency it runs at.
Given how PELT works, anything that is always-running without idle time
under PELT will reach 1024 eventually regardless of invariance.
> Reducing capacity on such a system scales one side of the comparison and
> not the other, and a fully busy CPU ends up reporting more utilization
> than it is credited with being able to run.
Sorry I didn't quite catch what 'comparison' means, and it's fairly
normal for task and CPU utilization to exceed capacity w/ or w/o
invariance. We just manually cap it to CPU capacity in a few places.
Could you be more specific on what the problem is?
> This became reachable with commit d2d5c129d07e ("cpufreq: Make
> cpufreq_update_pressure() fall back to cpuinfo.max_freq"); before it the
> pressure was always zero there. Whether that matters depends on frequency
> invariance rather than on the fallback itself: a system that has it scales
> both sides and is unaffected, while a system that does not scales only the
> capacity.
>
> Fixes: d2d5c129d07e ("cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq")
> Signed-off-by: Jianyong Wu <[email protected]>
> ---
> kernel/sched/fair.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index c19a025d8d68..a163e00c9882 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -5854,10 +5854,17 @@ static inline void util_est_dequeue(struct cfs_rq *cfs_rq,
> static inline unsigned long get_actual_cpu_capacity(int cpu)
> {
> unsigned long capacity = arch_scale_cpu_capacity(cpu);
> + unsigned long pressure = hw_load_avg(cpu_rq(cpu));
>
> - capacity -= max(hw_load_avg(cpu_rq(cpu)), cpufreq_get_pressure(cpu));
> + /*
> + * Utilization only follows frequency where the architecture is
> + * frequency invariant. Elsewhere, lowering the capacity would
> + * scale one side of the comparison and not the other.
> + */
> + if (arch_scale_freq_invariant())
> + pressure = max(pressure, cpufreq_get_pressure(cpu));
>
> - return capacity;
> + return capacity - pressure;
> }
>
> static inline int util_fits_cpu(unsigned long util,