Introduce CPU_IS_RUNNING() and us it in scheduler-related code to prevent
authorkettenis <kettenis@openbsd.org>
Tue, 6 Jul 2021 09:34:06 +0000 (09:34 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 6 Jul 2021 09:34:06 +0000 (09:34 +0000)
waiting on CPUs that didn't spin up.  This will allow us to spin down
CPUs in the future to save power as well.

ok mpi@

14 files changed:
sys/arch/alpha/include/cpu.h
sys/arch/amd64/include/cpu.h
sys/arch/arm/include/cpu.h
sys/arch/arm64/include/cpu.h
sys/arch/hppa/include/cpu.h
sys/arch/i386/include/cpu.h
sys/arch/m88k/include/cpu.h
sys/arch/mips64/include/cpu.h
sys/arch/powerpc/include/cpu.h
sys/arch/powerpc64/include/cpu.h
sys/arch/sh/include/cpu.h
sys/arch/sparc64/include/cpu.h
sys/kern/kern_sched.c
sys/kern/kern_smr.c

index 6dedb26..be5b57c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.64 2021/06/02 00:39:26 cheloha Exp $ */
+/* $OpenBSD: cpu.h,v 1.65 2021/07/06 09:34:06 kettenis Exp $ */
 /* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */
 
 /*-
@@ -241,6 +241,7 @@ extern      struct cpu_info *cpu_info[];
 
 #define        curcpu()                        ((struct cpu_info *)alpha_pal_rdval())
 #define        CPU_IS_PRIMARY(ci)              ((ci)->ci_flags & CPUF_PRIMARY)
+#define        CPU_IS_RUNNING(ci)              ((ci)->ci_flags & CPUF_RUNNING)
 
 void   cpu_boot_secondary_processors(void);
 
@@ -273,6 +274,7 @@ do {                                                                        \
 
 #define        curcpu()                        (&cpu_info_primary)
 #define        CPU_IS_PRIMARY(ci)              1
+#define        CPU_IS_RUNNING(ci)              1
 #define cpu_unidle(ci)                 do { /* nothing */ } while (0)
 #define CPU_BUSY_CYCLE()               do {} while (0)
 
index cc5012b..d19bf15 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.139 2021/06/18 06:17:28 guenther Exp $      */
+/*     $OpenBSD: cpu.h,v 1.140 2021/07/06 09:34:06 kettenis Exp $      */
 /*     $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $     */
 
 /*-
@@ -271,6 +271,7 @@ extern void need_resched(struct cpu_info *);
 #define cpu_number()   (curcpu()->ci_cpuid)
 
 #define CPU_IS_PRIMARY(ci)     ((ci)->ci_flags & CPUF_PRIMARY)
+#define CPU_IS_RUNNING(ci)     ((ci)->ci_flags & CPUF_RUNNING)
 
 extern struct cpu_info *cpu_info[MAXCPUS];
 
@@ -301,6 +302,7 @@ void cpu_unidle(struct cpu_info *);
  */
 #define        cpu_number()            0
 #define CPU_IS_PRIMARY(ci)     1
+#define CPU_IS_RUNNING(ci)     1
 
 #endif /* MULTIPROCESSOR */
 
index 28f1c91..e3b6d5c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.60 2021/06/02 00:39:26 cheloha Exp $        */
+/*     $OpenBSD: cpu.h,v 1.61 2021/07/06 09:34:06 kettenis Exp $       */
 /*     $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $  */
 
 /*
@@ -224,6 +224,7 @@ extern struct cpu_info *cpu_info_list;
 #ifndef MULTIPROCESSOR
 #define cpu_number()   0
 #define CPU_IS_PRIMARY(ci)     1
+#define CPU_IS_RUNNING(ci)     1
 #define CPU_INFO_ITERATOR      int
 #define CPU_INFO_FOREACH(cii, ci) \
        for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
@@ -234,6 +235,7 @@ extern struct cpu_info *cpu_info_list;
 #else
 #define cpu_number()           (curcpu()->ci_cpuid)
 #define CPU_IS_PRIMARY(ci)     ((ci) == &cpu_info_primary)
+#define CPU_IS_RUNNING(ci)     ((ci)->ci_flags & CPUF_RUNNING)
 #define CPU_INFO_ITERATOR              int
 #define CPU_INFO_FOREACH(cii, ci)      for (cii = 0, ci = cpu_info_list; \
                                            ci != NULL; ci = ci->ci_next)
index 29f7d4d..9f9e476 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.21 2021/06/02 00:39:26 cheloha Exp $ */
+/* $OpenBSD: cpu.h,v 1.22 2021/07/06 09:34:06 kettenis Exp $ */
 /*
  * Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
  *
@@ -161,6 +161,7 @@ extern struct cpu_info *cpu_info_list;
 #ifndef MULTIPROCESSOR
 #define cpu_number()   0
 #define CPU_IS_PRIMARY(ci)     1
+#define CPU_IS_RUNNING(ci)     1
 #define CPU_INFO_ITERATOR      int
 #define CPU_INFO_FOREACH(cii, ci) \
        for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
@@ -170,6 +171,7 @@ extern struct cpu_info *cpu_info_list;
 #else
 #define cpu_number()           (curcpu()->ci_cpuid)
 #define CPU_IS_PRIMARY(ci)     ((ci) == &cpu_info_primary)
+#define CPU_IS_RUNNING(ci)     ((ci)->ci_flags & CPUF_RUNNING)
 #define CPU_INFO_ITERATOR              int
 #define CPU_INFO_FOREACH(cii, ci)      for (cii = 0, ci = cpu_info_list; \
                                            ci != NULL; ci = ci->ci_next)
index b8dfc05..6270268 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.94 2021/06/02 00:39:26 cheloha Exp $        */
+/*     $OpenBSD: cpu.h,v 1.95 2021/07/06 09:34:06 kettenis Exp $       */
 
 /*
  * Copyright (c) 2000-2004 Michael Shalayeff
@@ -144,6 +144,7 @@ curcpu(void)
 
 #define CPU_INFO_UNIT(ci)      ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
 #define CPU_IS_PRIMARY(ci)     ((ci)->ci_cpuid == 0)
+#define CPU_IS_RUNNING(ci)     ((ci)->ci_flags & CPUF_RUNNING)
 #define        CPU_INFO_ITERATOR       int
 #define CPU_INFO_FOREACH(cii, ci) \
        for (cii = 0, ci = &cpu_info[0]; cii < ncpus; cii++, ci++)
index 97e5bc6..34f9b2a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.174 2021/06/02 00:39:26 cheloha Exp $       */
+/*     $OpenBSD: cpu.h,v 1.175 2021/07/06 09:34:06 kettenis Exp $      */
 /*     $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $        */
 
 /*-
@@ -233,6 +233,7 @@ curcpu(void)
 #define cpu_number()           (curcpu()->ci_cpuid)
 
 #define CPU_IS_PRIMARY(ci)     ((ci)->ci_flags & CPUF_PRIMARY)
+#define CPU_IS_RUNNING(ci)     ((ci)->ci_flags & CPUF_RUNNING)
 
 extern struct cpu_info *cpu_info[MAXCPUS];
 
@@ -252,6 +253,7 @@ void cpu_unidle(struct cpu_info *);
 #define        curcpu()                (&cpu_info_primary)
 
 #define CPU_IS_PRIMARY(ci)     1
+#define CPU_IS_RUNNING(ci)     1
 
 #define cpu_kick(ci)
 #define cpu_unidle(ci)
index 5b97b79..8b0c30b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.69 2021/06/02 00:39:26 cheloha Exp $ */
+/*     $OpenBSD: cpu.h,v 1.70 2021/07/06 09:34:06 kettenis Exp $ */
 /*
  * Copyright (c) 1996 Nivas Madhur
  * Copyright (c) 1992, 1993
@@ -202,6 +202,7 @@ curcpu(void)
 }
 
 #define        CPU_IS_PRIMARY(ci)      ((ci)->ci_flags & CIF_PRIMARY)
+#define        CPU_IS_RUNNING(ci)      ((ci)->ci_flags & CIF_ALIVE)
 
 void   cpu_boot_secondary_processors(void);
 __dead void cpu_emergency_disable(void);
@@ -214,6 +215,7 @@ void        m88k_broadcast_ipi(int);
 #define        curcpu()        (&m88k_cpus[0])
 #define        cpu_unidle(ci)  do { /* nothing */ } while (0)
 #define        CPU_IS_PRIMARY(ci)      1
+#define        CPU_IS_RUNNING(ci)      1
 
 #endif /* MULTIPROCESSOR */
 
index 79b0a24..57aa201 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.134 2021/06/02 00:39:26 cheloha Exp $       */
+/*     $OpenBSD: cpu.h,v 1.135 2021/07/06 09:34:06 kettenis Exp $      */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -225,6 +225,7 @@ extern void (*cpu_idle_cycle_func)(void);
 extern struct cpu_info *get_cpu_info(int);
 #define curcpu() getcurcpu()
 #define        CPU_IS_PRIMARY(ci)              ((ci)->ci_flags & CPUF_PRIMARY)
+#define        CPU_IS_RUNNING(ci)              ((ci)->ci_flags & CPUF_RUNNING)
 #define cpu_number()                   (curcpu()->ci_cpuid)
 
 extern struct cpuset cpus_running;
@@ -249,6 +250,7 @@ void        smp_rendezvous_cpus(unsigned long, void (*)(void *), void *arg);
 #define MAXCPUS                                1
 #define curcpu()                       (&cpu_info_primary)
 #define        CPU_IS_PRIMARY(ci)              1
+#define        CPU_IS_RUNNING(ci)              1
 #define cpu_number()                   0UL
 #define cpu_unidle(ci)
 #define get_cpu_info(i)                        (&cpu_info_primary)
index 2711694..2c9e8db 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.69 2021/06/02 00:39:26 cheloha Exp $        */
+/*     $OpenBSD: cpu.h,v 1.70 2021/07/06 09:34:06 kettenis Exp $       */
 /*     $NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $       */
 
 /*
@@ -125,6 +125,7 @@ cpu_number(void)
 void   cpu_boot_secondary_processors(void);
 
 #define CPU_IS_PRIMARY(ci)     ((ci)->ci_cpuid == 0)
+#define CPU_IS_RUNNING(ci)     1
 #define CPU_INFO_ITERATOR              int
 #define CPU_INFO_FOREACH(cii, ci)                                      \
        for (cii = 0, ci = &cpu_info[0]; cii < ncpusfound; cii++, ci++)
@@ -138,6 +139,7 @@ void cpu_unidle(struct cpu_info *);
 #define cpu_number()           0
 
 #define CPU_IS_PRIMARY(ci)     1
+#define CPU_IS_RUNNING(ci)     1
 #define CPU_INFO_ITERATOR              int
 #define CPU_INFO_FOREACH(cii, ci)                                      \
        for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
index 0bd905b..7825e62 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.30 2021/06/02 00:39:27 cheloha Exp $        */
+/*     $OpenBSD: cpu.h,v 1.31 2021/07/06 09:34:07 kettenis Exp $       */
 
 /*
  * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -130,6 +130,7 @@ curcpu(void)
 
 #define MAXCPUS                        1
 #define CPU_IS_PRIMARY(ci)     1
+#define CPU_IS_RUNNING(ci)     1
 #define cpu_number()           0
 
 #define CPU_INFO_UNIT(ci)      0
@@ -143,6 +144,7 @@ curcpu(void)
 
 #define MAXCPUS                        48
 #define CPU_IS_PRIMARY(ci)     ((ci) == cpu_info_primary)
+#define CPU_IS_RUNNING(ci)     ((ci)->ci_flags & CPUF_RUNNING)
 #define cpu_number()           (curcpu()->ci_cpuid)
 
 #define CPU_INFO_UNIT(ci)      ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
index bf51581..15b5b9c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.31 2021/06/02 00:39:27 cheloha Exp $        */
+/*     $OpenBSD: cpu.h,v 1.32 2021/07/06 09:34:07 kettenis Exp $       */
 /*     $NetBSD: cpu.h,v 1.41 2006/01/21 04:24:12 uwe Exp $     */
 
 /*-
@@ -78,6 +78,7 @@ extern struct cpu_info cpu_info_store;
 #define        curcpu()        (&cpu_info_store)
 #define cpu_number()   0
 #define CPU_IS_PRIMARY(ci)     1
+#define CPU_IS_RUNNING(ci)     1
 #define CPU_INFO_ITERATOR      int
 #define CPU_INFO_FOREACH(cii, ci) \
        for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
index 7c98e51..44a624d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.97 2021/06/02 00:39:27 cheloha Exp $        */
+/*     $OpenBSD: cpu.h,v 1.98 2021/07/06 09:34:07 kettenis Exp $       */
 /*     $NetBSD: cpu.h,v 1.28 2001/06/14 22:56:58 thorpej Exp $ */
 
 /*
@@ -179,6 +179,7 @@ register struct cpu_info *__curcpu asm ("g7");
 #define cpu_number()   (__curcpu->ci_cpuid)
 
 #define CPU_IS_PRIMARY(ci)     ((ci)->ci_cpuid == 0)
+#define CPU_IS_RUNNING(ci)     1
 #define CPU_INFO_ITERATOR      int
 #define CPU_INFO_FOREACH(cii, ci)                                      \
        for (cii = 0, ci = cpus; ci != NULL; ci = ci->ci_next)
@@ -199,6 +200,7 @@ void        cpu_unidle(struct cpu_info *);
 #define cpu_number()   0
 
 #define CPU_IS_PRIMARY(ci)     1
+#define CPU_IS_RUNNING(ci)     1
 #define CPU_INFO_ITERATOR      int
 #define CPU_INFO_FOREACH(cii, ci)                                      \
        for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
index 4803b55..5510108 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sched.c,v 1.71 2021/06/29 21:31:49 kettenis Exp $        */
+/*     $OpenBSD: kern_sched.c,v 1.72 2021/07/06 09:34:07 kettenis Exp $        */
 /*
  * Copyright (c) 2007, 2008 Artur Grabowski <art@openbsd.org>
  *
@@ -638,7 +638,7 @@ sched_start_secondary_cpus(void)
        CPU_INFO_FOREACH(cii, ci) {
                struct schedstate_percpu *spc = &ci->ci_schedstate;
 
-               if (CPU_IS_PRIMARY(ci))
+               if (CPU_IS_PRIMARY(ci) || !CPU_IS_RUNNING(ci))
                        continue;
                atomic_clearbits_int(&spc->spc_schedflags,
                    SPCF_SHOULDHALT | SPCF_HALTED);
@@ -662,7 +662,7 @@ sched_stop_secondary_cpus(void)
        CPU_INFO_FOREACH(cii, ci) {
                struct schedstate_percpu *spc = &ci->ci_schedstate;
 
-               if (CPU_IS_PRIMARY(ci))
+               if (CPU_IS_PRIMARY(ci) || !CPU_IS_RUNNING(ci))
                        continue;
                cpuset_del(&sched_all_cpus, ci);
                atomic_setbits_int(&spc->spc_schedflags, SPCF_SHOULDHALT);
@@ -671,7 +671,7 @@ sched_stop_secondary_cpus(void)
                struct schedstate_percpu *spc = &ci->ci_schedstate;
                struct sleep_state sls;
 
-               if (CPU_IS_PRIMARY(ci))
+               if (CPU_IS_PRIMARY(ci) || !CPU_IS_RUNNING(ci))
                        continue;
                while ((spc->spc_schedflags & SPCF_HALTED) == 0) {
                        sleep_setup(&sls, spc, PZERO, "schedstate", 0);
@@ -869,7 +869,7 @@ sysctl_hwsmt(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
 
        sched_smt = newsmt;
        CPU_INFO_FOREACH(cii, ci) {
-               if (CPU_IS_PRIMARY(ci))
+               if (CPU_IS_PRIMARY(ci) || !CPU_IS_RUNNING(ci))
                        continue;
                if (ci->ci_smt_id == 0)
                        continue;
index e002e56..f95e18c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_smr.c,v 1.11 2021/06/29 21:31:49 kettenis Exp $  */
+/*     $OpenBSD: kern_smr.c,v 1.12 2021/07/06 09:34:07 kettenis Exp $  */
 
 /*
  * Copyright (c) 2019-2020 Visa Hankala
@@ -149,6 +149,8 @@ smr_grace_wait(void)
        curcpu()->ci_schedstate.spc_smrgp = smrgp;
 
        CPU_INFO_FOREACH(cii, ci) {
+               if (!CPU_IS_RUNNING(ci))
+                       continue;
                if (READ_ONCE(ci->ci_schedstate.spc_smrgp) == smrgp)
                        continue;
                sched_peg_curproc(ci);