Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/sys curcpu_stable(9): New function for asserting curcpu(...



details:   https://anonhg.NetBSD.org/src/rev/e9c387c75ffa
branches:  trunk
changeset: 377353:e9c387c75ffa
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sat Jul 08 13:59:05 2023 +0000

description:
curcpu_stable(9): New function for asserting curcpu() is stable.

diffstat:

 share/man/man9/curproc.9  |  33 +++++++++++++++++++++++++--------
 sys/kern/kern_heartbeat.c |  14 ++------------
 sys/kern/subr_cpu.c       |  32 ++++++++++++++++++++++++++++++--
 sys/sys/cpu.h             |   3 ++-
 4 files changed, 59 insertions(+), 23 deletions(-)

diffs (177 lines):

diff -r 9d0b30bbe378 -r e9c387c75ffa share/man/man9/curproc.9
--- a/share/man/man9/curproc.9  Sat Jul 08 12:45:43 2023 +0000
+++ b/share/man/man9/curproc.9  Sat Jul 08 13:59:05 2023 +0000
@@ -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 -r 9d0b30bbe378 -r e9c387c75ffa sys/kern/kern_heartbeat.c
--- a/sys/kern/kern_heartbeat.c Sat Jul 08 12:45:43 2023 +0000
+++ b/sys/kern/kern_heartbeat.c Sat Jul 08 13:59:05 2023 +0000
@@ -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 @@
 #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 -r 9d0b30bbe378 -r e9c387c75ffa sys/kern/subr_cpu.c
--- a/sys/kern/subr_cpu.c       Sat Jul 08 12:45:43 2023 +0000
+++ b/sys/kern/subr_cpu.c       Sat Jul 08 13:59:05 2023 +0000
@@ -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 -r 9d0b30bbe378 -r e9c387c75ffa sys/sys/cpu.h
--- a/sys/sys/cpu.h     Sat Jul 08 12:45:43 2023 +0000
+++ b/sys/sys/cpu.h     Sat Jul 08 13:59:05 2023 +0000
@@ -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);



Home | Main Index | Thread Index | Old Index