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