From: Arun R Bharadwaj <hidden> Date: 2009-08-26 11:07:30
Hi,
"Cpuidle" is a CPU Power Management infrastrusture which helps manage
idle CPUs in a clean and efficient manner. The architecture can register
its driver (in this case, pseries_idle driver) so that it subscribes for
cpuidle feature. Cpuidle has a set of governors (ladder and menu),
which will decide the best idle state to be chosen for the current situation,
based on heuristics, and calculates the expected residency time
for the current idle state. So based on this, the cpu is put into
the right idle state.
Currently, cpuidle infrasture is exploited by ACPI to choose between
the available ACPI C-states. This patch-set is aimed at enabling
cpuidle for powerpc and provides a sample implementation for pseries.
Currently, in the pseries_dedicated_idle_sleep(), the processor would
poll for a time period, which is called the snooze, and only then it
is ceded, which would put the processor in nap state. Cpuidle aims at
separating this into 2 different idle states. Based on the expected
residency time predicted by the cpuidle governor, the idle state is
chosen directly. So, choosing to enter the nap state directly based on
the decision made by cpuidle would avoid unnecessary snoozing before
entering nap.
This patch-set tries to achieve the above objective by introducing a
pseries processor idle driver called pseries_idle_driver in
arch/powerpc/platform/pseries/processor_idle.c, which implements the
idle loop which would replace the pseries_dedicated_idle_sleep()
when cpuidle is enabled.
Experiment conducted:
----------------------
The following experiment was conducted on a completely idle JS22 blade,
to prove that using cpuidle infrastructure, the amount of nap time increases.
Nap and snooze times were sampled for all the cpus.
For a window of 1000 samples, When cpuidle was enabled,
the total nap time was of the order of a few seconds (5-10s), whereas
the total snooze time was of the order of a few milliseconds(10-30 ms).
When cpuidle infrastructure was disabled and the regular
pseries_dedicated_idle_sleep() idle loop was used, the snooze time itself
was of the order of hundreds of milliseconds. (100 - 500 ms).
This is clearly due to unnecessary snoozing before napping even on a
completely idle system.
The previous post in this area can be found at
http://lkml.org/lkml/2009/8/19/150
Changes from the previous version:
----------------------------------
Earlier I used the the name TPMD (Thermal and Power Management Devices)
to refer to this module which hooks on to the cpuidle infrastructure.
I have renamed this to Pseries Processor Idle, in order to avoid confusion.
Patches included in this set:
------------------------------
PATCH 1/2 - Enable cpuidle for pSeries.
PATCH 2/2 - Implement Pseries Processor Idle idle module
Any feedback on the overall design and idea is immensely valuable.
--arun
From: Arun R Bharadwaj <hidden> Date: 2009-08-26 11:08:59
* Arun R Bharadwaj [off-list ref] [2009-08-26 16:37:21]:
This patch enables the cpuidle option in Kconfig for pSeries.
Currently cpuidle infrastructure is enabled only for x86.
This code is almost completely borrowed from x86 to enable
cpuidle for pSeries.
Signed-off-by: Arun R Bharadwaj <redacted>
---
arch/powerpc/Kconfig | 17 +++++++++++++++++
arch/powerpc/include/asm/system.h | 2 ++
arch/powerpc/platforms/pseries/setup.c | 21 +++++++++++++++++++++
3 files changed, 40 insertions(+)
Index: linux.trees.git/arch/powerpc/Kconfig
===================================================================
@@ -243,6 +246,20 @@ source "kernel/Kconfig.freezer"source"arch/powerpc/sysdev/Kconfig"source"arch/powerpc/platforms/Kconfig"+menu"Power management options"++source"drivers/cpuidle/Kconfig"++configPSERIES_PROCESSOR_IDLE+bool"Idle Power Management Support for pSeries"+depends onPPC_PSERIES&&CPU_IDLE+defaulty+help+IdlePowerManagementSupportforpSeries.Thishooksontocpuidle+infrastructuretohelpinidlecpupowermanagement.++endmenu+menu"Kernel options"configHIGHMEM
@@ -278,6 +278,27 @@ static struct notifier_block pci_dn_reco.notifier_call=pci_dn_reconfig_notifier,};+staticvoiddo_nothing(void*unused)+{+}++/*+*cpu_idle_wait-UsedtoensurethatalltheCPUsdiscardoldvalueof+*pm_idleandupdatetonewpm_idlevalue.Requiredwhilechangingpm_idle+*handleronSMPsystems.+*+*Callermusthavechangedpm_idletothenewvaluebeforethecall.Old+*pm_idlevaluewillnotbeusedbyanyCPUafterthereturnofthisfunction.+*/+voidcpu_idle_wait(void)+{+/* Ensure that new value of pm_idle is set before proceeding */+smp_mb();+/* kick all the CPUs so that they exit out of pm_idle */+smp_call_function(do_nothing,NULL,1);+}+EXPORT_SYMBOL_GPL(cpu_idle_wait);+staticvoid__initpSeries_setup_arch(void){/* Discover PIC type and setup ppc_md accordingly */
From: Arun R Bharadwaj <hidden> Date: 2009-08-26 11:10:12
* Arun R Bharadwaj [off-list ref] [2009-08-26 16:37:21]:
This patch creates arch/powerpc/platforms/pseries/processor_idle.c,
which implements the cpuidle infrastructure for pseries.
It implements a pseries_cpuidle_loop() which would be the main idle loop
called from cpu_idle(). It makes decision of entering either snooze or nap
state based on the decision taken by the cpuidle governor.
Signed-off-by: Arun R Bharadwaj <redacted>
---
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/processor_idle.c | 181 ++++++++++++++++++++++++
arch/powerpc/platforms/pseries/pseries.h | 14 +
arch/powerpc/platforms/pseries/setup.c | 3
4 files changed, 196 insertions(+), 3 deletions(-)
Index: linux.trees.git/arch/powerpc/platforms/pseries/Makefile
===================================================================
Seriously.. this caused plenty problems over on x86 and you're doing the
exact same dumb thing?
Hi Peter,
Cpuidle assumes pm_idle to be the default idle power management
function. So i should either do this, or change the stuff in cpuidle.c
so that it is more abstract.
--arun
Seriously.. this caused plenty problems over on x86 and you're doing the
exact same dumb thing?
Hi Peter,
Cpuidle assumes pm_idle to be the default idle power management
function. So i should either do this, or change the stuff in cpuidle.c
so that it is more abstract.
I would much prefer the latter, I've been telling the x86 power folks to
fix this like forever, but they never seem to get around to it.
They even tried adding a second such unmanaged function pointer for
play-dead, instead of integrating everything into a single management
interface.
Seriously.. this caused plenty problems over on x86 and you're doing the
exact same dumb thing?
I already said I didn't want this export.
First thing first: We already have a ppc_md.power_save() callback,
filled by the platform. which implements the "low level" part of idle on
powerpc (ie, the actual putting of the CPU into some kind of wait state)
and is called by our idle loop.
We -also- have a higher level ppc_md.idle_loop() which allows the
platform to completely override the idle loop, though we rarely do it (I
think only iSeries does it nowadays).
So I see no need to -add- another callback here. I'm not entirely sure
what the cpuidle framework does, it's no obvious from Arun commit
messages I must say, but it doesn't look like the right approach for
integration. In fact, pSeries already have a choice between different
powersave models depending on what kind of hypervisor is there.
So Arun, please try to fit nicely within the existing interfaces, or if
you want to add a new one, please justify very precisely what design
decisions lead you to that.
Finally, there's also a problem with your first patch 1/2: You are
setting a Kconfig flag unconditionally indicating that the arch supports
some idle wait function, but you only implement it somewhere in
arch/powerpc/platform/pseries, so you'll break the build of any other
platform. You also prevent another platform to implement a different one
and be built in the same kernel.
For such generic callbacks, if it's justified (and only if it is), you
can add a ppc_md. hook for the platform to fill, and you need to cater
for platforms that don't.
Cheers,
Ben.