Re: [PATCH 2/6] powerpc, powernv, CPU hotplug: Put offline CPUs in Fast-Sleep instead of Nap

2014-06-04 Thread Paul Mackerras
On Wed, May 28, 2014 at 10:08:56AM +0530, Preeti U Murthy wrote:
> From: Srivatsa S. Bhat 
> 
> The offline cpus are put to fast sleep if the idle state is discovered in the
> device tree. This is to gain maximum powersavings in the offline state.

...

>   while (!generic_check_cpu_restart(cpu)) {
>   ppc64_runlatch_off();
> - power7_nap();
> +
> + /* If sleep is supported, go to sleep, instead of nap */
> + if (idle_states & IDLE_USE_SLEEP)
> + power7_sleep();
> + else
> + power7_nap();
> +
>   ppc64_runlatch_on();
>   if (!generic_check_cpu_restart(cpu)) {
>   DBG("CPU%d Unexpected exit while offline !\n", cpu);

What is the latency for waking up from fast sleep state?  I'm concerned
this will increase the latency for entering KVM guests.

Paul.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/6] powerpc, powernv, CPU hotplug: Put offline CPUs in Fast-Sleep instead of Nap

2014-06-04 Thread Paul Mackerras
On Wed, May 28, 2014 at 10:08:56AM +0530, Preeti U Murthy wrote:
 From: Srivatsa S. Bhat srivatsa.b...@linux.vnet.ibm.com
 
 The offline cpus are put to fast sleep if the idle state is discovered in the
 device tree. This is to gain maximum powersavings in the offline state.

...

   while (!generic_check_cpu_restart(cpu)) {
   ppc64_runlatch_off();
 - power7_nap();
 +
 + /* If sleep is supported, go to sleep, instead of nap */
 + if (idle_states  IDLE_USE_SLEEP)
 + power7_sleep();
 + else
 + power7_nap();
 +
   ppc64_runlatch_on();
   if (!generic_check_cpu_restart(cpu)) {
   DBG(CPU%d Unexpected exit while offline !\n, cpu);

What is the latency for waking up from fast sleep state?  I'm concerned
this will increase the latency for entering KVM guests.

Paul.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/6] powerpc, powernv, CPU hotplug: Put offline CPUs in Fast-Sleep instead of Nap

2014-05-27 Thread Preeti U Murthy
From: Srivatsa S. Bhat 

The offline cpus are put to fast sleep if the idle state is discovered in the
device tree. This is to gain maximum powersavings in the offline state.

Signed-off-by: Srivatsa S. Bhat 
[ Changelog added by  ]
Signed-off-by: Preeti U Murthy 
---

 arch/powerpc/include/asm/processor.h |8 +
 arch/powerpc/kernel/idle.c   |   52 ++
 arch/powerpc/platforms/powernv/smp.c |   12 +++-
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index d922e5c..c5256db 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -449,6 +449,14 @@ static inline unsigned long get_clean_sp(unsigned long sp, 
int is_32)
 #define IDLE_INST_NAP  0x0001 /* nap instruction can be used */
 #define IDLE_INST_SLEEP0x0002 /* sleep instruction can be used */
 
+/* Flags to indicate which of the CPU idle states are available for use */
+
+#define IDLE_USE_NAP   (1UL << 0)
+#define IDLE_USE_SLEEP (1UL << 1)
+
+extern unsigned int supported_cpuidle_states;
+extern unsigned int pnv_get_supported_cpuidle_states(void);
+
 extern unsigned long cpuidle_disable;
 enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
 
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index d7216c9..e51d574 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -32,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
@@ -79,6 +81,56 @@ void arch_cpu_idle(void)
ppc64_runlatch_on();
 }
 
+#ifdef CONFIG_PPC_POWERNV
+
+unsigned int supported_cpuidle_states = 0;
+
+unsigned int pnv_get_supported_cpuidle_states(void)
+{
+   return supported_cpuidle_states;
+}
+
+static int __init pnv_probe_idle_states(void)
+{
+   struct device_node *power_mgt;
+   struct property *prop;
+   int dt_idle_states;
+   u32 *flags;
+   int i;
+
+   if (!firmware_has_feature(FW_FEATURE_OPALv3))
+   return 0;
+
+   power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
+   if (!power_mgt) {
+   pr_warn("opal: PowerMgmt Node not found\n");
+   return 0;
+   }
+
+   prop = of_find_property(power_mgt, "ibm,cpu-idle-state-flags", NULL);
+   if (!prop) {
+   pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n");
+   return 0;
+   }
+
+   dt_idle_states = prop->length / sizeof(u32);
+   flags = (u32 *) prop->value;
+
+   for (i = 0; i < dt_idle_states; i++) {
+   if (flags[i] & IDLE_INST_NAP)
+   supported_cpuidle_states |= IDLE_USE_NAP;
+
+   if (flags[i] & IDLE_INST_SLEEP)
+   supported_cpuidle_states |= IDLE_USE_SLEEP;
+   }
+
+   return 0;
+}
+
+__initcall(pnv_probe_idle_states);
+#endif
+
+
 int powersave_nap;
 
 #ifdef CONFIG_SYSCTL
diff --git a/arch/powerpc/platforms/powernv/smp.c 
b/arch/powerpc/platforms/powernv/smp.c
index bf5fcd4..fc83006 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "powernv.h"
 
@@ -142,6 +143,7 @@ static int pnv_smp_cpu_disable(void)
 static void pnv_smp_cpu_kill_self(void)
 {
unsigned int cpu;
+   unsigned long idle_states;
 
/* Standard hot unplug procedure */
local_irq_disable();
@@ -152,13 +154,21 @@ static void pnv_smp_cpu_kill_self(void)
generic_set_cpu_dead(cpu);
smp_wmb();
 
+   idle_states = pnv_get_supported_cpuidle_states();
+
/* We don't want to take decrementer interrupts while we are offline,
 * so clear LPCR:PECE1. We keep PECE2 enabled.
 */
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
while (!generic_check_cpu_restart(cpu)) {
ppc64_runlatch_off();
-   power7_nap();
+
+   /* If sleep is supported, go to sleep, instead of nap */
+   if (idle_states & IDLE_USE_SLEEP)
+   power7_sleep();
+   else
+   power7_nap();
+
ppc64_runlatch_on();
if (!generic_check_cpu_restart(cpu)) {
DBG("CPU%d Unexpected exit while offline !\n", cpu);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/6] powerpc, powernv, CPU hotplug: Put offline CPUs in Fast-Sleep instead of Nap

2014-05-27 Thread Preeti U Murthy
From: Srivatsa S. Bhat srivatsa.b...@linux.vnet.ibm.com

The offline cpus are put to fast sleep if the idle state is discovered in the
device tree. This is to gain maximum powersavings in the offline state.

Signed-off-by: Srivatsa S. Bhat srivatsa.b...@linux.vnet.ibm.com
[ Changelog added by pre...@linux.vnet.ibm.com ]
Signed-off-by: Preeti U Murthy pre...@linux.vnet.ibm.com
---

 arch/powerpc/include/asm/processor.h |8 +
 arch/powerpc/kernel/idle.c   |   52 ++
 arch/powerpc/platforms/powernv/smp.c |   12 +++-
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index d922e5c..c5256db 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -449,6 +449,14 @@ static inline unsigned long get_clean_sp(unsigned long sp, 
int is_32)
 #define IDLE_INST_NAP  0x0001 /* nap instruction can be used */
 #define IDLE_INST_SLEEP0x0002 /* sleep instruction can be used */
 
+/* Flags to indicate which of the CPU idle states are available for use */
+
+#define IDLE_USE_NAP   (1UL  0)
+#define IDLE_USE_SLEEP (1UL  1)
+
+extern unsigned int supported_cpuidle_states;
+extern unsigned int pnv_get_supported_cpuidle_states(void);
+
 extern unsigned long cpuidle_disable;
 enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
 
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index d7216c9..e51d574 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -25,6 +25,7 @@
 #include linux/cpu.h
 #include linux/sysctl.h
 #include linux/tick.h
+#include linux/of.h
 
 #include asm/processor.h
 #include asm/cputable.h
@@ -32,6 +33,7 @@
 #include asm/machdep.h
 #include asm/runlatch.h
 #include asm/smp.h
+#include asm/firmware.h
 
 
 unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
@@ -79,6 +81,56 @@ void arch_cpu_idle(void)
ppc64_runlatch_on();
 }
 
+#ifdef CONFIG_PPC_POWERNV
+
+unsigned int supported_cpuidle_states = 0;
+
+unsigned int pnv_get_supported_cpuidle_states(void)
+{
+   return supported_cpuidle_states;
+}
+
+static int __init pnv_probe_idle_states(void)
+{
+   struct device_node *power_mgt;
+   struct property *prop;
+   int dt_idle_states;
+   u32 *flags;
+   int i;
+
+   if (!firmware_has_feature(FW_FEATURE_OPALv3))
+   return 0;
+
+   power_mgt = of_find_node_by_path(/ibm,opal/power-mgt);
+   if (!power_mgt) {
+   pr_warn(opal: PowerMgmt Node not found\n);
+   return 0;
+   }
+
+   prop = of_find_property(power_mgt, ibm,cpu-idle-state-flags, NULL);
+   if (!prop) {
+   pr_warn(DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n);
+   return 0;
+   }
+
+   dt_idle_states = prop-length / sizeof(u32);
+   flags = (u32 *) prop-value;
+
+   for (i = 0; i  dt_idle_states; i++) {
+   if (flags[i]  IDLE_INST_NAP)
+   supported_cpuidle_states |= IDLE_USE_NAP;
+
+   if (flags[i]  IDLE_INST_SLEEP)
+   supported_cpuidle_states |= IDLE_USE_SLEEP;
+   }
+
+   return 0;
+}
+
+__initcall(pnv_probe_idle_states);
+#endif
+
+
 int powersave_nap;
 
 #ifdef CONFIG_SYSCTL
diff --git a/arch/powerpc/platforms/powernv/smp.c 
b/arch/powerpc/platforms/powernv/smp.c
index bf5fcd4..fc83006 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -31,6 +31,7 @@
 #include asm/xics.h
 #include asm/opal.h
 #include asm/runlatch.h
+#include asm/processor.h
 
 #include powernv.h
 
@@ -142,6 +143,7 @@ static int pnv_smp_cpu_disable(void)
 static void pnv_smp_cpu_kill_self(void)
 {
unsigned int cpu;
+   unsigned long idle_states;
 
/* Standard hot unplug procedure */
local_irq_disable();
@@ -152,13 +154,21 @@ static void pnv_smp_cpu_kill_self(void)
generic_set_cpu_dead(cpu);
smp_wmb();
 
+   idle_states = pnv_get_supported_cpuidle_states();
+
/* We don't want to take decrementer interrupts while we are offline,
 * so clear LPCR:PECE1. We keep PECE2 enabled.
 */
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR)  ~(u64)LPCR_PECE1);
while (!generic_check_cpu_restart(cpu)) {
ppc64_runlatch_off();
-   power7_nap();
+
+   /* If sleep is supported, go to sleep, instead of nap */
+   if (idle_states  IDLE_USE_SLEEP)
+   power7_sleep();
+   else
+   power7_nap();
+
ppc64_runlatch_on();
if (!generic_check_cpu_restart(cpu)) {
DBG(CPU%d Unexpected exit while offline !\n, cpu);

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