diff options
author | 2020-09-23 03:03:11 +0000 | |
---|---|---|
committer | 2020-09-23 03:03:11 +0000 | |
commit | c7966c0ce778201c4fa0e71eace2b478e439ef94 (patch) | |
tree | c1452b3d2909a305bde64981a28f0d21f0bebd3b | |
parent | disable POOL_DEBUG in preparation for release (diff) | |
download | wireguard-openbsd-c7966c0ce778201c4fa0e71eace2b478e439ef94.tar.xz wireguard-openbsd-c7966c0ce778201c4fa0e71eace2b478e439ef94.zip |
Use an IPI, so hw.setperf affects all cores in the mp kernel.
Before, apm -A was speeding up only one core of my POWER9.
Now, apm -A speeds up all cores, so my parallel builds are faster.
I copy the idea from amd64 and i386: mp_setperf() sends an IPI to all
cpus; the interrupt handler calls ul_setperf().
ok deraadt@ kettenis@
-rw-r--r-- | sys/arch/powerpc64/dev/opal.c | 8 | ||||
-rw-r--r-- | sys/arch/powerpc64/include/cpu.h | 5 | ||||
-rw-r--r-- | sys/arch/powerpc64/include/intr.h | 5 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/cpu.c | 30 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/intr.c | 8 |
5 files changed, 44 insertions, 12 deletions
diff --git a/sys/arch/powerpc64/dev/opal.c b/sys/arch/powerpc64/dev/opal.c index 65573322aa8..a3ec08afa92 100644 --- a/sys/arch/powerpc64/dev/opal.c +++ b/sys/arch/powerpc64/dev/opal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: opal.c,v 1.9 2020/09/21 11:14:28 kettenis Exp $ */ +/* $OpenBSD: opal.c,v 1.10 2020/09/23 03:03:11 gkoehler Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> * @@ -22,6 +22,7 @@ #include <sys/systm.h> #include <machine/bus.h> +#include <machine/cpu.h> #include <machine/fdt.h> #include <machine/opal.h> @@ -345,7 +346,12 @@ opalpm_init(struct opal_softc *sc, int node) if ((i = opalpm_find_index(sc)) != -1) perflevel = (sc->sc_npstate - 1 - i) * 100 / sc->sc_npstate; cpu_cpuspeed = opalpm_cpuspeed; +#ifndef MULTIPROCESSOR cpu_setperf = opalpm_setperf; +#else + ul_setperf = opalpm_setperf; + cpu_setperf = mp_setperf; +#endif } int diff --git a/sys/arch/powerpc64/include/cpu.h b/sys/arch/powerpc64/include/cpu.h index c6504f6cf99..7a95344f554 100644 --- a/sys/arch/powerpc64/include/cpu.h +++ b/sys/arch/powerpc64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.27 2020/09/15 07:47:24 kettenis Exp $ */ +/* $OpenBSD: cpu.h,v 1.28 2020/09/23 03:03:12 gkoehler Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -150,6 +150,9 @@ void cpu_kick(struct cpu_info *); void cpu_boot_secondary_processors(void); void cpu_startclock(void); +extern void (*ul_setperf)(int); +void mp_setperf(int); + #endif #define clockframe trapframe diff --git a/sys/arch/powerpc64/include/intr.h b/sys/arch/powerpc64/include/intr.h index 053a1c16b76..f3019600b90 100644 --- a/sys/arch/powerpc64/include/intr.h +++ b/sys/arch/powerpc64/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.11 2020/09/21 11:14:28 kettenis Exp $ */ +/* $OpenBSD: intr.h,v 1.12 2020/09/23 03:03:12 gkoehler Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -91,7 +91,8 @@ void *intr_establish(uint32_t, int, int, struct cpu_info *, int (*)(void *), void *, const char *); #define IPI_NOP 0 -#define IPI_DDB 1 +#define IPI_DDB (1 << 0) +#define IPI_SETPERF (1 << 1) void intr_send_ipi(struct cpu_info *, int); diff --git a/sys/arch/powerpc64/powerpc64/cpu.c b/sys/arch/powerpc64/powerpc64/cpu.c index 38e1daf0a33..2a01ecbb707 100644 --- a/sys/arch/powerpc64/powerpc64/cpu.c +++ b/sys/arch/powerpc64/powerpc64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.18 2020/09/15 07:47:24 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.19 2020/09/23 03:03:12 gkoehler Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -255,6 +255,9 @@ cpu_darn(void *arg) #ifdef MULTIPROCESSOR +volatile int mp_perflevel; +void (*ul_setperf)(int); + void cpu_bootstrap(void) { @@ -349,11 +352,15 @@ int cpu_intr(void *arg) { struct cpu_info *ci = curcpu(); + int pending; + + pending = atomic_swap_uint(&ci->ci_ipi_reason, IPI_NOP); - if (ci->ci_ipi_reason == IPI_DDB) { - ci->ci_ipi_reason = IPI_NOP; + if (pending & IPI_DDB) db_enter(); - } + + if (pending & IPI_SETPERF) + ul_setperf(mp_perflevel); return 1; } @@ -365,4 +372,19 @@ cpu_kick(struct cpu_info *ci) intr_send_ipi(ci, IPI_NOP); } +/* + * Run ul_setperf(level) on every core. + */ +void +mp_setperf(int level) { + int i; + + mp_perflevel = level; + ul_setperf(level); + for (i = 0; i < ncpus; i++) { + if (i != cpu_number()) + intr_send_ipi(&cpu_info[i], IPI_SETPERF); + } +} + #endif diff --git a/sys/arch/powerpc64/powerpc64/intr.c b/sys/arch/powerpc64/powerpc64/intr.c index c6fc13137a2..6f07ccf3ec2 100644 --- a/sys/arch/powerpc64/powerpc64/intr.c +++ b/sys/arch/powerpc64/powerpc64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.7 2020/09/21 11:14:28 kettenis Exp $ */ +/* $OpenBSD: intr.c,v 1.8 2020/09/23 03:03:12 gkoehler Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -21,6 +21,7 @@ #include <sys/malloc.h> #include <sys/systm.h> +#include <machine/atomic.h> #include <machine/intr.h> #include <dev/ofw/openfirm.h> @@ -400,9 +401,8 @@ intr_send_ipi(struct cpu_info *ci, int reason) if (ci == curcpu() && reason == IPI_NOP) return; - /* Never overwrite IPI_DDB with IPI_NOP. */ - if (reason == IPI_DDB) - ci->ci_ipi_reason = reason; + if (reason != IPI_NOP) + atomic_setbits_int(&ci->ci_ipi_reason, reason); if (ih && ih->ih_ic) ih->ih_ic->ic_send_ipi(ih->ih_ih); |