| From b3edde44e5d4504c23a176819865cd603fd16d6c Mon Sep 17 00:00:00 2001 |
| From: Vincent Guittot <vincent.guittot@linaro.org> |
| Date: Mon, 11 Dec 2023 11:48:51 +0100 |
| Subject: cpufreq/schedutil: Use a fixed reference frequency |
| |
| From: Vincent Guittot <vincent.guittot@linaro.org> |
| |
| commit b3edde44e5d4504c23a176819865cd603fd16d6c upstream. |
| |
| cpuinfo.max_freq can change at runtime because of boost as an example. This |
| implies that the value could be different than the one that has been |
| used when computing the capacity of a CPU. |
| |
| The new arch_scale_freq_ref() returns a fixed and coherent reference |
| frequency that can be used when computing a frequency based on utilization. |
| |
| Use this arch_scale_freq_ref() when available and fallback to |
| policy otherwise. |
| |
| Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org> |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Tested-by: Lukasz Luba <lukasz.luba@arm.com> |
| Reviewed-by: Lukasz Luba <lukasz.luba@arm.com> |
| Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com> |
| Acked-by: Rafael J. Wysocki <rafael@kernel.org> |
| Acked-by: Viresh Kumar <viresh.kumar@linaro.org> |
| Link: https://lore.kernel.org/r/20231211104855.558096-4-vincent.guittot@linaro.org |
| Stable-dep-of: e37617c8e53a ("sched/fair: Fix frequency selection for non-invariant case") |
| Signed-off-by: Wentao Guan <guanwentao@uniontech.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| kernel/sched/cpufreq_schedutil.c | 26 ++++++++++++++++++++++++-- |
| 1 file changed, 24 insertions(+), 2 deletions(-) |
| |
| --- a/kernel/sched/cpufreq_schedutil.c |
| +++ b/kernel/sched/cpufreq_schedutil.c |
| @@ -138,6 +138,28 @@ static void sugov_deferred_update(struct |
| } |
| |
| /** |
| + * get_capacity_ref_freq - get the reference frequency that has been used to |
| + * correlate frequency and compute capacity for a given cpufreq policy. We use |
| + * the CPU managing it for the arch_scale_freq_ref() call in the function. |
| + * @policy: the cpufreq policy of the CPU in question. |
| + * |
| + * Return: the reference CPU frequency to compute a capacity. |
| + */ |
| +static __always_inline |
| +unsigned long get_capacity_ref_freq(struct cpufreq_policy *policy) |
| +{ |
| + unsigned int freq = arch_scale_freq_ref(policy->cpu); |
| + |
| + if (freq) |
| + return freq; |
| + |
| + if (arch_scale_freq_invariant()) |
| + return policy->cpuinfo.max_freq; |
| + |
| + return policy->cur; |
| +} |
| + |
| +/** |
| * get_next_freq - Compute a new frequency for a given cpufreq policy. |
| * @sg_policy: schedutil policy object to compute the new frequency for. |
| * @util: Current CPU utilization. |
| @@ -163,9 +185,9 @@ static unsigned int get_next_freq(struct |
| unsigned long util, unsigned long max) |
| { |
| struct cpufreq_policy *policy = sg_policy->policy; |
| - unsigned int freq = arch_scale_freq_invariant() ? |
| - policy->cpuinfo.max_freq : policy->cur; |
| + unsigned int freq; |
| |
| + freq = get_capacity_ref_freq(policy); |
| freq = map_util_freq(util, freq, max); |
| |
| if (freq == sg_policy->cached_raw_freq && !sg_policy->need_freq_update) |