[RFC/PATCH 3/3] cpuidle/pseries: Add stop0lite state

Gautham R. Shenoy ego at linux.vnet.ibm.com
Tue Mar 31 23:10:58 AEDT 2020


From: "Gautham R. Shenoy" <ego at linux.vnet.ibm.com>

The POWER ISA v3.0 allows stop instruction to be executed from a
HV=0,PR=0 context. If the PSSCR[ESL|EC] bits are cleared, then the
stop instruction thus executed will cause the thread to pause, thereby
donating its cycles to the other threads in the core until the paused
thread is woken up by an interrupt.

In this patch we define a cpuidle state for pseries guests named
stop0lite. This has a latency and residency intermediate to that of
snooze and CEDE. While snooze has non-existent latency, it consumes
the CPU cycles without contributing to anything useful. CEDE on the
other hand requires a full VM exit, which can result in some other
vCPU being scheduled on this physical CPU thereby delaying the
scheduling of the CEDEd vCPU back. In such cases, when the expected
idle duration is small (1-20us), the vCPU can go to this stop0lite
state which provides a nice intermediate state between snooze and
CEDE.

Signed-off-by: Gautham R. Shenoy <ego at linux.vnet.ibm.com>
---
 drivers/cpuidle/cpuidle-pseries.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c
index 74c2479..9c8c18d 100644
--- a/drivers/cpuidle/cpuidle-pseries.c
+++ b/drivers/cpuidle/cpuidle-pseries.c
@@ -20,6 +20,7 @@
 #include <asm/firmware.h>
 #include <asm/runlatch.h>
 #include <asm/plpar_wrappers.h>
+#include <asm/processor.h>
 
 struct cpuidle_driver pseries_idle_driver = {
 	.name             = "pseries_idle",
@@ -170,6 +171,26 @@ static int shared_cede_loop(struct cpuidle_device *dev,
 		.enter = &dedicated_cede_loop },
 };
 
+
+
+static int stop_loop(struct cpuidle_device *dev,
+		     struct cpuidle_driver *drv,
+		     int index)
+{
+	unsigned long srr1 = 0;
+
+	if (!prep_irq_for_idle_irqsoff())
+		return index;
+
+	__ppc64_runlatch_off();
+	asm volatile("stop");
+	__ppc64_runlatch_on();
+	fini_irq_for_idle_irqsoff();
+	irq_set_pending_from_srr1(srr1);
+
+	return index;
+}
+
 /*
  * States for shared partition case.
  */
@@ -180,6 +201,12 @@ static int shared_cede_loop(struct cpuidle_device *dev,
 		.exit_latency = 0,
 		.target_residency = 0,
 		.enter = &snooze_loop },
+	{ /* stop0_lite */
+		.name = "stop0lite",
+		.desc = "Pauses the CPU",
+		.exit_latency = 2,
+		.target_residency=20,
+		.enter = &stop_loop },
 	{ /* Shared Cede */
 		.name = "Shared Cede",
 		.desc = "Shared Cede",
-- 
1.9.4



More information about the Linuxppc-dev mailing list