This patch series ports the cpuidle framework for ppc64 platform and
implements a cpuidle back-end driver for ppc64 (pSeries) platform.
Currently idle states are managed by pseries_{dedicated,shared}_idle_sleep()
routines in arch/powerpc/platforms/pseries/setup.c. There are
two idle states (snooze and cede) that are exploited by
these routines based on simple heuristics.
Moving the idle states over to cpuidle framework can take advantage of
the advanced heuristics, tunables, and features provided by cpuidle
framework. Additional idle states like extended cede with hints would be
included and exploited using the cpuidle framework. The statistics and
tracing infrastructure provided by the cpuidle framework also helps in
enabling power management related tools and help tune the system and
applications.
This series aims to maintain compatibility and functionality to
existing pSeries idle cpu management code. There are no new functions
or idle states added as part of this series.
The previous version of this patch can be found at
https://lkml.org/lkml/2011/6/7/375
Changes from the previous version (v1):
1] Rebased to latest 3.2-rc2
2] Incorporated the changes from the feedback provided by Ben
in the previous version of this series.
3] The first three patches in this series posted in v1 are not
re-posted as they were taken from "idle cleanup - v3" posted by
Len Brown (https://lkml.org/lkml/2011/4/2/8) which have made
to the mainline in 3.1.
This cleanup was a community requirement and major dependency
before cpuidle framework can be ported over to powerpc
architecture.
This patch series includes:
[1/4] - Provides arch specific cpu_idle_wait() function required by cpuidle
subsystem.
[2/4] - pseries_idle cpuidle driver
[3/4] - Enables cpuidle for pSeries and directly calls cpuidle_idle_call()
[4/4] - Handles powersave=off kernel boot parameter and disables registration
of pseries_idle cpuidle driver.
This series has been tested on ppc64 pSeries POWER7 system with the snooze
and cede states
--
arch/powerpc/Kconfig | 4
arch/powerpc/include/asm/processor.h | 3
arch/powerpc/include/asm/system.h | 9 +
arch/powerpc/kernel/idle.c | 26 ++
arch/powerpc/kernel/sysfs.c | 2
arch/powerpc/platforms/Kconfig | 6
arch/powerpc/platforms/pseries/Kconfig | 9 +
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/processor_idle.c | 321 +++++++++++++++++++++++
arch/powerpc/platforms/pseries/pseries.h | 3
arch/powerpc/platforms/pseries/setup.c | 89 ------
arch/powerpc/platforms/pseries/smp.c | 1
include/linux/cpuidle.h | 2
13 files changed, 387 insertions(+), 89 deletions(-)
create mode 100644 arch/powerpc/platforms/pseries/processor_idle.c
-Deepthi
This patch provides cpu_idle_wait() routine for the powerpc
platform which is required by the cpuidle subsystem. This
routine is requied to change the idle handler on SMP systems.
The equivalent routine for x86 is in arch/x86/kernel/process.c
but the powerpc implementation is different.
Signed-off-by: Deepthi Dharwar <redacted>
Signed-off-by: Trinabh Gupta <redacted>
Signed-off-by: Arun R Bharadwaj <redacted>
---
arch/powerpc/Kconfig | 4 ++++
arch/powerpc/include/asm/processor.h | 2 ++
arch/powerpc/include/asm/system.h | 1 +
arch/powerpc/kernel/idle.c | 26 ++++++++++++++++++++++++++
4 files changed, 33 insertions(+), 0 deletions(-)
@@ -221,6 +221,7 @@ extern unsigned long klimit;externvoid*zalloc_maybe_bootmem(size_tsize,gfp_tmask);externintpowersave_nap;/* set if nap mode can be used in idle loop */+voidcpu_idle_wait(void);/**Atomicexchange
@@ -102,6 +106,28 @@ void cpu_idle(void)}}++/*+*cpu_idle_wait-UsedtoensurethatalltheCPUscomeoutoftheold+*idleloopandstartusingthenewidleloop.+*RequiredwhilechangingidlehandleronSMPsystems.+*Callermusthavechangedidlehandlertothenewvaluebeforethecall.+*/+voidcpu_idle_wait(void)+{+intcpu;+smp_mb();++/* kick all the CPUs so that they exit out of old idle routine */+get_online_cpus();+for_each_online_cpu(cpu){+if(cpu!=smp_processor_id())+smp_send_reschedule(cpu);+}+put_online_cpus();+}+EXPORT_SYMBOL_GPL(cpu_idle_wait);+intpowersave_nap;#ifdef CONFIG_SYSCTL
This patch implements a backhand cpuidle driver for pSeries
based on pseries_dedicated_idle_loop and pseries_shared_idle_loop
routines. The driver is built only if CONFIG_CPU_IDLE is set. This
cpuidle driver uses global registration of idle states and
not per-cpu.
Signed-off-by: Deepthi Dharwar <redacted>
Signed-off-by: Trinabh Gupta <redacted>
Signed-off-by: Arun R Bharadwaj <redacted>
---
arch/powerpc/include/asm/system.h | 8 +
arch/powerpc/kernel/sysfs.c | 2
arch/powerpc/platforms/pseries/Kconfig | 9 +
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/processor_idle.c | 317 +++++++++++++++++++++++
arch/powerpc/platforms/pseries/pseries.h | 3
arch/powerpc/platforms/pseries/setup.c | 3
arch/powerpc/platforms/pseries/smp.c | 1
8 files changed, 341 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/platforms/pseries/processor_idle.c
@@ -223,6 +223,14 @@ extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);externintpowersave_nap;/* set if nap mode can be used in idle loop */voidcpu_idle_wait(void);+#ifdef CONFIG_PSERIES_IDLE+externvoidupdate_smt_snooze_delay(intsnooze);+externintpseries_notify_cpuidle_add_cpu(intcpu);+#else+staticinlinevoidupdate_smt_snooze_delay(intsnooze){}+staticinlineintpseries_notify_cpuidle_add_cpu(intcpu){return0;}+#endif+/**Atomicexchange*
This patch enables cpuidle for pSeries and cpuidle_idle_call() is
directly called from the idle loop. As a result pseries_idle cpuidle
driver registered with cpuidle subsystem comes into action. This patch
also removes the routines pseries_shared_idle_sleep and
pseries_dedicated_idle_sleep as they are now implemented as part of
pseries_idle cpuidle driver.
Signed-off-by: Deepthi Dharwar <redacted>
Signed-off-by: Trinabh Gupta <redacted>
Signed-off-by: Arun R Bharadwaj <redacted>
---
arch/powerpc/platforms/Kconfig | 6 ++
arch/powerpc/platforms/pseries/setup.c | 86 +-------------------------------
include/linux/cpuidle.h | 2 -
3 files changed, 8 insertions(+), 86 deletions(-)
@@ -74,9 +75,6 @@ EXPORT_SYMBOL(CMO_PageSize);intfwnmi_active;/* TRUE if an FWNMI handler is present */-staticvoidpseries_shared_idle_sleep(void);-staticvoidpseries_dedicated_idle_sleep(void);-staticstructdevice_node*pSeries_mpic_node;staticvoidpSeries_show_cpuinfo(structseq_file*m)
This patch makes pseries_idle_driver not to be registered when
power_save=off kernel boot option is specified. The
boot_option_idle_override variable used here is similar to
its usage on x86.
Signed-off-by: Deepthi Dharwar <redacted>
Signed-off-by: Trinabh Gupta <redacted>
Signed-off-by: Arun R Bharadwaj <redacted>
---
arch/powerpc/include/asm/processor.h | 1 +
arch/powerpc/platforms/pseries/processor_idle.c | 4 ++++
2 files changed, 5 insertions(+), 0 deletions(-)
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2011-11-27 22:48:38
On Thu, 2011-11-17 at 16:58 +0530, Deepthi Dharwar wrote:
This patch provides cpu_idle_wait() routine for the powerpc
platform which is required by the cpuidle subsystem. This
routine is requied to change the idle handler on SMP systems.
The equivalent routine for x86 is in arch/x86/kernel/process.c
but the powerpc implementation is different.
Signed-off-by: Deepthi Dharwar <redacted>
Signed-off-by: Trinabh Gupta <redacted>
Signed-off-by: Arun R Bharadwaj <redacted>
---
No, that patch also adds this idle boot override thing (can you pick a
shorter name for boot_option_idle_override btw ?) which seems unrelated
and without any explanation as to what it's supposed to be about.
Additionally, I'm a bit worried (but maybe we already discussed that a
while back, I don't know) but cpu_idle_wait() has "wait" in the name,
which makes me think it might need to actually -wait- for all cpus to
have come out of the function.
Now your implementation doesn't provide that guarantee. It might be
fine, I don't know, but if it is, you'd better document it well in the
comments surrounding the code, because as it is, all you do is shoot an
interrupt which will cause the target CPU to eventually come out of idle
some time in the future.
Cheers,
Ben.
@@ -221,6 +221,7 @@ extern unsigned long klimit;externvoid*zalloc_maybe_bootmem(size_tsize,gfp_tmask);externintpowersave_nap;/* set if nap mode can be used in idle loop */+voidcpu_idle_wait(void);/**Atomicexchange
@@ -102,6 +106,28 @@ void cpu_idle(void)}}++/*+*cpu_idle_wait-UsedtoensurethatalltheCPUscomeoutoftheold+*idleloopandstartusingthenewidleloop.+*RequiredwhilechangingidlehandleronSMPsystems.+*Callermusthavechangedidlehandlertothenewvaluebeforethecall.+*/+voidcpu_idle_wait(void)+{+intcpu;+smp_mb();++/* kick all the CPUs so that they exit out of old idle routine */+get_online_cpus();+for_each_online_cpu(cpu){+if(cpu!=smp_processor_id())+smp_send_reschedule(cpu);+}+put_online_cpus();+}+EXPORT_SYMBOL_GPL(cpu_idle_wait);+intpowersave_nap;#ifdef CONFIG_SYSCTL
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2011-11-27 23:03:43
On Thu, 2011-11-17 at 16:58 +0530, Deepthi Dharwar wrote:
This patch implements a backhand cpuidle driver for pSeries
based on pseries_dedicated_idle_loop and pseries_shared_idle_loop
routines. The driver is built only if CONFIG_CPU_IDLE is set. This
cpuidle driver uses global registration of idle states and
not per-cpu.
Shorter name please. pseries_cpuidle_devs is fine.
+static struct cpuidle_state *cpuidle_state_table;
+
+void update_smt_snooze_delay(int snooze)
+{
+ struct cpuidle_driver *drv = cpuidle_get_driver();
+ if (drv)
+ drv->states[0].target_residency = snooze;
+}
+
+static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
+{
+
+ *kt_before = ktime_get_real();
+ *in_purr = mfspr(SPRN_PURR);
+ /*
+ * Indicate to the HV that we are idle. Now would be
+ * a good time to find other work to dispatch.
+ */
+ get_lppaca()->idle = 1;
+ get_lppaca()->donate_dedicated_cpu = 1;
+}
I notice that you call this on shared processors as well. The old ocde
used to not set donate_dedicated_cpu in that case. I assume that's not a
big deal and that the HV will just ignore it in the shared processor
case but please add a comment after you've verified it.
So your snooze loop has no timeout, is that handled by the cpuidle
driver using some kind of timer ? That sounds a lot less efficient than
passing a max delay to the snooze loop to handle getting into a deeper
state after a bit of snoozing rather than interrupting etc...
Don't even printk here, this will happen on all !pseries machines and
the debug output isn't useful. Also move the check of max-cstate to
after the splpar test.
Overall, I quite like these patches, my comments are all pretty minor,
hopefully the next round should be the one.
Cheers,
Ben.
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2011-11-27 23:05:45
On Thu, 2011-11-17 at 16:58 +0530, Deepthi Dharwar wrote:
quoted hunk
This patch enables cpuidle for pSeries and cpuidle_idle_call() is
directly called from the idle loop. As a result pseries_idle cpuidle
driver registered with cpuidle subsystem comes into action. This patch
also removes the routines pseries_shared_idle_sleep and
pseries_dedicated_idle_sleep as they are now implemented as part of
pseries_idle cpuidle driver.
Signed-off-by: Deepthi Dharwar <redacted>
Signed-off-by: Trinabh Gupta <redacted>
Signed-off-by: Arun R Bharadwaj <redacted>
---
arch/powerpc/platforms/Kconfig | 6 ++
arch/powerpc/platforms/pseries/setup.c | 86 +-------------------------------
include/linux/cpuidle.h | 2 -
3 files changed, 8 insertions(+), 86 deletions(-)
@@ -74,9 +75,6 @@ EXPORT_SYMBOL(CMO_PageSize);intfwnmi_active;/* TRUE if an FWNMI handler is present */-staticvoidpseries_shared_idle_sleep(void);-staticvoidpseries_dedicated_idle_sleep(void);-staticstructdevice_node*pSeries_mpic_node;staticvoidpSeries_show_cpuinfo(structseq_file*m)
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2011-11-27 23:07:26
On Thu, 2011-11-17 at 16:59 +0530, Deepthi Dharwar wrote:
This patch makes pseries_idle_driver not to be registered when
power_save=off kernel boot option is specified. The
boot_option_idle_override variable used here is similar to
its usage on x86.
Quick Q. With your changes, the CPU will never get into idle at all
until cpuidle initializes and the driver loads.
That means not only much later in the boot process, but potentially
never if the distro has the driver as a module and fails to load it, or
similar.
Can't that be an issue ? Shouldn't we keep at least one of the basic
idle functions as a fallback ?
Cheers,
Ben.
Hi Ben,
Thanks a lot for the review.
On 11/28/2011 04:18 AM, Benjamin Herrenschmidt wrote:
On Thu, 2011-11-17 at 16:58 +0530, Deepthi Dharwar wrote:
quoted
This patch provides cpu_idle_wait() routine for the powerpc
platform which is required by the cpuidle subsystem. This
routine is requied to change the idle handler on SMP systems.
The equivalent routine for x86 is in arch/x86/kernel/process.c
but the powerpc implementation is different.
Signed-off-by: Deepthi Dharwar <redacted>
Signed-off-by: Trinabh Gupta <redacted>
Signed-off-by: Arun R Bharadwaj <redacted>
---
No, that patch also adds this idle boot override thing (can you pick a
shorter name for boot_option_idle_override btw ?) which seems unrelated
and without any explanation as to what it's supposed to be about.
Yes, we can pick a better and shorter name for this variable.
This variable is used to determine if cpuidle framework
needs to be enabled and pseries_driver to be loaded or not.
We disable cpuidle framework only when powersave_off option is set or
not enabled by the user.
Additionally, I'm a bit worried (but maybe we already discussed that a
while back, I don't know) but cpu_idle_wait() has "wait" in the name,
which makes me think it might need to actually -wait- for all cpus to
have come out of the function.
cpu_idle_wait is used to ensure that all the CPUs discard old idle
handler and update to new one. Required while changing idle
handler on SMP systems.
Now your implementation doesn't provide that guarantee. It might be
fine, I don't know, but if it is, you'd better document it well in the
comments surrounding the code, because as it is, all you do is shoot an
interrupt which will cause the target CPU to eventually come out of idle
some time in the future.
I was hoping that sending an explicit reschedule to the cpus would
do the trick but sure we can add some documentation around the code.
@@ -221,6 +221,7 @@ extern unsigned long klimit;externvoid*zalloc_maybe_bootmem(size_tsize,gfp_tmask);externintpowersave_nap;/* set if nap mode can be used in idle loop */+voidcpu_idle_wait(void);/**Atomicexchange
@@ -102,6 +106,28 @@ void cpu_idle(void)}}++/*+*cpu_idle_wait-UsedtoensurethatalltheCPUscomeoutoftheold+*idleloopandstartusingthenewidleloop.+*RequiredwhilechangingidlehandleronSMPsystems.+*Callermusthavechangedidlehandlertothenewvaluebeforethecall.+*/+voidcpu_idle_wait(void)+{+intcpu;+smp_mb();++/* kick all the CPUs so that they exit out of old idle routine */+get_online_cpus();+for_each_online_cpu(cpu){+if(cpu!=smp_processor_id())+smp_send_reschedule(cpu);+}+put_online_cpus();+}+EXPORT_SYMBOL_GPL(cpu_idle_wait);+intpowersave_nap;#ifdef CONFIG_SYSCTL
On 11/28/2011 04:33 AM, Benjamin Herrenschmidt wrote:
On Thu, 2011-11-17 at 16:58 +0530, Deepthi Dharwar wrote:
quoted
This patch implements a backhand cpuidle driver for pSeries
based on pseries_dedicated_idle_loop and pseries_shared_idle_loop
routines. The driver is built only if CONFIG_CPU_IDLE is set. This
cpuidle driver uses global registration of idle states and
not per-cpu.
Shorter name please. pseries_cpuidle_devs is fine.
I ll do so.
quoted
+static struct cpuidle_state *cpuidle_state_table;
+
+void update_smt_snooze_delay(int snooze)
+{
+ struct cpuidle_driver *drv = cpuidle_get_driver();
+ if (drv)
+ drv->states[0].target_residency = snooze;
+}
+
+static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
+{
+
+ *kt_before = ktime_get_real();
+ *in_purr = mfspr(SPRN_PURR);
+ /*
+ * Indicate to the HV that we are idle. Now would be
+ * a good time to find other work to dispatch.
+ */
+ get_lppaca()->idle = 1;
+ get_lppaca()->donate_dedicated_cpu = 1;
+}
I notice that you call this on shared processors as well. The old ocde
used to not set donate_dedicated_cpu in that case. I assume that's not a
big deal and that the HV will just ignore it in the shared processor
case but please add a comment after you've verified it.
Yes, the old code does not set donate_dedicated_cpu. But yes I will
try testing it in a shared proc config but also remove this
initialization for shared idle loop.
So your snooze loop has no timeout, is that handled by the cpuidle
driver using some kind of timer ? That sounds a lot less efficient than
passing a max delay to the snooze loop to handle getting into a deeper
state after a bit of snoozing rather than interrupting etc...
My bad, snooze_loop is essential for a time out. Nope cpuidle
driver doesn't have any timer mechanism. I ll fix it.
Need to add loop for snooze time.
Don't even printk here, this will happen on all !pseries machines and
the debug output isn't useful. Also move the check of max-cstate to
after the splpar test.
I ll move the check above.
Overall, I quite like these patches, my comments are all pretty minor,
hopefully the next round should be the one.
On 11/28/2011 04:35 AM, Benjamin Herrenschmidt wrote:
On Thu, 2011-11-17 at 16:58 +0530, Deepthi Dharwar wrote:
quoted
This patch enables cpuidle for pSeries and cpuidle_idle_call() is
directly called from the idle loop. As a result pseries_idle cpuidle
driver registered with cpuidle subsystem comes into action. This patch
also removes the routines pseries_shared_idle_sleep and
pseries_dedicated_idle_sleep as they are now implemented as part of
pseries_idle cpuidle driver.
Signed-off-by: Deepthi Dharwar <redacted>
Signed-off-by: Trinabh Gupta <redacted>
Signed-off-by: Arun R Bharadwaj <redacted>
---
arch/powerpc/platforms/Kconfig | 6 ++
arch/powerpc/platforms/pseries/setup.c | 86 +-------------------------------
include/linux/cpuidle.h | 2 -
3 files changed, 8 insertions(+), 86 deletions(-)
@@ -74,9 +75,6 @@ EXPORT_SYMBOL(CMO_PageSize);intfwnmi_active;/* TRUE if an FWNMI handler is present */-staticvoidpseries_shared_idle_sleep(void);-staticvoidpseries_dedicated_idle_sleep(void);-staticstructdevice_node*pSeries_mpic_node;staticvoidpSeries_show_cpuinfo(structseq_file*m)
On 11/28/2011 04:37 AM, Benjamin Herrenschmidt wrote:
On Thu, 2011-11-17 at 16:59 +0530, Deepthi Dharwar wrote:
quoted
This patch makes pseries_idle_driver not to be registered when
power_save=off kernel boot option is specified. The
boot_option_idle_override variable used here is similar to
its usage on x86.
Quick Q. With your changes, the CPU will never get into idle at all
until cpuidle initializes and the driver loads.
That means not only much later in the boot process, but potentially
never if the distro has the driver as a module and fails to load it, or
similar.
Can't that be an issue ? Shouldn't we keep at least one of the basic
idle functions as a fallback ?
On an LPAR if cpuidle is disabled, ppc_md.power_save is still set to
cpuidle_idle_call by default here. This would result in calling of
cpuidle_idle_call repeatedly, only for the call to return -ENODEV. The
default idle is never executed.
This would be a major design flaw. No fallback idle routine.
We propose to fix this by checking the return value of
ppc_md.power_save() call from void to int.
Right now return value is void, but if we change this to int, this
would solve two problems. One being removing the cast to a function
pointer in the prev patch and this design flaw stated above.
So by checking the return value of ppc_md.power_save(), we can invoke
the default idle on failure. But my only concern is about the effects of
changing the ppc_md.power_save() to return int on other powerpc
architectures. Would it be a good idea to change the return type to int
which would help us flag an error and fallback to default idle?
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2011-11-28 20:40:49
On Mon, 2011-11-28 at 16:32 +0530, Deepthi Dharwar wrote:
quoted
Additionally, I'm a bit worried (but maybe we already discussed that a
while back, I don't know) but cpu_idle_wait() has "wait" in the name,
which makes me think it might need to actually -wait- for all cpus to
have come out of the function.
cpu_idle_wait is used to ensure that all the CPUs discard old idle
handler and update to new one. Required while changing idle
handler on SMP systems.
quoted
Now your implementation doesn't provide that guarantee. It might be
fine, I don't know, but if it is, you'd better document it well in the
comments surrounding the code, because as it is, all you do is shoot an
interrupt which will cause the target CPU to eventually come out of idle
some time in the future.
I was hoping that sending an explicit reschedule to the cpus would
do the trick but sure we can add some documentation around the code.
Well, the question is what guarantee do you expect. Sending a reschedule
IPI will take the other CPUs out of the actual sleep mode, but it will
be some time from there back to getting out of the handler function
(first back out of hypervisor etc...).
The code as you implemented it doesn't wait for that to happen. It might
be fine ... or not. I don't know what semantics you are after precisely.
Cheers,
Ben.
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2011-11-28 20:41:44
On Mon, 2011-11-28 at 16:33 +0530, Deepthi Dharwar wrote:
On an LPAR if cpuidle is disabled, ppc_md.power_save is still set to
cpuidle_idle_call by default here. This would result in calling of
cpuidle_idle_call repeatedly, only for the call to return -ENODEV. The
default idle is never executed.
This would be a major design flaw. No fallback idle routine.
We propose to fix this by checking the return value of
ppc_md.power_save() call from void to int.
Right now return value is void, but if we change this to int, this
would solve two problems. One being removing the cast to a function
pointer in the prev patch and this design flaw stated above.
So by checking the return value of ppc_md.power_save(), we can invoke
the default idle on failure. But my only concern is about the effects of
changing the ppc_md.power_save() to return int on other powerpc
architectures. Would it be a good idea to change the return type to int
which would help us flag an error and fallback to default idle?
I would have preferred an approach where the cpuidle module sets
ppc_md.power_save when loaded and restores it when unloaded ... but that
would have to go into the cpuidle core as a powerpc specific tweak and
might not be generally well received.
So go for it, add the return value, but you'll have to update all the
idle functions (grep for power_save in arch/powerpc to find them).
Cheers,
Ben.
On 11/29/2011 02:05 AM, Benjamin Herrenschmidt wrote:
On Mon, 2011-11-28 at 16:32 +0530, Deepthi Dharwar wrote:
quoted
quoted
Additionally, I'm a bit worried (but maybe we already discussed that a
while back, I don't know) but cpu_idle_wait() has "wait" in the name,
which makes me think it might need to actually -wait- for all cpus to
have come out of the function.
cpu_idle_wait is used to ensure that all the CPUs discard old idle
handler and update to new one. Required while changing idle
handler on SMP systems.
quoted
Now your implementation doesn't provide that guarantee. It might be
fine, I don't know, but if it is, you'd better document it well in the
comments surrounding the code, because as it is, all you do is shoot an
interrupt which will cause the target CPU to eventually come out of idle
some time in the future.
I was hoping that sending an explicit reschedule to the cpus would
do the trick but sure we can add some documentation around the code.
Well, the question is what guarantee do you expect. Sending a reschedule
IPI will take the other CPUs out of the actual sleep mode, but it will
be some time from there back to getting out of the handler function
(first back out of hypervisor etc...).
The code as you implemented it doesn't wait for that to happen. It might
be fine ... or not. I don't know what semantics you are after precisely.
Cheers,
Ben.
Yes, this could be problematic as there is small window for the
race condition to occur . Otherwise we need to manually schedule
it by running a kernel thread but this would definitely have a
overhead and would be an overkill.
Regards,
Deepthi
On 11/29/2011 02:09 AM, Benjamin Herrenschmidt wrote:
On Mon, 2011-11-28 at 16:33 +0530, Deepthi Dharwar wrote:
quoted
On an LPAR if cpuidle is disabled, ppc_md.power_save is still set to
cpuidle_idle_call by default here. This would result in calling of
cpuidle_idle_call repeatedly, only for the call to return -ENODEV. The
default idle is never executed.
This would be a major design flaw. No fallback idle routine.
We propose to fix this by checking the return value of
ppc_md.power_save() call from void to int.
Right now return value is void, but if we change this to int, this
would solve two problems. One being removing the cast to a function
pointer in the prev patch and this design flaw stated above.
So by checking the return value of ppc_md.power_save(), we can invoke
the default idle on failure. But my only concern is about the effects of
changing the ppc_md.power_save() to return int on other powerpc
architectures. Would it be a good idea to change the return type to int
which would help us flag an error and fallback to default idle?
I would have preferred an approach where the cpuidle module sets
ppc_md.power_save when loaded and restores it when unloaded ... but that
would have to go into the cpuidle core as a powerpc specific tweak and
might not be generally well received.
So go for it, add the return value, but you'll have to update all the
idle functions (grep for power_save in arch/powerpc to find them).
Thanks Ben. Yes, I will update all the idle functions under powerpc.
I will re-work these patches with the discussed changes.
Regards,
Deepthi
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2011-11-29 07:04:20
On Tue, 2011-11-29 at 12:12 +0530, Deepthi Dharwar wrote:
Yes, this could be problematic as there is small window for the
race condition to occur . Otherwise we need to manually schedule
it by running a kernel thread but this would definitely have a
overhead and would be an overkill.
Depends what this "window" is. IE. What are you trying to protect
yourself against ? What's the risk ?
If it's just module unload, then stop_machine is probably your
friend :-)
Cheers,
Ben.
On 11/29/2011 12:31 PM, Benjamin Herrenschmidt wrote:
On Tue, 2011-11-29 at 12:12 +0530, Deepthi Dharwar wrote:
quoted
Yes, this could be problematic as there is small window for the
race condition to occur . Otherwise we need to manually schedule
it by running a kernel thread but this would definitely have a
overhead and would be an overkill.
Depends what this "window" is. IE. What are you trying to protect
yourself against ? What's the risk ?
If it's just module unload, then stop_machine is probably your
friend :-)
Cheers,
Ben.
Yup, it is the module unload that I am worried about. Otherwise
manually doing it using kernel thread would be an overkill -:(
Regards,
Deepthi
On 11/29/2011 02:09 AM, Benjamin Herrenschmidt wrote:
quoted
On Mon, 2011-11-28 at 16:33 +0530, Deepthi Dharwar wrote:
quoted
On an LPAR if cpuidle is disabled, ppc_md.power_save is still set to
cpuidle_idle_call by default here. This would result in calling of
cpuidle_idle_call repeatedly, only for the call to return -ENODEV. The
default idle is never executed.
This would be a major design flaw. No fallback idle routine.
We propose to fix this by checking the return value of
ppc_md.power_save() call from void to int.
Right now return value is void, but if we change this to int, this
would solve two problems. One being removing the cast to a function
pointer in the prev patch and this design flaw stated above.
kernel/idle.c: ppc_md.power_save = NULL;
quoted
quoted
So by checking the return value of ppc_md.power_save(), we can invoke
the default idle on failure. But my only concern is about the effects of
changing the ppc_md.power_save() to return int on other powerpc
architectures. Would it be a good idea to change the return type to int
which would help us flag an error and fallback to default idle?
I would have preferred an approach where the cpuidle module sets
ppc_md.power_save when loaded and restores it when unloaded ... but that
would have to go into the cpuidle core as a powerpc specific tweak and
might not be generally well received.
So go for it, add the return value, but you'll have to update all the
idle functions (grep for power_save in arch/powerpc to find them).
Thanks Ben. Yes, I will update all the idle functions under powerpc.
I will re-work these patches with the discussed changes.
Regards,
Deepthi
_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
Hi Ben,
I was trying to add a return value for power_save for all arch/powepc
idle functions but a few of them directly call *.S routines, as they
are asm.
What would be a good way to change the return value for asm routines ?
Do we make a change in asm only, put the return value in r3 or write a
wrapper function which would call these asm routines and return an int ?
Regards,
Deepthi
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2011-11-30 04:52:57
On Wed, 2011-11-30 at 06:55 +0530, Deepthi Dharwar wrote:
I was trying to add a return value for power_save for all arch/powepc
idle functions but a few of them directly call *.S routines, as they
are asm.
What would be a good way to change the return value for asm
routines ?
Do we make a change in asm only, put the return value in r3 or write a
wrapper function which would call these asm routines and return an
int ?
No, add li r3,0 at the end, but beware that their return point might not
be ovbvious since we often return from an interrupt which modifies the
return address ... Let me know if there's some you can't figure out and
I'll help you.
Cheers,
Ben.