diff options
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/kern/kern_heartbeat.c | 14 | ||||
| -rw-r--r-- | sys/kern/subr_cpu.c | 32 | ||||
| -rw-r--r-- | sys/sys/cpu.h | 3 |
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); |
