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 *);
 

Reply via email to