All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steve Muckle <steve.muckle@linaro.org>
To: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Steve Muckle <steve.muckle@linaro.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	Vincent Guittot <vincent.guittot@linaro.org>,
	Morten Rasmussen <morten.rasmussen@arm.com>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	Juri Lelli <Juri.Lelli@arm.com>,
	Patrick Bellasi <patrick.bellasi@arm.com>,
	Michael Turquette <mturquette@baylibre.com>
Subject: Re: [PATCH v2 2/3] cpufreq: acpi-cpufreq: add resolve_freq callback
Date: Mon, 30 May 2016 09:20:27 -0700	[thread overview]
Message-ID: <20160530162027.GF9864@graphite.smuckle.net> (raw)
In-Reply-To: <20160526064341.GV17585@vireshk-i7>

On Thu, May 26, 2016 at 12:13:41PM +0530, Viresh Kumar wrote:
> On 25-05-16, 19:53, Steve Muckle wrote:
> > Support the new resolve_freq cpufreq callback which resolves a target
> > frequency to a driver-supported frequency without actually setting it.
> 
> And here is the first abuser of this API as I was talking about in the
> earlier patch :)
> 
> But, I know why you are doing it and I think we can do it differently.
> 
> So, lets assume that the ->resolve_freq() callback will ONLY be
> provided by the drivers which also provide a ->target() callback.
> 
> i.e. not by acpi-cpufreq at least.
> 
> > The target frequency and resolved frequency table entry are cached so
> > that a subsequent fast_switch operation may avoid the frequency table
> > walk assuming the requested target frequency is the same.
> > 
> > Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > Signed-off-by: Steve Muckle <smuckle@linaro.org>
> > ---
> >  drivers/cpufreq/acpi-cpufreq.c | 56 ++++++++++++++++++++++++++++++++----------
> >  1 file changed, 43 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
> > index 7f38fb55f223..d87962eda1ed 100644
> > --- a/drivers/cpufreq/acpi-cpufreq.c
> > +++ b/drivers/cpufreq/acpi-cpufreq.c
> > @@ -66,6 +66,8 @@ enum {
> >  
> >  struct acpi_cpufreq_data {
> >  	struct cpufreq_frequency_table *freq_table;
> > +	unsigned int cached_lookup_freq;
> > +	struct cpufreq_frequency_table *cached_lookup_entry;
> 
> This could have been an integer value 'Index', which could have been
> used together with the freq-table to get the freq we wanted.
> 
> And, then we can move these two fields into the cpufreq_policy
> structure and make them part of the first patch itself.
> 
> >  	unsigned int resume;
> >  	unsigned int cpu_feature;
> >  	unsigned int acpi_perf_cpu;
> > @@ -458,26 +460,53 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
> >  	return result;
> >  }
> >  
> > -unsigned int acpi_cpufreq_fast_switch(struct cpufreq_policy *policy,
> > -				      unsigned int target_freq)
> > +/*
> > + * Find the closest frequency above target_freq.
> > + *
> > + * The table is sorted in the reverse order with respect to the
> > + * frequency and all of the entries are valid (see the initialization).
> > + */
> > +static inline struct cpufreq_frequency_table
> > +*lookup_freq(struct cpufreq_frequency_table *table, unsigned int target_freq)
> >  {
> > -	struct acpi_cpufreq_data *data = policy->driver_data;
> > -	struct acpi_processor_performance *perf;
> > -	struct cpufreq_frequency_table *entry;
> > -	unsigned int next_perf_state, next_freq, freq;
> > +	struct cpufreq_frequency_table *entry = table;
> > +	unsigned int freq;
> >  
> > -	/*
> > -	 * Find the closest frequency above target_freq.
> > -	 *
> > -	 * The table is sorted in the reverse order with respect to the
> > -	 * frequency and all of the entries are valid (see the initialization).
> > -	 */
> > -	entry = data->freq_table;
> >  	do {
> >  		entry++;
> >  		freq = entry->frequency;
> >  	} while (freq >= target_freq && freq != CPUFREQ_TABLE_END);
> >  	entry--;
> > +
> > +	return entry;
> > +}
> > +
> > +unsigned int acpi_cpufreq_resolve_freq(struct cpufreq_policy *policy,
> > +				       unsigned int target_freq)
> > +{
> > +	struct acpi_cpufreq_data *data = policy->driver_data;
> > +	struct cpufreq_frequency_table *entry;
> > +
> > +	data->cached_lookup_freq = target_freq;
> > +	entry = lookup_freq(data->freq_table, target_freq);
> > +	data->cached_lookup_entry = entry;
> > +
> > +	return entry->frequency;
> > +}
> > +
> 
> And then we could remove this callback from acpi-cpufreq.
> 
> > +unsigned int acpi_cpufreq_fast_switch(struct cpufreq_policy *policy,
> > +				      unsigned int target_freq)
> > +{
> > +	struct acpi_cpufreq_data *data = policy->driver_data;
> > +	struct acpi_processor_performance *perf;
> > +	struct cpufreq_frequency_table *entry;
> > +	unsigned int next_perf_state, next_freq;
> > +
> > +	if (data->cached_lookup_entry &&
> > +	    data->cached_lookup_freq == target_freq)
> > +		entry = data->cached_lookup_entry;
> > +	else
> > +		entry = lookup_freq(data->freq_table, target_freq);
> 
> And a static inline callback in cpufreq.h to get this entry.
> 
> >  	next_freq = entry->frequency;
> >  	next_perf_state = entry->driver_data;
> >  
> > @@ -918,6 +947,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
> >  	.verify		= cpufreq_generic_frequency_table_verify,
> >  	.target_index	= acpi_cpufreq_target,
> >  	.fast_switch	= acpi_cpufreq_fast_switch,
> > +	.resolve_freq	= acpi_cpufreq_resolve_freq,
> >  	.bios_limit	= acpi_processor_get_bios_limit,
> >  	.init		= acpi_cpufreq_cpu_init,
> >  	.exit		= acpi_cpufreq_cpu_exit,
> 
> Sounds reasonable ?

A couple concerns... One is that if we do the lookup in
cpufreq_driver_resolve_freq() for drivers which implement target_index()
then it means using cpufreq_frequency_table_target() there.  This is a
heavier weight function that can't take advantage of driver-specific
knowledge that the freq table is sorted a particular way. So for
acpi-cpufreq we'd now be having to walk the whole table for every
fast_switch.

Another is that it'll be a a bit odd that the logic used to lookup the
driver frequency will be different in the cached and uncached
fast_switch cases. In the cached case it will have been determined by
code in cpufreq_driver_resolve_freq() whereas in the uncached case it
will be logic in the driver, in its fast_switch routine.

I think at least the first issue would need to be solved to use this
approach as it would impact performance for every fast_switch call.

(Thanks for the review btw!)

thanks,
Steve

  reply	other threads:[~2016-05-30 16:20 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-26  2:52 [PATCH v2 0/3] cpufreq: avoid redundant driver calls in schedutil Steve Muckle
2016-05-26  2:52 ` [PATCH v2 1/3] cpufreq: add resolve_freq driver callback Steve Muckle
2016-05-26  6:25   ` Viresh Kumar
2016-05-30 15:31     ` Steve Muckle
2016-05-31  5:30       ` Viresh Kumar
2016-05-31 18:48         ` Steve Muckle
2016-05-31 11:14   ` Viresh Kumar
2016-05-31 18:12     ` Steve Muckle
2016-05-26  2:53 ` [PATCH v2 2/3] cpufreq: acpi-cpufreq: add resolve_freq callback Steve Muckle
2016-05-26  6:43   ` Viresh Kumar
2016-05-30 16:20     ` Steve Muckle [this message]
2016-05-31 11:38       ` Viresh Kumar
2016-05-26  2:53 ` [PATCH v2 3/3] cpufreq: schedutil: map raw required frequency to driver frequency Steve Muckle
2016-05-26  7:16   ` Viresh Kumar
2016-05-29  0:40     ` Rafael J. Wysocki
2016-05-30 10:18       ` Viresh Kumar
2016-05-30 14:25         ` Rafael J. Wysocki
2016-05-30 15:32           ` Viresh Kumar
2016-05-30 19:08             ` Rafael J. Wysocki
2016-05-31  9:02             ` Peter Zijlstra
2016-05-31  1:49           ` Wanpeng Li
2016-05-30 16:35     ` Steve Muckle
2016-06-01 10:50       ` Viresh Kumar
2016-05-27  5:41   ` Wanpeng Li
2016-05-30 16:48     ` Steve Muckle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160530162027.GF9864@graphite.smuckle.net \
    --to=steve.muckle@linaro.org \
    --cc=Juri.Lelli@arm.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=morten.rasmussen@arm.com \
    --cc=mturquette@baylibre.com \
    --cc=patrick.bellasi@arm.com \
    --cc=peterz@infradead.org \
    --cc=rafael@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=viresh.kumar@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.