Date: Sun, 27 May 2018 20:24:24 +0000 (UTC) From: Justin Hibbits <jhibbits@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r334259 - in head/sys/powerpc: include powerpc Message-ID: <201805272024.w4RKOORO090038@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805272024.w4RKOORO090038>