Skip to content

Commit

Permalink
sched/fair: Fix frequency selection for non-invariant case
Browse files Browse the repository at this point in the history
Linus reported a ~50% performance regression on single-threaded
workloads on his AMD Ryzen system, and bisected it to:

  9c0b4bb ("sched/cpufreq: Rework schedutil governor performance estimation")

When frequency invariance is not enabled, get_capacity_ref_freq(policy)
is supposed to return the current frequency and the performance margin
applied by map_util_perf(), enabling the utilization to go above the
maximum compute capacity and to select a higher frequency than the current one.

After the changes in 9c0b4bb, the performance margin was applied
earlier in the path to take into account utilization clampings and
we couldn't get a utilization higher than the maximum compute capacity,
and the CPU remained 'stuck' at lower frequencies.

To fix this, we must use a frequency above the current frequency to
get a chance to select a higher OPP when the current one becomes fully used.
Apply the same margin and return a frequency 25% higher than the current
one in order to switch to the next OPP before we fully use the CPU
at the current one.

[ mingo: Clarified the changelog. ]

Fixes: 9c0b4bb ("sched/cpufreq: Rework schedutil governor performance estimation")
Reported-by: Linus Torvalds <[email protected]>
Bisected-by: Linus Torvalds <[email protected]>
Reported-by: Wyes Karny <[email protected]>
Signed-off-by: Vincent Guittot <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Tested-by: Wyes Karny <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
  • Loading branch information
vingu-linaro authored and Ingo Molnar committed Jan 16, 2024
1 parent bfe8eb3 commit e37617c
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion kernel/sched/cpufreq_schedutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ unsigned long get_capacity_ref_freq(struct cpufreq_policy *policy)
if (arch_scale_freq_invariant())
return policy->cpuinfo.max_freq;

return policy->cur;
/*
* Apply a 25% margin so that we select a higher frequency than
* the current one before the CPU is fully busy:
*/
return policy->cur + (policy->cur >> 2);
}

/**
Expand Down

0 comments on commit e37617c

Please sign in to comment.