summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man9/curproc.933
-rw-r--r--sys/kern/kern_heartbeat.c14
-rw-r--r--sys/kern/subr_cpu.c32
-rw-r--r--sys/sys/cpu.h3
4 files changed, 59 insertions, 23 deletions
diff --git a/share/man/man9/curproc.9 b/share/man/man9/curproc.9
index 3e77ffc5c85..282af8d1fbb 100644
--- a/share/man/man9/curproc.9
+++ b/share/man/man9/curproc.9
@@ -1,4 +1,4 @@
-.\" $NetBSD: curproc.9,v 1.6 2022/09/22 14:02:24 riastradh Exp $
+.\" $NetBSD: curproc.9,v 1.7 2023/07/08 13:59:05 riastradh Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,24 +27,25 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd July 1, 2010
+.Dd July 8, 2023
.Dt CURPROC 9
.Os
.Sh NAME
-.Nm curproc ,
.Nm curcpu ,
-.Nm curlwp
-.Nd current process, processor, and
-.Tn LWP
+.Nm curlwp ,
+.Nm curproc
+.Nd current processor, thread, and process
.Sh SYNOPSIS
.In sys/proc.h
.Ft struct cpu_info *
.Fn curcpu "void"
.Vt struct proc *curproc ;
.Vt struct lwp *curlwp ;
+.In sys/cpu.h
+.Ft bool
+.Fn curcpu_stable "void"
.Sh DESCRIPTION
-The following macros retrieve
-the current CPU, process, and thread
+The following retrieve the current CPU, process, and thread
.Pq lightweight process, or Tn LWP ,
respectively:
.Bl -tag -width Dv
@@ -62,6 +63,17 @@ by disabling preemption
.Pq Xr kpreempt_disable 9 ,
or by binding the thread to its CPU
.Pq Xr curlwp_bind 9 .
+.Pp
+The function
+.Fn curcpu_stable
+can be used in assertions
+.Pq Xr KASSERT 9
+to verify that
+.Fn curcpu
+is stable in the current context.
+.Fn curcpu_stable
+MUST NOT be used to make dynamic decisions about whether to query
+.Fn curcpu .
.It Dv curproc
Yields a pointer to the
.Vt "struct proc"
@@ -102,6 +114,11 @@ but it may be overridden by
.Pa machine/cpu.h ,
and must be overridden on architectures supporting multiprocessing and
kernel preemption.
+.Pp
+The
+.Fn curcpu_stable
+function is defined in
+.Pa kern/subr_cpu.c .
.Sh SEE ALSO
.Xr cpu_number 9 ,
.Xr proc_find 9
diff --git a/sys/kern/kern_heartbeat.c b/sys/kern/kern_heartbeat.c
index 3b7631aba6f..7bb4811b7f5 100644
--- a/sys/kern/kern_heartbeat.c
+++ b/sys/kern/kern_heartbeat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_heartbeat.c,v 1.2 2023/07/07 17:05:13 riastradh Exp $ */
+/* $NetBSD: kern_heartbeat.c,v 1.3 2023/07/08 13:59:05 riastradh Exp $ */
/*-
* Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_heartbeat.c,v 1.2 2023/07/07 17:05:13 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_heartbeat.c,v 1.3 2023/07/08 13:59:05 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -104,16 +104,6 @@ __KERNEL_RCSID(0, "$NetBSD: kern_heartbeat.c,v 1.2 2023/07/07 17:05:13 riastradh
#include <ddb/ddb.h>
#endif
-static inline bool
-curcpu_stable(void)
-{
-
- return kpreempt_disabled() ||
- (curlwp->l_pflag & LP_BOUND) ||
- cpu_intr_p() ||
- cpu_softintr_p();
-}
-
/*
* Global state.
*
diff --git a/sys/kern/subr_cpu.c b/sys/kern/subr_cpu.c
index 523de709c92..f8a4b6f5b0f 100644
--- a/sys/kern/subr_cpu.c
+++ b/sys/kern/subr_cpu.c
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_cpu.c,v 1.18 2022/01/24 09:42:14 andvar Exp $ */
+/* $NetBSD: subr_cpu.c,v 1.19 2023/07/08 13:59:05 riastradh Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009, 2010, 2012, 2019, 2020
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_cpu.c,v 1.18 2022/01/24 09:42:14 andvar Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_cpu.c,v 1.19 2023/07/08 13:59:05 riastradh Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -137,6 +137,34 @@ cpu_softintr_p(void)
return (curlwp->l_pflag & LP_INTR) != 0;
}
+bool
+curcpu_stable(void)
+{
+ struct lwp *const l = curlwp;
+ const int pflag = l->l_pflag;
+ const int nopreempt = l->l_nopreempt;
+
+ /*
+ * - Softints (LP_INTR) never migrate between CPUs.
+ * - Bound lwps (LP_BOUND), either kthreads created bound to
+ * a CPU or any lwps bound with curlwp_bind, never migrate.
+ * - If kpreemption is disabled, the lwp can't migrate.
+ * - If we're in interrupt context, preemption is blocked.
+ *
+ * We combine the LP_INTR, LP_BOUND, and l_nopreempt test into
+ * a single predicted-true branch so this is cheap to assert in
+ * most contexts where it will be used, then fall back to
+ * calling the full kpreempt_disabled() and cpu_intr_p() as
+ * subroutines.
+ *
+ * XXX Is cpu_intr_p redundant with kpreempt_disabled?
+ */
+ return __predict_true(((pflag & (LP_INTR|LP_BOUND)) | nopreempt)
+ != 0) ||
+ kpreempt_disabled() ||
+ cpu_intr_p();
+}
+
/*
* Collect CPU topology information as each CPU is attached. This can be
* called early during boot, so we need to be careful what we do.
diff --git a/sys/sys/cpu.h b/sys/sys/cpu.h
index ca266fc33cd..54b9f478ae2 100644
--- a/sys/sys/cpu.h
+++ b/sys/sys/cpu.h
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.51 2020/06/15 18:04:42 ad Exp $ */
+/* $NetBSD: cpu.h,v 1.52 2023/07/08 13:59:05 riastradh Exp $ */
/*-
* Copyright (c) 2007 YAMAMOTO Takashi,
@@ -84,6 +84,7 @@ int cpu_setstate(struct cpu_info *, bool);
int cpu_setintr(struct cpu_info *, bool);
bool cpu_intr_p(void);
bool cpu_softintr_p(void);
+bool curcpu_stable(void);
bool cpu_kpreempt_enter(uintptr_t, int);
void cpu_kpreempt_exit(uintptr_t);
bool cpu_kpreempt_disabled(void);