Implement the cpu_yield hypervisor call. Use it in the idle loop for
authorart <art@openbsd.org>
Mon, 21 Jul 2008 13:30:04 +0000 (13:30 +0000)
committerart <art@openbsd.org>
Mon, 21 Jul 2008 13:30:04 +0000 (13:30 +0000)
SUN4V to let it suspend strands (why does everyone invent own words for
hyperthreads?). This gives a huge performance boost when most of the
cpus are idle.

kettenis@ ok

sys/arch/sparc64/include/hypervisor.h
sys/arch/sparc64/sparc64/cpu.c
sys/arch/sparc64/sparc64/hvcall.S
sys/arch/sparc64/sparc64/locore.s

index eacf6f2..6ef58b8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: hypervisor.h,v 1.1 2008/03/08 19:15:56 kettenis Exp $ */
+/*     $OpenBSD: hypervisor.h,v 1.2 2008/07/21 13:30:04 art Exp $      */
 
 /*
  * Copyright (c) 2008 Mark Kettenis
@@ -49,6 +49,8 @@ int64_t       hv_cpu_qconf(uint64_t queue, uint64_t base, uint64_t nentries);
 int64_t        hv_cpu_mondo_send(uint64_t ncpus, paddr_t cpulist, paddr_t data);
 int64_t        hv_cpu_myid(uint64_t *cpuid);
 
+void hv_cpu_yield(void);
+
 /*
  * MMU services
  */
index fbd6d20..193cebc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.c,v 1.44 2008/07/12 14:26:07 kettenis Exp $       */
+/*     $OpenBSD: cpu.c,v 1.45 2008/07/21 13:30:05 art Exp $    */
 /*     $NetBSD: cpu.c,v 1.13 2001/05/26 21:27:15 chs Exp $ */
 
 /*
@@ -516,3 +516,38 @@ need_resched(struct cpu_info *ci)
        if (ci->ci_curproc != NULL)
                aston(ci->ci_curproc);
 }
+
+/*
+ * Idle loop.
+ *
+ * We disable and reenable the interrupts in every cycle of the idle loop.
+ * Since hv_cpu_yield doesn't actually reenable interrupts, it just wakes
+ * up if an interrupt would have happened, but it's our responsibility to
+ * unblock interrupts.
+ */
+
+void
+cpu_idle_enter(void)
+{
+       if (CPU_ISSUN4V) {
+               sparc_wrpr(pstate, sparc_rdpr(pstate) & ~PSTATE_IE, 0);
+       }
+}
+
+void
+cpu_idle_cycle(void)
+{
+       if (CPU_ISSUN4V) {
+               hv_cpu_yield();
+               sparc_wrpr(pstate, sparc_rdpr(pstate) | PSTATE_IE, 0);
+               sparc_wrpr(pstate, sparc_rdpr(pstate) & ~PSTATE_IE, 0);
+       }
+}
+
+void
+cpu_idle_leave()
+{
+       if (CPU_ISSUN4V) {
+               sparc_wrpr(pstate, sparc_rdpr(pstate) | PSTATE_IE, 0);
+       }
+}
index ff19183..dd27ee8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: hvcall.S,v 1.1 2008/03/08 19:15:56 kettenis Exp $     */
+/*     $OpenBSD: hvcall.S,v 1.2 2008/07/21 13:30:05 art Exp $  */
 
 /*
  * Copyright (c) 2008 Mark Kettenis
@@ -320,3 +320,9 @@ ENTRY(hv_pci_config_put)
        ta      FAST_TRAP
        retl
         stx    %o1, [%g5]
+
+ENTRY(hv_cpu_yield)
+       mov     CPU_YIELD, %o5
+       ta      FAST_TRAP
+       retl
+        nop
index 756a272..81f83cb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: locore.s,v 1.146 2008/07/12 15:05:51 kettenis Exp $   */
+/*     $OpenBSD: locore.s,v 1.147 2008/07/21 13:30:05 art Exp $        */
 /*     $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $    */
 
 /*
@@ -6154,18 +6154,6 @@ Lsw_havectx:
        ret
         restore
 
-ENTRY(cpu_idle_enter)
-       retl
-        nop
-
-ENTRY(cpu_idle_cycle)
-       retl
-        nop
-
-ENTRY(cpu_idle_leave)
-       retl
-        nop
-
 /*
  * Snapshot the current process so that stack frames are up to date.
  * Only used just before a crash dump.