Message ID | 20231018162540.667646-4-vincent.guittot@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | consolidate and cleanup CPU capacity | expand |
On Wed, Oct 18, 2023 at 6:25 PM Vincent Guittot <vincent.guittot@linaro.org> wrote: > > 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> > Reviewed-by: Lukasz Luba <lukasz.luba@arm.com> > Tested-by: Lukasz Luba <lukasz.luba@arm.com> Acked-by: Rafael J. Wysocki <rafael@kernel.org> > > --- > kernel/sched/cpufreq_schedutil.c | 26 ++++++++++++++++++++++++-- > 1 file changed, 24 insertions(+), 2 deletions(-) > > diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c > index 458d359f5991..6e4030482ae8 100644 > --- a/kernel/sched/cpufreq_schedutil.c > +++ b/kernel/sched/cpufreq_schedutil.c > @@ -114,6 +114,28 @@ static void sugov_deferred_update(struct sugov_policy *sg_policy) > } > } > > +/** > + * cpufreq_get_capacity_ref_freq - get the reference frequency of a given CPU that > + * has been used to correlate frequency and compute capacity. > + * @policy: the cpufreq policy of the CPU in question. > + * @use_current: Fallback to current freq instead of policy->cpuinfo.max_freq. > + * > + * 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. > @@ -140,10 +162,10 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, > 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; > > util = map_util_perf(util); > + 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) > -- > 2.34.1 >
On Wed, Oct 18, 2023 at 06:25:37PM +0200, Vincent Guittot wrote: > +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; > +} Hmm, what should x86 do here? I know it mostly doesn't use these things, but would it make sense to stick the base frequency in ?
On Wed, 25 Oct 2023 at 13:53, Peter Zijlstra <peterz@infradead.org> wrote: > > On Wed, Oct 18, 2023 at 06:25:37PM +0200, Vincent Guittot wrote: > > > +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; > > +} > > Hmm, what should x86 do here? I know it mostly doesn't use these things, > but would it make sense to stick the base frequency in ? get_capacity_ref_freq() should return the frequency that is used as the reference for the max compute capacity. On Arm64, we have seen some inconsistency especially because we use the energy model, we compute the CPU's capacity at boot and we can have different compute capacity in our system whereas x86 always uses SCHED_CAPACITY_SCALE even on hybrid system if I'm not wrong So I was not sure that this will make any difference for x86 platform > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
On 18/10/2023 18:25, Vincent Guittot wrote: > 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> > Reviewed-by: Lukasz Luba <lukasz.luba@arm.com> > Tested-by: Lukasz Luba <lukasz.luba@arm.com> > > --- > kernel/sched/cpufreq_schedutil.c | 26 ++++++++++++++++++++++++-- > 1 file changed, 24 insertions(+), 2 deletions(-) > > diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c > index 458d359f5991..6e4030482ae8 100644 > --- a/kernel/sched/cpufreq_schedutil.c > +++ b/kernel/sched/cpufreq_schedutil.c > @@ -114,6 +114,28 @@ static void sugov_deferred_update(struct sugov_policy *sg_policy) > } > } > > +/** > + * cpufreq_get_capacity_ref_freq - get the reference frequency of a given CPU that s/cpufreq_get_capacity_ref_freq/get_capacity_ref_freq s/of a given CPU/for a given cpufreq policy ? (of which the CPU managing it is used for the arch_scale_freq_ref() call in the function. > + * has been used to correlate frequency and compute capacity. > + * @policy: the cpufreq policy of the CPU in question. > + * @use_current: Fallback to current freq instead of policy->cpuinfo.max_freq. Looks like use_current does not exists as a parameter. > + * > + * 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; > +} Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
On Wed, 25 Oct 2023 at 22:13, Dietmar Eggemann <dietmar.eggemann@arm.com> wrote: > > On 18/10/2023 18:25, Vincent Guittot wrote: > > 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> > > Reviewed-by: Lukasz Luba <lukasz.luba@arm.com> > > Tested-by: Lukasz Luba <lukasz.luba@arm.com> > > > > --- > > kernel/sched/cpufreq_schedutil.c | 26 ++++++++++++++++++++++++-- > > 1 file changed, 24 insertions(+), 2 deletions(-) > > > > diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c > > index 458d359f5991..6e4030482ae8 100644 > > --- a/kernel/sched/cpufreq_schedutil.c > > +++ b/kernel/sched/cpufreq_schedutil.c > > @@ -114,6 +114,28 @@ static void sugov_deferred_update(struct sugov_policy *sg_policy) > > } > > } > > > > +/** > > + * cpufreq_get_capacity_ref_freq - get the reference frequency of a given CPU that > > s/cpufreq_get_capacity_ref_freq/get_capacity_ref_freq > > s/of a given CPU/for a given cpufreq policy ? (of which the CPU managing > it is used for the arch_scale_freq_ref() call in the function. > > > + * has been used to correlate frequency and compute capacity. > > + * @policy: the cpufreq policy of the CPU in question. > > + * @use_current: Fallback to current freq instead of policy->cpuinfo.max_freq. > > Looks like use_current does not exists as a parameter. Thanks for the review. I'm going to apply your comments > > > + * > > + * 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; > > +} > > Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com> > > >
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 458d359f5991..6e4030482ae8 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -114,6 +114,28 @@ static void sugov_deferred_update(struct sugov_policy *sg_policy) } } +/** + * cpufreq_get_capacity_ref_freq - get the reference frequency of a given CPU that + * has been used to correlate frequency and compute capacity. + * @policy: the cpufreq policy of the CPU in question. + * @use_current: Fallback to current freq instead of policy->cpuinfo.max_freq. + * + * 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. @@ -140,10 +162,10 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, 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; util = map_util_perf(util); + 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)