summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_heartbeat.c14
-rw-r--r--sys/kern/subr_cpu.c32
-rw-r--r--sys/sys/cpu.h3
3 files changed, 34 insertions, 15 deletions
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);