diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-04-10 19:25:43 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-04-10 19:25:43 +0000 |
commit | 4239f985ba44d5108be4badd6dae111ea089b557 (patch) | |
tree | 39b7028c9c07590783a23c7e9f4646cde6dd03e6 /sys | |
parent | 067ec3949e0a5823835af770680701078c914f00 (diff) |
Make sun4v_broadcast_ipi() do its job by making a single hypervisor call
instead of repeatedly calling sun4v_send_ipi(). Makes compiling a kernel
almost 20% faster.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc64/sparc64/ipifuncs.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/sys/arch/sparc64/sparc64/ipifuncs.c b/sys/arch/sparc64/sparc64/ipifuncs.c index b5117888453..e51a6ad3726 100644 --- a/sys/arch/sparc64/sparc64/ipifuncs.c +++ b/sys/arch/sparc64/sparc64/ipifuncs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipifuncs.c,v 1.8 2008/03/31 22:14:01 kettenis Exp $ */ +/* $OpenBSD: ipifuncs.c,v 1.9 2008/04/10 19:25:42 kettenis Exp $ */ /* $NetBSD: ipifuncs.c,v 1.8 2006/10/07 18:11:36 rjs Exp $ */ /*- @@ -179,15 +179,36 @@ sun4u_broadcast_ipi(void (*func)(void), u_int64_t arg0, u_int64_t arg1) void sun4v_broadcast_ipi(void (*func)(void), u_int64_t arg0, u_int64_t arg1) { - struct cpu_info *ci; + struct cpu_info *ci = curcpu(); + paddr_t cpuset = ci->ci_cpuset; + int err, i, ncpus = 0; for (ci = cpus; ci != NULL; ci = ci->ci_next) { if (ci->ci_number == cpu_number()) continue; if ((ci->ci_flags & CPUF_RUNNING) == 0) continue; - sun4v_send_ipi(ci->ci_itid, func, arg0, arg1); + stha(cpuset, ASI_PHYS_CACHED, ci->ci_itid); + cpuset += sizeof(int16_t); + ncpus++; } + + if (ncpus == 0) + return; + + ci = curcpu(); + stxa(ci->ci_mondo, ASI_PHYS_CACHED, (vaddr_t)func); + stxa(ci->ci_mondo + 8, ASI_PHYS_CACHED, arg0); + stxa(ci->ci_mondo + 16, ASI_PHYS_CACHED, arg1); + + for (i = 0; i < SPARC64_IPI_RETRIES; i++) { + err = hv_cpu_mondo_send(ncpus, ci->ci_cpuset, ci->ci_mondo); + if (err != H_EWOULDBLOCK) + break; + delay(10); + } + if (err != H_EOK) + panic("Unable to broadcast mondo %lx: %d", func, err); } void |