diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2008-07-21 13:30:06 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2008-07-21 13:30:06 +0000 |
commit | 4b218cee305e4c1378440ef5c5575cc11cd829f3 (patch) | |
tree | 826454623f93536936adfb7826964297b6dd10bf /sys/arch/sparc64 | |
parent | 2a104c95a23b111054dd1e591ee635e9f2d22db4 (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.h | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/cpu.c | 37 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/hvcall.S | 8 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/locore.s | 14 |
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. |