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
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to