On Tue, Sep 01, 2020 at 09:55:47PM +0100, Ionela Voinescu wrote: > Now that the update of the FI scale factor is done in cpufreq core for > selected functions - target(), target_index() and fast_switch(), > we can provide feedback to the task scheduler and architecture code > on whether cpufreq supports FI. > > For this purpose provide an external function to expose whether the > cpufreq drivers support FI, by using a static key. > > The logic behind the enablement of cpufreq-based invariance is as > follows: > - cpufreq-based invariance is disabled by default > - cpufreq-based invariance is enabled if any of the callbacks > above is implemented while the unsupported setpolicy() is not > > The cpufreq_supports_freq_invariance() function only returns whether > cpufreq is instrumented with the arch_set_freq_scale() calls that > result in support for frequency invariance. Due to the lack of knowledge > on whether the implementation of arch_set_freq_scale() actually results > in the setting of a scale factor based on cpufreq information, it is up > to the architecture code to ensure the setting and provision of the > scale factor to the scheduler. > > Signed-off-by: Ionela Voinescu <ionela.voine...@arm.com> > Acked-by: Viresh Kumar <viresh.ku...@linaro.org> > Cc: Rafael J. Wysocki <r...@rjwysocki.net> > Cc: Viresh Kumar <viresh.ku...@linaro.org> > --- > drivers/cpufreq/cpufreq.c | 16 ++++++++++++++++ > include/linux/cpufreq.h | 5 +++++ > 2 files changed, 21 insertions(+) > > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c > index 4d5fe777184a..570bf2ebe9d4 100644 > --- a/drivers/cpufreq/cpufreq.c > +++ b/drivers/cpufreq/cpufreq.c > @@ -61,6 +61,12 @@ static struct cpufreq_driver *cpufreq_driver; > static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); > static DEFINE_RWLOCK(cpufreq_driver_lock); > > +static DEFINE_STATIC_KEY_FALSE(cpufreq_freq_invariance); > +bool cpufreq_supports_freq_invariance(void) > +{ > + return static_branch_likely(&cpufreq_freq_invariance); > +} > + > /* Flag to suspend/resume CPUFreq governors */ > static bool cpufreq_suspended; > > @@ -2720,6 +2726,15 @@ int cpufreq_register_driver(struct cpufreq_driver > *driver_data) > cpufreq_driver = driver_data; > write_unlock_irqrestore(&cpufreq_driver_lock, flags); > > + /* > + * Mark support for the scheduler's frequency invariance engine for > + * drivers that implement target(), target_index() or fast_switch(). > + */ > + if (!cpufreq_driver->setpolicy) { > + static_branch_enable_cpuslocked(&cpufreq_freq_invariance); > + pr_debug("supports frequency invariance"); > + } > + > if (driver_data->setpolicy)
[super nit] while I understand cpufreq_driver = driver_data, it looks odd if 2 consecutive statements refer it with different variables. Or am I confusing myself hugely. -- Regards, Sudeep