From: "Kasagar, Srinidhi" <srinidhi.kasagar@intel.com>
To: Len Brown <lenb@kernel.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
viresh.kumar@linaro.org, Linux PM list <linux-pm@vger.kernel.org>,
vishwesh.m.rudramuni@intel.com, "Brown,
Len" <len.brown@intel.com>,
srinidhi.kasagar@intel.com
Subject: Re: [PATCH v4] cpufreq: Add SFI based cpufreq driver support
Date: Mon, 10 Nov 2014 16:26:06 +0530 [thread overview]
Message-ID: <20141110105606.GA11060@intel-desktop> (raw)
In-Reply-To: <CAJvTdKkUR5OfdEjyhPrh3PzkvPce2aYRT59YhvOGwco-jLSZ=g@mail.gmail.com>
On Fri, Nov 07, 2014 at 01:18:47AM -0500, Len Brown wrote:
> On Tue, Nov 4, 2014 at 12:00 PM, Srinidhi Kasagar
> <srinidhi.kasagar@intel.com> wrote:
> > This adds the SFI based cpu freq driver for some of the Intel's
> > Silvermont based Atom architectures like Z34xx and Z35xx.
> >
> > Signed-off-by: Rudramuni, Vishwesh M <vishwesh.m.rudramuni@intel.com>
> > Signed-off-by: Srinidhi Kasagar <srinidhi.kasagar@intel.com>
> > Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> ...
> >
> > drivers/cpufreq/Kconfig.x86 | 10 ++
> > drivers/cpufreq/Makefile | 1 +
>
> Please update MAINTAINERS to indicate who will maintain this driver.
OK..
[...]
> > +config X86_SFI_CPUFREQ
> > + tristate "SFI Processor P-States driver"
> > + depends on X86_INTEL_MID && SFI
> > + help
> > + This adds a CPUFreq driver for some Silvermont based Intel Atom
> > + platforms (like INTEL_MID) which enumerates processor performance
> > + states through SFI.
>
> s/enumerates/enumerate/
>
> Also, perhaps add the real HW names that are present in the commit message?
Ok, will fix.
[..]
> > +#include <asm/msr.h>
> > +#include <asm/processor.h>
> > +
> > +#define SFI_FREQ_MAX 32
>
> Delete this #define, and the array where it is used.
> Neither are necessary.
>
> > +#define INTEL_MSR_RANGE 0xffff
>
> I see this was copied INTEL_MSR_RANGE from acpi-cpufreq.c, but
> two wrongs don't make a right. Instead it should be something like
>
> msr-index.h
> #define MSR_IA32_PERF_CTL 0x00000199
> +#define INTEL_PERF_CTL_MASK 0xffff
>
> as it is (Intel) architecture generic (and it is a mask, not a range:-)
Yes, make sense..Will fix.
>
> > +#define INTEL_MSR_BUSRATIO_MASK 0xff00
>
> Please delete this #define, and the code that references it.
>
> If this definition were architectural, we'd also see it in msr-index.h
> under the definition of PERF_STATUS msr.
> But it isn't architectural. I don't like seeing it manufactured for this code,
> and I don't like seeing the unreliable PERF_STATUS MSR accessed.
>
> For the driver.get current frequency, it would be better to either
> simply return the last value written to PERF_CTRL, or if you really
> want to get fance, use APERF/MPERF to actually calcuate the frequency,
> like intel_pstate.c does.
> In either case, this #define and the code it references should go.
Yes, can be done. Will fix the code by reading PERF_CTRL MSR rather.
>
> > +
> > +static DEFINE_PER_CPU(struct sfi_cpufreq_data *, drv_data);
> > +static DEFINE_MUTEX(performance_mutex);
> > +static struct sfi_freq_table_entry sfi_cpufreq_array[SFI_FREQ_MAX];
> > +
> > +/* sfi_perf_data is a pointer to percpu data. */
> > +static struct sfi_processor_performance *sfi_perf_data;
> > +static struct cpufreq_driver sfi_cpufreq_driver;
> > +static int sfi_cpufreq_num;
> > +
> > +/* Performance management */
> > +struct sfi_processor_px {
> > + u32 core_frequency; /* megahertz */
> > + u32 transition_latency; /* microseconds */
> > + u32 control; /* control value */
> > +};
>
> delete the definition of sfi_processor_px.
> it is already defined in sfi.h as sfi_freq_table_entry.
Yes, my bad. Not noticed. Thanks. Will reuse it.
[...]
> > +static int parse_freq(struct sfi_table_header *table)
> > +{
> > + struct sfi_table_simple *sb;
> > + struct sfi_freq_table_entry *pentry;
> > + int total_len;
> > +
> > + sb = (struct sfi_table_simple *)table;
> > + if (!sb) {
> > + pr_warn("SFI: Unable to map frequency table\n");
> > + return -ENODEV;
>
> Delete this check, it is impossible for it to execute.
> The calling function, sfi_table_parse()
> already checked for !table.
Yes, the check does not make sense. Will remove.
>
> > + }
> > +
> > + if (!sfi_cpufreq_num) {
>
> Why is there a check for sfi_cpufreq_num?
> Do you expect to find more than one SFI_SIG_FREQ,
> and here you are implementing a policy of using the 1st
> and ignoring the 2nd?
No, will remove it.
>
> > + sfi_cpufreq_num = SFI_GET_NUM_ENTRIES(sb,
> > + struct sfi_freq_table_entry);
> > + pentry = (struct sfi_freq_table_entry *)sb->pentry;
> > + total_len = sfi_cpufreq_num * sizeof(*pentry);
> > + memcpy(sfi_cpufreq_array, pentry, total_len);
>
> you went to the trouble of defining SFI_FREQ_MAX,
> but I don't see a check here to make sure that you are
> not copying over the end of that array...
>
> Why are you copying the entries to sfi_cpu_freq_array[]
> in the first place? Wouldn't it be a better delete
> SFI_FREQ_MAX, delete this copy, and simply read the table
> entries from where they already are?
OK. Will fix.
[...]
> > + performance->state_count = sfi_cpufreq_num;
> > + performance->states =
> > + kmalloc(sizeof(struct sfi_processor_px) * sfi_cpufreq_num,
> > + GFP_KERNEL);
> > + if (!performance->states)
> > + result = -ENOMEM;
>
> don't you mean *return* -ENOMEM?
> If you continue here, below you're going to try to write to the structure
> you just failed to allocate....
>
> But again, unclear you need to allocate this memory in the first place...
The function itself is unnecessary. Will remove it entirely.
>
> > +
> > + /* Populate the P-states info from the SFI table */
> > + for (i = 0; i < sfi_cpufreq_num; i++) {
> > + performance->states[i].core_frequency =
> > + sfi_cpufreq_array[i].freq_mhz;
> > + performance->states[i].transition_latency =
> > + sfi_cpufreq_array[i].latency;
> > + performance->states[i].control =
> > + sfi_cpufreq_array[i].ctrl_val;
> > + pr_debug("State [%d]: core_frequency[%d] transition_latency[%d] control[0x%x]\n",
> > + i,
> > + (u32) performance->states[i].core_frequency,
> > + (u32) performance->states[i].transition_latency,
> > + (u32) performance->states[i].control);
> > + }
> > +
> > + return result;
>
> It really does seem that sfi_processor_get_performance_states()
> can be replaced with 1 line in your parse routine to point
> performance->states to the address of the 0th entry in sfi_freq table.
Right. will fix it too.
>
> > +}
> > +
> > +static int sfi_processor_register_performance(
> > + struct sfi_processor_performance *performance)
> > +{
> > + mutex_lock(&performance_mutex);
> > +
> > + /* parse the freq table from SFI */
> > + sfi_cpufreq_num = 0;
> > + sfi_table_parse(SFI_SIG_FREQ, NULL, NULL, parse_freq);
>
> why do you ignore sfi_table_parse()'s possible error return value?
Let me check. In parse_freq, if i dont check for sb, then it may
not make sense.
>
> > +
> > + sfi_processor_get_performance_states(performance);
>
> again, should look at error return values,
> but even better to delete the called routine entirely.
Yes, will remove the entire routine.
[...]
> > +
> > +static unsigned extract_freq(u32 msr, unsigned int cpu)
>
> delete this routine.
>
> > +{
> > + struct cpufreq_frequency_table *pos;
> > + struct sfi_processor_performance *perf;
> > + struct sfi_cpufreq_data *data = per_cpu(drv_data, cpu);
> > + u32 sfi_ctrl;
> > +
> > + msr &= INTEL_MSR_BUSRATIO_MASK;
> > + perf = data->sfi_data;
> > +
> > + cpufreq_for_each_entry(pos, data->freq_table) {
> > + sfi_ctrl = perf->states[pos->driver_data].control
> > + & INTEL_MSR_BUSRATIO_MASK;
> > + if (sfi_ctrl == msr)
> > + return pos->frequency;
> > + }
> > + return data->freq_table[0].frequency;
> > +}
> > +
> > +static u32 get_cur_val(const struct cpumask *mask)
> > +{
>
> delete this routine
>
> > + u32 val, dummy;
> > +
> > + if (unlikely(cpumask_empty(mask)))
> > + return 0;
> > +
> > + rdmsr_on_cpu(cpumask_any(mask), MSR_IA32_PERF_STATUS, &val, &dummy);
> > +
> > + return val;
> > +}
> > +
> > +static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
> > +{
>
> replace this routine with one that
> simply returns the latest requested freq on that cpu.
> or if you want to get fancy, calculate actual average frequency
> like intel_pstate.c does.
Not sure if in understood correctly. Do you mean I should not
even read from PERF_CTL in get_cur_freq_on_cpu, rather just
return the cached last requested frequency? I'm not sure
of the behavior in case if we offline and online a cpu.
[...]
> > + /* capability check */
> > + if (perf->state_count <= 1) {
>
> yes, I know you copied this from acpi-cpufreq.c, but
> wouldn't it make more sense for register_performance(), which discovers
> the number of states and makes the allocation, to handle this internally
> and simply return success/fail?
Yes, will fix.
srinidhi
next prev parent reply other threads:[~2014-11-10 10:55 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-04 17:00 [PATCH v4] cpufreq: Add SFI based cpufreq driver support Srinidhi Kasagar
2014-11-07 6:18 ` Len Brown
2014-11-10 10:56 ` Kasagar, Srinidhi [this message]
2014-11-10 19:10 ` Len Brown
2014-11-18 5:39 ` Kasagar, Srinidhi
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=20141110105606.GA11060@intel-desktop \
--to=srinidhi.kasagar@intel.com \
--cc=len.brown@intel.com \
--cc=lenb@kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rjw@rjwysocki.net \
--cc=viresh.kumar@linaro.org \
--cc=vishwesh.m.rudramuni@intel.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).