summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgkoehler <gkoehler@openbsd.org>2020-09-23 03:03:11 +0000
committergkoehler <gkoehler@openbsd.org>2020-09-23 03:03:11 +0000
commitc7966c0ce778201c4fa0e71eace2b478e439ef94 (patch)
treec1452b3d2909a305bde64981a28f0d21f0bebd3b
parentdisable POOL_DEBUG in preparation for release (diff)
downloadwireguard-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.c8
-rw-r--r--sys/arch/powerpc64/include/cpu.h5
-rw-r--r--sys/arch/powerpc64/include/intr.h5
-rw-r--r--sys/arch/powerpc64/powerpc64/cpu.c30
-rw-r--r--sys/arch/powerpc64/powerpc64/intr.c8
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);