Module Name: src
Committed By: thorpej
Date: Fri Feb 7 11:55:22 UTC 2020
Modified Files:
src/sys/kern: subr_percpu.c
src/sys/sys: percpu.h
Log Message:
Add percpu_foreach_xcall(), which is like percpu_foreach(), except it
runs the callback on the target CPU.
To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/kern/subr_percpu.c
cvs rdiff -u -r1.4 -r1.5 src/sys/sys/percpu.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/subr_percpu.c
diff -u src/sys/kern/subr_percpu.c:1.23 src/sys/kern/subr_percpu.c:1.24
--- src/sys/kern/subr_percpu.c:1.23 Sat Feb 1 12:53:41 2020
+++ src/sys/kern/subr_percpu.c Fri Feb 7 11:55:22 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_percpu.c,v 1.23 2020/02/01 12:53:41 riastradh Exp $ */
+/* $NetBSD: subr_percpu.c,v 1.24 2020/02/07 11:55:22 thorpej Exp $ */
/*-
* Copyright (c)2007,2008 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_percpu.c,v 1.23 2020/02/01 12:53:41 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_percpu.c,v 1.24 2020/02/07 11:55:22 thorpej Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -412,7 +412,9 @@ percpu_getptr_remote(percpu_t *pc, struc
/*
* percpu_foreach: call the specified callback function for each cpus.
*
- * => called in thread context.
+ * => must be called from thread context.
+ * => callback executes on **current** CPU (or, really, arbitrary CPU,
+ * in case of preemption)
* => caller should not rely on the cpu iteration order.
* => the callback function should be minimum because it is executed with
* holding a global lock, which can block low-priority xcalls.
@@ -430,3 +432,46 @@ percpu_foreach(percpu_t *pc, percpu_call
}
percpu_traverse_exit();
}
+
+struct percpu_xcall_ctx {
+ percpu_callback_t ctx_cb;
+ void *ctx_arg;
+};
+
+static void
+percpu_xcfunc(void * const v1, void * const v2)
+{
+ percpu_t * const pc = v1;
+ struct percpu_xcall_ctx * const ctx = v2;
+
+ (*ctx->ctx_cb)(percpu_getref(pc), ctx->ctx_arg, curcpu());
+ percpu_putref(pc);
+}
+
+/*
+ * percpu_foreach_xcall: call the specified callback function for each
+ * cpu. This version uses an xcall to run the callback on each cpu.
+ *
+ * => must be called from thread context.
+ * => callback executes on **remote** CPU in soft-interrupt context
+ * (at the specified soft interrupt priority).
+ * => caller should not rely on the cpu iteration order.
+ * => the callback function should be minimum because it may be
+ * executed in soft-interrupt context. eg. it's illegal for
+ * a callback function to sleep for memory allocation.
+ */
+void
+percpu_foreach_xcall(percpu_t *pc, u_int xcflags, percpu_callback_t cb,
+ void *arg)
+{
+ struct percpu_xcall_ctx ctx = {
+ .ctx_cb = cb,
+ .ctx_arg = arg,
+ };
+ CPU_INFO_ITERATOR cii;
+ struct cpu_info *ci;
+
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ xc_wait(xc_unicast(xcflags, percpu_xcfunc, pc, &ctx, ci));
+ }
+}
Index: src/sys/sys/percpu.h
diff -u src/sys/sys/percpu.h:1.4 src/sys/sys/percpu.h:1.5
--- src/sys/sys/percpu.h:1.4 Sat Feb 1 12:49:02 2020
+++ src/sys/sys/percpu.h Fri Feb 7 11:55:22 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: percpu.h,v 1.4 2020/02/01 12:49:02 riastradh Exp $ */
+/* $NetBSD: percpu.h,v 1.5 2020/02/07 11:55:22 thorpej Exp $ */
/*-
* Copyright (c)2007,2008 YAMAMOTO Takashi,
@@ -40,6 +40,7 @@ void percpu_putref(percpu_t *);
typedef void (*percpu_callback_t)(void *, void *, struct cpu_info *);
void percpu_foreach(percpu_t *, percpu_callback_t, void *);
+void percpu_foreach_xcall(percpu_t *, u_int, percpu_callback_t, void *);
percpu_t *percpu_create(size_t, percpu_callback_t, percpu_callback_t, void *);