[PATCHv2] omap2+: pm: cpufreq: Fix loops_per_jiffy calculation
Colin Cross
ccross at google.com
Tue Jun 28 18:29:57 EDT 2011
<resending as plain text>
On Fri, Jun 24, 2011 at 6:53 AM, Sanjeev Premi <premi at ti.com> wrote:
>
> Currently, loops_per_jiffy is being calculated twice for
> non-SMP processors.
> - Before calling cpufreq_notify_transition()
> - From within cpufreq_notify_transition()
>
> Double adjustment leads to incorrect value being assigned to
> loops_per_jiffy. This manifests as incorrect BogoMIPS in
> "cat /proc/cpuinfo".
>
> The value of loops_per_jiffy needs to be calculated only
> when CONFIG_SMP is true. It is the core change included
> in this patch.
>
> The patch also leverages the definition of for_each_cpu()
> with and without CONFIG_SMP to consolidate the mechanism
> to call cpufreq_notify_transition().
>
> Signed-off-by: Sanjeev Premi <premi at ti.com>
> ---
> Changes since v1:
> * loops_per_jiffy are updated when CONFIG_SMP is true.
> * leverage definition of for_each_cpu()
>
> Tested on OMAP3EVM with and without CONFIG_SMP.
> Since the log is rather long, will be posting the log in
> a follow-up mail.
>
> arch/arm/mach-omap2/omap2plus-cpufreq.c | 27 +++++++++++++++------------
> 1 files changed, 15 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
> index 346519e..0263cae 100644
> --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
> +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
> @@ -97,12 +97,8 @@ static int omap_target(struct cpufreq_policy *policy,
> return ret;
>
> /* Notify transitions */
> - if (is_smp()) {
> - for_each_cpu(i, policy->cpus) {
> - freqs.cpu = i;
> - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
> - }
> - } else {
> + for_each_cpu(i, policy->cpus) {
> + freqs.cpu = i;
> cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
> }
>
> @@ -114,13 +110,20 @@ static int omap_target(struct cpufreq_policy *policy,
>
> freqs.new = omap_getspeed(policy->cpu);
>
> +#ifdef CONFIG_SMP
> + /* Adjust jiffies before transition */
> + for_each_cpu(i, policy->cpus) {
> + unsigned long lpj = per_cpu(cpu_data, i).loops_per_jiffy;
> +
> + per_cpu(cpu_data, i).loops_per_jiffy = cpufreq_scale(lpj,
> + freqs.old,
> + freqs.new);
Can't this rewrite the loops_per_jiffy for the other CPU while it is
in a udelay? If it has already calculated the number of loops
necessary, and the CPU frequency increases, it could end up returning
too early from udelay.
There were previous discussions about polling a fixed-frequency timer
for udelay on SMP systems.
> + }
> +#endif
> +
> /* Notify transitions */
> - if (is_smp()) {
> - for_each_cpu(i, policy->cpus) {
> - freqs.cpu = i;
> - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> - }
> - } else {
> + for_each_cpu(i, policy->cpus) {
> + freqs.cpu = i;
> cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> }
>
> --
> 1.7.2.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the linux-arm-kernel
mailing list