summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2008-07-21 13:30:06 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2008-07-21 13:30:06 +0000
commit4b218cee305e4c1378440ef5c5575cc11cd829f3 (patch)
tree826454623f93536936adfb7826964297b6dd10bf /sys/arch/sparc64
parent2a104c95a23b111054dd1e591ee635e9f2d22db4 (diff)
Implement the cpu_yield hypervisor call. Use it in the idle loop for
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
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r--sys/arch/sparc64/include/hypervisor.h4
-rw-r--r--sys/arch/sparc64/sparc64/cpu.c37
-rw-r--r--sys/arch/sparc64/sparc64/hvcall.S8
-rw-r--r--sys/arch/sparc64/sparc64/locore.s14
4 files changed, 47 insertions, 16 deletions
diff --git a/sys/arch/sparc64/include/hypervisor.h b/sys/arch/sparc64/include/hypervisor.h
index eacf6f2afad..6ef58b8d3d7 100644
--- a/sys/arch/sparc64/include/hypervisor.h
+++ b/sys/arch/sparc64/include/hypervisor.h
@@ -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
*/
diff --git a/sys/arch/sparc64/sparc64/cpu.c b/sys/arch/sparc64/sparc64/cpu.c
index fbd6d202875..193cebcdca4 100644
--- a/sys/arch/sparc64/sparc64/cpu.c
+++ b/sys/arch/sparc64/sparc64/cpu.c
@@ -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);
+ }
+}
diff --git a/sys/arch/sparc64/sparc64/hvcall.S b/sys/arch/sparc64/sparc64/hvcall.S
index ff19183db57..dd27ee8496f 100644
--- a/sys/arch/sparc64/sparc64/hvcall.S
+++ b/sys/arch/sparc64/sparc64/hvcall.S
@@ -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
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s
index 756a272622d..81f83cb749a 100644
--- a/sys/arch/sparc64/sparc64/locore.s
+++ b/sys/arch/sparc64/sparc64/locore.s
@@ -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.