[PATCH v2 0/2] sched/cpufreq: fix schedutil's boost frequency handling

Ananthu C V posted 2 patches 2 weeks, 3 days ago
drivers/base/arch_topology.c |  3 ++-
drivers/cpufreq/cpufreq.c    | 14 +++++++++++++-
drivers/cpufreq/freq_table.c | 11 +++++++++++
include/linux/cpufreq.h      |  2 ++
4 files changed, 28 insertions(+), 2 deletions(-)
[PATCH v2 0/2] sched/cpufreq: fix schedutil's boost frequency handling
Posted by Ananthu C V 2 weeks, 3 days ago
Schedutil's ability to reach boost frequencies depends on two values
being correct: policy max, which caps the resolved target frequency,
and the per-CPU capacity frequency reference, which anchors the
utilization-to-frequency mapping.

This series fixes a few gaps in how these values are maintained across
boost transitions:

The per-CPU capacity frequency reference is set once at policy
creation and never updated when boost is enabled afterwards, leaving
schedutil unable to target boost frequencies even at full utilization.
Track the max available (boost inclusive) frequency before policy
comes online and use it to seed the capacity_freq_ref value, allowing
schedutil to utilize the boost frequency values when boost is enabled
later.

The generic boost callback only raises cpuinfo max, never lowers it.
Once boost is enabled, disabling it leaves cpuinfo max pinned at the
boost ceiling, keeping policy max stuck there too. Also track the max
available non-boost frequency and use the newly tracked max values to
control boost frequencies when a frequency table is available, allowing
the frequency to drop back to non boost values on boost disable. In
the absense of a frequency table, the handling will fall back to using
cpuinfo->max_freq, preserving the current behaviour.

Logs below for clear context:
Intermediate values from the time_in_state output and logs from bench
runs are truncated for brevity.

Before fix
----------

boost  policy0  policy12  policy6

0

4454400

4723200

4723200

355200 36958
4454400 650
4588800 0
4723200 0

After fix
---------

boost  policy0  policy12  policy6

0

4454400

4723200

4454400

0

355200 40147
4454400 79
4588800 0
4723200 0

355200 44834
4454400 93
4588800 25
4723200 569

Signed-off-by: Ananthu C V <ananthu.cv@oss.qualcomm.com>
---
Ananthu C V (2):
      arch_topology: seed capacity_freq_ref with boost-aware max freq
      cpufreq: fix schedutil not returning to non-boost freq when boost is disabled

 drivers/base/arch_topology.c |  3 ++-
 drivers/cpufreq/cpufreq.c    | 14 +++++++++++++-
 drivers/cpufreq/freq_table.c | 11 +++++++++++
 include/linux/cpufreq.h      |  2 ++
 4 files changed, 28 insertions(+), 2 deletions(-)
---
base-commit: 32b6ef9a5d0eca44f9cd91f52f4faa89f145a0de
change-id: 20260804-schedutil-boost-frequency-handling-8e6bf2387a4a

Best regards,
-- 
Ananthu C V <ananthu.cv@oss.qualcomm.com>
Re: [PATCH v2 0/2] sched/cpufreq: fix schedutil's boost frequency handling
Posted by Oleg Keri 1 week, 1 day ago
Hi Ananthu,

Tested both patches on a Lenovo Yoga Slim 7x Gen 11 (Glymur,
scmi-cpufreq) on top of next-20260915.

1/2: with boost off at boot the little cores get cpu_capacity=553,
which matches the 4723200 boost maximum as the reference (4032000
would give 647). A workload pinned to cpu6 runs at 4032000 with boost
off and 4723200 with boost on, 3.14 s against 2.50 s.

2/2:

  # cat policy6/scaling_max_freq
  4032000
  # echo 1 > boost
  # cat policy6/scaling_max_freq
  4723200
  # echo 0 > boost
  # cat policy6/scaling_max_freq
  4032000

One observation: policy6/cpuinfo_max_freq still reads 4723200 after
boost is switched off again.

Tested-by: Oleg Keri <okerixx@gmail.com> # Lenovo Yoga Slim 7x Gen 11
Re: [PATCH v2 0/2] sched/cpufreq: fix schedutil's boost frequency handling
Posted by Ananthu C V 4 days, 8 hours ago
Hi Oleg,

On Thu, Sep 17, 2026 at 06:05:06PM +0200, Oleg Keri wrote:
> Hi Ananthu,
> 
> Tested both patches on a Lenovo Yoga Slim 7x Gen 11 (Glymur,
> scmi-cpufreq) on top of next-20260915.
> 
> 1/2: with boost off at boot the little cores get cpu_capacity=553,
> which matches the 4723200 boost maximum as the reference (4032000
> would give 647). A workload pinned to cpu6 runs at 4032000 with boost
> off and 4723200 with boost on, 3.14 s against 2.50 s.
> 
> 2/2:
> 
>   # cat policy6/scaling_max_freq
>   4032000
>   # echo 1 > boost
>   # cat policy6/scaling_max_freq
>   4723200
>   # echo 0 > boost
>   # cat policy6/scaling_max_freq
>   4032000
> 
> One observation: policy6/cpuinfo_max_freq still reads 4723200 after
> boost is switched off again.

cpuinfo->max_freq has a guard that only updates it upwards, so it is not
able to come down. This is by design, to preserve driver set values. That
is what the second patch is trying to work around. Runtime enforcement of
boost frequency handling will try not to rely on cpuinfo_max_freq whenever
possible with this series, allowing the value to come back to a non boost
freq.

> Tested-by: Oleg Keri <okerixx@gmail.com> # Lenovo Yoga Slim 7x Gen 11

Thanks for testing the patches.

Best,
Ananthu
Re: [PATCH v2 0/2] sched/cpufreq: fix schedutil's boost frequency handling
Posted by Dietmar Eggemann 1 week, 4 days ago
On 08.09.26 10:30, Ananthu C V wrote:
> Schedutil's ability to reach boost frequencies depends on two values
> being correct: policy max, which caps the resolved target frequency,
> and the per-CPU capacity frequency reference, which anchors the
> utilization-to-frequency mapping.
> 
> This series fixes a few gaps in how these values are maintained across
> boost transitions:
> 
> The per-CPU capacity frequency reference is set once at policy
> creation and never updated when boost is enabled afterwards, leaving
> schedutil unable to target boost frequencies even at full utilization.
> Track the max available (boost inclusive) frequency before policy
> comes online and use it to seed the capacity_freq_ref value, allowing
> schedutil to utilize the boost frequency values when boost is enabled
> later.
> 
> The generic boost callback only raises cpuinfo max, never lowers it.
> Once boost is enabled, disabling it leaves cpuinfo max pinned at the
> boost ceiling, keeping policy max stuck there too. Also track the max
> available non-boost frequency and use the newly tracked max values to
> control boost frequencies when a frequency table is available, allowing
> the frequency to drop back to non boost values on boost disable. In
> the absense of a frequency table, the handling will fall back to using
> cpuinfo->max_freq, preserving the current behaviour.
> 
> Logs below for clear context:
> Intermediate values from the time_in_state output and logs from bench
> runs are truncated for brevity.
> 
> Before fix
> ----------
> 
> boost  policy0  policy12  policy6
> 
> 0
> 
> 4454400
> 
> 4723200
> 
> 4723200
> 
> 355200 36958
> 4454400 650
> 4588800 0
> 4723200 0
> 
> After fix
> ---------
> 
> boost  policy0  policy12  policy6
> 
> 0
> 
> 4454400
> 
> 4723200
> 
> 4454400
> 
> 0
> 
> 355200 40147
> 4454400 79
> 4588800 0
> 4723200 0
> 
> 355200 44834
> 4454400 93
> 4588800 25
> 4723200 569
> 
> Signed-off-by: Ananthu C V <ananthu.cv@oss.qualcomm.com>
> ---
> Ananthu C V (2):
>       arch_topology: seed capacity_freq_ref with boost-aware max freq
>       cpufreq: fix schedutil not returning to non-boost freq when boost is disabled
> 
>  drivers/base/arch_topology.c |  3 ++-
>  drivers/cpufreq/cpufreq.c    | 14 +++++++++++++-
>  drivers/cpufreq/freq_table.c | 11 +++++++++++
>  include/linux/cpufreq.h      |  2 ++
>  4 files changed, 28 insertions(+), 2 deletions(-)
> ---
> base-commit: 32b6ef9a5d0eca44f9cd91f52f4faa89f145a0de
> change-id: 20260804-schedutil-boost-frequency-handling-8e6bf2387a4a
IMHO, this makes sense, also the coordination via cpufreq_pressure
(policy->max).

On ARM64 Juno R0:

# cat /sys/devices/system/cpu/cpu*/cpu_capacity
446
1024
1024
446
446
446

# cat /sys/devices/system/cpu/cpufreq/boost
0

cat
/sys/devices/system/cpu/cpu{0,1}/cpufreq/scaling_{available,boost}_frequencies
450000 575000 700000
775000 850000
450000 625000 800000
950000 1100000

# cat /sys/devices/system/cpu/cpu{0,1}/cpufreq/cpuinfo_{min,max}_freq
450000
700000
450000
800000

# dmsg | grep policy

[3.323564] cpufreq_update_pressure(): policy->related_cpus=[0,3-5]
policy->max=700000 pressure=102                                      (*)
[3.333206] cpufreq_update_pressure(): policy->related_cpus=[1-2]
policy->max=800000 pressure=280


# echo 1 > /sys/devices/system/cpu/cpufreq/boost

# dmsg | grep policy

[ 1511.188932] policy->related_cpus=[1-2] pressure=0
[ 1511.189050] policy->related_cpus=[0,3-5] pressure=0

# echo 0 > /sys/devices/system/cpu/cpufreq/boost

# dmsg | grep policy

[  204.951039] cpufreq_update_pressure(): policy->related_cpus=[1-2]
policy->max=800000 pressure=280
[  204.951223] cpufreq_update_pressure(): policy->related_cpus=[0,3-5]
policy->max=700000 pressure=79                                       (*)

(*) This is the only small issue I see. The pressure=102 is pressure
based on purely uarch differences (max_capacity(0,3-5)=578) whereas
pressure=79 later is based on uarch + max frequency differences
(max_capacity(0,3-5)=446).
Re: [PATCH v2 0/2] sched/cpufreq: fix schedutil's boost frequency handling
Posted by Ananthu C V 2 weeks, 3 days ago
It seems some mangling was done and all lines starting with hashes
were considered comments and ignored, malforming the logs. Apologies
for that, this is how it's supposed to look :)

Before fix
----------
# cd /sys/devices/system/cpu/cpufreq/
# ls
boost  policy0  policy12  policy6
# cat boost
0
# cat policy6/scaling_max_freq
4454400
# echo 1 > boost
# cat policy6/scaling_max_freq
4723200
# echo 0 > boost
# cat policy6/scaling_max_freq
4723200
4723200

# echo 1 > boost
# cat policy6/stats/time_in_state
355200 36958
4454400 650
4588800 0
4723200 0

After fix
---------
# cd /sys/devices/system/cpu/cpufreq/
# ls
boost  policy0  policy12  policy6
# cat boost
0
# cat policy6/scaling_max_freq
4454400
# echo 1 > boost
# cat policy6/scaling_max_freq
4723200
# echo 0 > policy6/boost
# cat policy6/scaling_max_freq
4454400

# cat policy6/boost
0
# cat policy6/stats/time_in_state
355200 40147
4454400 79
4588800 0
4723200 0
# echo 1 > policy6/boost
# cat policy6/stats/time_in_state
355200 44834
4454400 93
4588800 25
4723200 569

Best,
Ananthu