svn commit: r334259 - in head/sys/powerpc: include powerpc

Justin Hibbits jhibbits at FreeBSD.org
Sun May 27 20:24:25 UTC 2018


Author: jhibbits
Date: Sun May 27 20:24:24 2018
New Revision: 334259
URL: https://svnweb.freebsd.org/changeset/base/334259

Log:
  Stop idle threads on power9 in the idle task until an interrupt.
  
  This reduces the CPU cycle wastage on power9, which is SMT4.  Any idle
  thread that's spinning is simply starving working threads on the same core
  of valuable resources.
  
  This can be reduced further by taking more advantage of the PSSCR supported
  states, as well as permitting state loss, as is currently done for power8.
  The currently implemented stop state is the lowest latency, which may still
  consume resources.

Modified:
  head/sys/powerpc/include/spr.h
  head/sys/powerpc/powerpc/cpu.c

Modified: head/sys/powerpc/include/spr.h
==============================================================================
--- head/sys/powerpc/include/spr.h	Sun May 27 19:27:34 2018	(r334258)
+++ head/sys/powerpc/include/spr.h	Sun May 27 20:24:24 2018	(r334259)
@@ -383,6 +383,7 @@
 #define	SPR_MD_CAM		0x338	/* ..8 IMMU CAM entry read */
 #define	SPR_MD_RAM0		0x339	/* ..8 IMMU RAM entry read reg 0 */
 #define	SPR_MD_RAM1		0x33a	/* ..8 IMMU RAM entry read reg 1 */
+#define	SPR_PSSCR		0x357	/* Processor Stop Status and Control Register (ISA 3.0) */
 #define	SPR_UMMCR2		0x3a0	/* .6. User Monitor Mode Control Register 2 */
 #define	SPR_UMMCR0		0x3a8	/* .6. User Monitor Mode Control Register 0 */
 #define	SPR_USIA		0x3ab	/* .6. User Sampled Instruction Address */

Modified: head/sys/powerpc/powerpc/cpu.c
==============================================================================
--- head/sys/powerpc/powerpc/cpu.c	Sun May 27 19:27:34 2018	(r334258)
+++ head/sys/powerpc/powerpc/cpu.c	Sun May 27 20:24:24 2018	(r334259)
@@ -91,6 +91,7 @@ static void	cpu_idle_60x(sbintime_t);
 static void	cpu_idle_booke(sbintime_t);
 #if defined(__powerpc64__) && defined(AIM)
 static void	cpu_idle_powerx(sbintime_t);
+static void	cpu_idle_power9(sbintime_t sbt);
 #endif
 
 struct cputab {
@@ -181,7 +182,7 @@ static const struct cputab models[] = {
 	   PPC_FEATURE2_ARCH_2_07 | PPC_FEATURE2_HTM | PPC_FEATURE2_DSCR |
 	   PPC_FEATURE2_ISEL | PPC_FEATURE2_TAR | PPC_FEATURE2_HAS_VEC_CRYPTO |
 	   PPC_FEATURE2_ARCH_3_00 | PPC_FEATURE2_HAS_IEEE128 |
-	   PPC_FEATURE2_DARN, NULL },
+	   PPC_FEATURE2_DARN, cpu_powerx_setup },
         { "Motorola PowerPC 7400",	MPC7400,	REVFMT_MAJMIN,
 	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, 0, cpu_6xx_setup },
         { "Motorola PowerPC 7410",	MPC7410,	REVFMT_MAJMIN,
@@ -660,7 +661,12 @@ cpu_powerx_setup(int cpuid, uint16_t vers)
 	switch (vers) {
 	case IBMPOWER8:
 	case IBMPOWER8E:
+		cpu_idle_hook = cpu_idle_powerx;
+		mtspr(SPR_LPCR, mfspr(SPR_LPCR) | LPCR_PECE_WAKESET);
+		isync();
+		break;
 	case IBMPOWER9:
+		cpu_idle_hook = cpu_idle_power9;
 		mtspr(SPR_LPCR, mfspr(SPR_LPCR) | LPCR_PECE_WAKESET);
 		isync();
 		break;
@@ -668,7 +674,6 @@ cpu_powerx_setup(int cpuid, uint16_t vers)
 		return;
 	}
 
-	cpu_idle_hook = cpu_idle_powerx;
 #endif
 }
 
@@ -797,6 +802,27 @@ cpu_idle_powerx(sbintime_t sbt)
 
 	enter_idle_powerx();
 	spinlock_exit();
+}
+
+static void
+cpu_idle_power9(sbintime_t sbt)
+{
+	register_t msr;
+
+	msr = mfmsr();
+
+	/* Suspend external interrupts until stop instruction completes. */
+	mtmsr(msr &  ~PSL_EE);
+	/* Set the stop state to lowest latency, wake up to next instruction */
+	mtspr(SPR_PSSCR, 0);
+	/* "stop" instruction (PowerISA 3.0) */
+	__asm __volatile (".long 0x4c0002e4");
+	/*
+	 * Re-enable external interrupts to capture the interrupt that caused
+	 * the wake up.
+	 */
+	mtmsr(msr);
+	
 }
 #endif
 


More information about the svn-src-head mailing list