diff mbox

CPUFREQ: Add the suspend/resume flag to avoid smp_call in cpufreq_suspend/resume

Message ID 1248399463.3556.30.camel@localhost.localdomain (mailing list archive)
State RFC, archived
Headers show

Commit Message

Zhao, Yakui July 24, 2009, 1:37 a.m. UTC
Subject: [CPUFREQ]: Add the suspend/resume flag to avoid smp_call in cpufreq_suspend/resume 
From: Zhao Yakui <yakui.zhao@intel.com>

Only CPU0 is available in course of cpufreq_suspend/resume.
So it is unnecessary to do the smp_call for getting the current
cpufreq.

Add a flag of suspend/resume to avoid the smp_call in course of
cpufreq_suspend/resume.

http://bugzilla.kernel.org/show_bug.cgi?id=13781
http://bugzilla.kernel.org/show_bug.cgi?id=13269

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Tested-by: Christian Casteyde<casteyde.christian@free.fr>
---
 arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c  |   24 +++++++++++++++++++++---
 arch/x86/kernel/cpu/cpufreq/powernow-k8.c   |   13 ++++++++++++-
 arch/x86/kernel/cpu/cpufreq/speedstep-ich.c |   12 ++++++++++--
 drivers/cpufreq/cpufreq.c                   |    7 +++++++
 include/linux/cpufreq.h                     |    2 ++
 5 files changed, 52 insertions(+), 6 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Dave Jones July 24, 2009, 1:49 a.m. UTC | #1
On Fri, Jul 24, 2009 at 09:37:43AM +0800, ykzhao wrote:
 > Subject: [CPUFREQ]: Add the suspend/resume flag to avoid smp_call in cpufreq_suspend/resume 
 > From: Zhao Yakui <yakui.zhao@intel.com>
 > 
 > Only CPU0 is available in course of cpufreq_suspend/resume.
 > So it is unnecessary to do the smp_call for getting the current
 > cpufreq.
 > 
 > Add a flag of suspend/resume to avoid the smp_call in course of
 > cpufreq_suspend/resume.
 > 
 > http://bugzilla.kernel.org/show_bug.cgi?id=13781
 > http://bugzilla.kernel.org/show_bug.cgi?id=13269
 > 
 > Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
 > Tested-by: Christian Casteyde<casteyde.christian@free.fr>

All this goes away if we just made that suspend/resume code
conditional on powerpc as previously discussed.

We don't need any of it on x86 afaict

	Dave
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Zhao, Yakui July 24, 2009, 5:18 a.m. UTC | #2
On Fri, 2009-07-24 at 09:49 +0800, Dave Jones wrote:
> On Fri, Jul 24, 2009 at 09:37:43AM +0800, ykzhao wrote:
>  > Subject: [CPUFREQ]: Add the suspend/resume flag to avoid smp_call in cpufreq_suspend/resume 
>  > From: Zhao Yakui <yakui.zhao@intel.com>
>  > 
>  > Only CPU0 is available in course of cpufreq_suspend/resume.
>  > So it is unnecessary to do the smp_call for getting the current
>  > cpufreq.
>  > 
>  > Add a flag of suspend/resume to avoid the smp_call in course of
>  > cpufreq_suspend/resume.
>  > 
>  > http://bugzilla.kernel.org/show_bug.cgi?id=13781
>  > http://bugzilla.kernel.org/show_bug.cgi?id=13269
>  > 
>  > Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
>  > Tested-by: Christian Casteyde<casteyde.christian@free.fr>
> 
> All this goes away if we just made that suspend/resume code
> conditional on powerpc as previously discussed.
Do you mean that this issue exists on powerpc platform?
How to resolve this issue on the Powerpc according to the discussion?
Where can I get the patch?
thanks.
> 
> We don't need any of it on x86 afaict
> 
> 	Dave

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Zhao, Yakui July 28, 2009, 1:40 a.m. UTC | #3
On Fri, 2009-07-24 at 09:49 +0800, Dave Jones wrote:
> On Fri, Jul 24, 2009 at 09:37:43AM +0800, ykzhao wrote:
>  > Subject: [CPUFREQ]: Add the suspend/resume flag to avoid smp_call in cpufreq_suspend/resume 
>  > From: Zhao Yakui <yakui.zhao@intel.com>
>  > 
>  > Only CPU0 is available in course of cpufreq_suspend/resume.
>  > So it is unnecessary to do the smp_call for getting the current
>  > cpufreq.
>  > 
>  > Add a flag of suspend/resume to avoid the smp_call in course of
>  > cpufreq_suspend/resume.
>  > 
>  > http://bugzilla.kernel.org/show_bug.cgi?id=13781
>  > http://bugzilla.kernel.org/show_bug.cgi?id=13269
>  > 
>  > Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
>  > Tested-by: Christian Casteyde<casteyde.christian@free.fr>
> 
> All this goes away if we just made that suspend/resume code
> conditional on powerpc as previously discussed.
Hi, Dave
    Will you please point out what we should do to fix the issue son x86
similar to that on powerpc?
    
    Is the patch mentioned already shipped in upstream kernel?

thanks.
> 
> We don't need any of it on x86 afaict
> 
> 	Dave

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

Index: linux-2.6/drivers/cpufreq/cpufreq.c
===================================================================
--- linux-2.6.orig/drivers/cpufreq/cpufreq.c	2009-07-23 09:23:36.000000000 +0800
+++ linux-2.6/drivers/cpufreq/cpufreq.c	2009-07-24 09:08:27.000000000 +0800
@@ -1266,6 +1266,9 @@ 
 	/* only handle each CPU group once */
 	if (unlikely(cpu_policy->cpu != cpu))
 		goto out;
+	/* Set the flag of suspend/resume */
+	if (!cpufreq_driver->suspend_resume)
+		cpufreq_driver->suspend_resume = 1;
 
 	if (cpufreq_driver->suspend) {
 		ret = cpufreq_driver->suspend(cpu_policy, pmsg);
@@ -1391,6 +1394,10 @@ 
 	schedule_work(&cpu_policy->update);
 fail:
 	cpufreq_cpu_put(cpu_policy);
+	/* clear the flag of suspend/resume */
+	if (cpufreq_driver->suspend_resume)
+		cpufreq_driver->suspend_resume = 0;
+
 	return ret;
 }
 
Index: linux-2.6/include/linux/cpufreq.h
===================================================================
--- linux-2.6.orig/include/linux/cpufreq.h	2009-07-09 13:03:11.000000000 +0800
+++ linux-2.6/include/linux/cpufreq.h	2009-07-24 09:08:27.000000000 +0800
@@ -234,6 +234,8 @@ 
 	int	(*suspend)	(struct cpufreq_policy *policy, pm_message_t pmsg);
 	int	(*resume)	(struct cpufreq_policy *policy);
 	struct freq_attr	**attr;
+	int			suspend_resume; /* indicates whether it is
+						 * suspend/resume */
 };
 
 /* flags */
Index: linux-2.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2009-07-09 13:07:06.000000000 +0800
+++ linux-2.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2009-07-24 09:08:27.000000000 +0800
@@ -197,19 +197,37 @@ 
 
 static void drv_read(struct drv_cmd *cmd)
 {
-	cmd->val = 0;
+	struct cpufreq_driver *freq_driver;
 
-	smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1);
+	freq_driver = &acpi_cpufreq_driver;
+	cmd->val = 0;
+	/*
+	 * In fact only CPU0 is availabe in course of sysdev_suspend/resume.
+	 * So do it on the current cpu directly
+	 */
+	if (!freq_driver->suspend_resume)
+		smp_call_function_single(cpumask_any(cmd->mask),
+				do_drv_read, cmd, 1);
+	else
+		do_drv_read(cmd);
 }
 
 static void drv_write(struct drv_cmd *cmd)
 {
+	struct cpufreq_driver *freq_driver;
 	int this_cpu;
 
 	this_cpu = get_cpu();
+	freq_driver = &acpi_cpufreq_driver;
 	if (cpumask_test_cpu(this_cpu, cmd->mask))
 		do_drv_write(cmd);
-	smp_call_function_many(cmd->mask, do_drv_write, cmd, 1);
+
+	/*
+	 * Only CPU0 is available in course of sysdev_suspend/resume.
+	 * Don't use the smp call again when it is in suspend/resume.
+	 */
+	if (!freq_driver->suspend_resume)
+		smp_call_function_many(cmd->mask, do_drv_write, cmd, 1);
 	put_cpu();
 }
 
Index: linux-2.6/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2009-07-23 09:23:36.000000000 +0800
+++ linux-2.6/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2009-07-24 09:08:27.000000000 +0800
@@ -53,6 +53,7 @@ 
 static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
 
 static int cpu_family = CPU_OPTERON;
+static struct cpufreq_driver cpufreq_amd64_driver;
 
 #ifndef CONFIG_SMP
 static inline const struct cpumask *cpu_core_mask(int cpu)
@@ -1388,11 +1389,21 @@ 
 	struct powernow_k8_data *data = per_cpu(powernow_data, cpu);
 	unsigned int khz = 0;
 	int err;
+	struct cpufreq_driver *freq_driver = &cpufreq_amd64_driver;
 
 	if (!data)
 		return -EINVAL;
 
-	smp_call_function_single(cpu, query_values_on_cpu, &err, true);
+	/*
+	 * Only CPU0 is available in course of sysdev_suspend/resume.
+	 * So do it on the current cpu directly in course of
+	 * sysdev_suspend/resume.
+	 */
+	if (!freq_driver->suspend_resume)
+		smp_call_function_single(cpu, query_values_on_cpu, &err, true);
+	else
+		query_values_on_cpu(&err);
+
 	if (err)
 		goto out;
 
Index: linux-2.6/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2009-07-09 13:07:08.000000000 +0800
+++ linux-2.6/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2009-07-24 09:08:27.000000000 +0800
@@ -41,6 +41,8 @@ 
  */
 static unsigned int speedstep_processor;
 
+static struct cpufreq_driver speedstep_driver;
+
 static u32 pmbase;
 
 /*
@@ -246,11 +248,17 @@ 
 
 static unsigned int speedstep_get(unsigned int cpu)
 {
+	struct cpufreq_driver *freq_driver = &speedstep_driver;
 	struct get_freq_data data = { .processor = cpu };
 
+	/* In fact only CPU0 is available in course of sysdev_suspend/resume.
+	 * So do it on the current cpu directly
+	 */
+	if (freq_driver->suspend_resume)
+		get_freq_data(&data);
 	/* You're supposed to ensure CPU is online. */
-	if (smp_call_function_single(cpu, get_freq_data, &data, 1) != 0)
-		BUG();
+	else
+		smp_call_function_single(cpu, get_freq_data, &data, 1);
 
 	dprintk("detected %u kHz as current frequency\n", data.speed);
 	return data.speed;