Module Name: src
Committed By: mrg
Date: Fri Jan 17 04:11:33 UTC 2025
Modified Files:
src/sys/kern: kern_cpu.c kern_runq.c sched_4bsd.c
src/sys/sys: cpu.h
Log Message:
partly prepare for more than 2-level CPU speed scheduler support
put the calls behind looking at SPCF_IDLE and SPCF_1STCLASS mostly
behind functions that can grow support for more than 2 CPU classes.
4 new functions, with 2 of them just simple aliases for the 1st:
bool cpu_is_type(struct cpu_info *ci, int wanted);
bool cpu_is_idle_1stclass(struct cpu_info *ci)
bool cpu_is_1stclass(struct cpu_info *ci)
bool cpu_is_better(struct cpu_info *ci1, struct cpu_info *ci2);
with this in place, we can retain the desire to run on 1st-class by
preference, while also expanding cpu_is_better() to handle multiple
non 1st-class CPUs. ultimately, i envision seeing a priority number
where we can mark the fastest turbo-speed cores ahead of others, for
the case we can detect this.
XXX: use struct schedstate_percpu instead of cpu_info?
NFCI.
To generate a diff of this commit:
cvs rdiff -u -r1.97 -r1.98 src/sys/kern/kern_cpu.c
cvs rdiff -u -r1.70 -r1.71 src/sys/kern/kern_runq.c
cvs rdiff -u -r1.46 -r1.47 src/sys/kern/sched_4bsd.c
cvs rdiff -u -r1.54 -r1.55 src/sys/sys/cpu.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_cpu.c
diff -u src/sys/kern/kern_cpu.c:1.97 src/sys/kern/kern_cpu.c:1.98
--- src/sys/kern/kern_cpu.c:1.97 Sat Sep 2 17:44:59 2023
+++ src/sys/kern/kern_cpu.c Fri Jan 17 04:11:33 2025
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_cpu.c,v 1.97 2023/09/02 17:44:59 riastradh Exp $ */
+/* $NetBSD: kern_cpu.c,v 1.98 2025/01/17 04:11:33 mrg Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009, 2010, 2012, 2019 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.97 2023/09/02 17:44:59 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.98 2025/01/17 04:11:33 mrg Exp $");
#ifdef _KERNEL_OPT
#include "opt_cpu_ucode.h"
@@ -452,6 +452,42 @@ cpu_setstate(struct cpu_info *ci, bool o
return 0;
}
+bool
+cpu_is_type(struct cpu_info *ci, int wanted)
+{
+
+ return (ci->ci_schedstate.spc_flags & wanted) == wanted;
+}
+
+bool
+cpu_is_idle_1stclass(struct cpu_info *ci)
+{
+ const int wanted = SPCF_IDLE | SPCF_1STCLASS;
+
+ return cpu_is_type(ci, wanted);
+}
+
+bool
+cpu_is_1stclass(struct cpu_info *ci)
+{
+ const int wanted = SPCF_1STCLASS;
+
+ return cpu_is_type(ci, wanted);
+}
+
+bool
+cpu_is_better(struct cpu_info *ci1, struct cpu_info *ci2)
+{
+ const int ci1_flags = ci1->ci_schedstate.spc_flags;
+ const int ci2_flags = ci2->ci_schedstate.spc_flags;
+
+ if ((ci1_flags & SPCF_1STCLASS) != 0 &&
+ (ci2_flags & SPCF_1STCLASS) == 0)
+ return ci1;
+
+ return ci2;
+}
+
#if defined(__HAVE_INTR_CONTROL)
static void
cpu_xc_intr(struct cpu_info *ci, void *unused)
Index: src/sys/kern/kern_runq.c
diff -u src/sys/kern/kern_runq.c:1.70 src/sys/kern/kern_runq.c:1.71
--- src/sys/kern/kern_runq.c:1.70 Tue Sep 19 22:15:32 2023
+++ src/sys/kern/kern_runq.c Fri Jan 17 04:11:33 2025
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_runq.c,v 1.70 2023/09/19 22:15:32 ad Exp $ */
+/* $NetBSD: kern_runq.c,v 1.71 2025/01/17 04:11:33 mrg Exp $ */
/*-
* Copyright (c) 2019, 2020 The NetBSD Foundation, Inc.
@@ -56,7 +56,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.70 2023/09/19 22:15:32 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.71 2025/01/17 04:11:33 mrg Exp $");
#include "opt_dtrace.h"
@@ -523,8 +523,7 @@ sched_bestcpu(struct lwp *l, struct cpu_
curspc = &curci->ci_schedstate;
/* If this CPU is idle and 1st class, we're done. */
- if ((curspc->spc_flags & (SPCF_IDLE | SPCF_1STCLASS)) ==
- (SPCF_IDLE | SPCF_1STCLASS)) {
+ if (cpu_is_idle_1stclass(curci)) {
return curci;
}
@@ -536,8 +535,7 @@ sched_bestcpu(struct lwp *l, struct cpu_
}
if (curpri == bestpri) {
/* Prefer first class CPUs over others. */
- if ((curspc->spc_flags & SPCF_1STCLASS) == 0 &&
- (bestspc->spc_flags & SPCF_1STCLASS) != 0) {
+ if (cpu_is_better(bestci, curci)) {
continue;
}
/*
@@ -568,7 +566,7 @@ sched_bestcpu(struct lwp *l, struct cpu_
struct cpu_info *
sched_takecpu(struct lwp *l)
{
- struct schedstate_percpu *spc, *tspc;
+ struct schedstate_percpu *spc;
struct cpu_info *ci, *curci, *tci;
pri_t eprio;
int flags;
@@ -611,9 +609,7 @@ sched_takecpu(struct lwp *l)
*/
tci = ci;
do {
- tspc = &tci->ci_schedstate;
- if ((tspc->spc_flags & flags) == flags &&
- sched_migratable(l, tci)) {
+ if (cpu_is_type(tci, flags) && sched_migratable(l, tci)) {
return tci;
}
tci = tci->ci_sibling[CPUREL_CORE];
@@ -635,9 +631,7 @@ sched_takecpu(struct lwp *l)
curci = curcpu();
tci = curci;
do {
- tspc = &tci->ci_schedstate;
- if ((tspc->spc_flags & flags) == flags &&
- sched_migratable(l, tci)) {
+ if (cpu_is_type(tci, flags) && sched_migratable(l, tci)) {
return tci;
}
tci = tci->ci_sibling[CPUREL_CORE];
@@ -670,8 +664,7 @@ sched_catchlwp(struct cpu_info *ci)
* Be more aggressive if this CPU is first class, and the other
* is not.
*/
- gentle = ((curspc->spc_flags & SPCF_1STCLASS) == 0 ||
- (spc->spc_flags & SPCF_1STCLASS) != 0);
+ gentle = cpu_is_better(curci, ci);
if (atomic_load_relaxed(&spc->spc_mcount) < (gentle ? min_catch : 1) ||
curspc->spc_psid != spc->spc_psid) {
@@ -913,7 +906,6 @@ sched_idle(void)
void
sched_preempted(struct lwp *l)
{
- const int flags = SPCF_IDLE | SPCF_1STCLASS;
struct schedstate_percpu *tspc;
struct cpu_info *ci, *tci;
@@ -930,8 +922,8 @@ sched_preempted(struct lwp *l)
* - or this LWP is a child of vfork() that has just done execve()
*/
if (l->l_target_cpu != NULL ||
- ((tspc->spc_flags & SPCF_1STCLASS) != 0 &&
- (l->l_pflag & LP_TELEPORT) == 0)) {
+ (cpu_is_1stclass(ci) &&
+ (l->l_pflag & LP_TELEPORT) == 0)) {
return;
}
@@ -944,8 +936,7 @@ sched_preempted(struct lwp *l)
tci = ci->ci_sibling[CPUREL_CORE];
while (tci != ci) {
tspc = &tci->ci_schedstate;
- if ((tspc->spc_flags & flags) == flags &&
- sched_migratable(l, tci)) {
+ if (cpu_is_idle_1stclass(tci) && sched_migratable(l, tci)) {
l->l_target_cpu = tci;
l->l_pflag &= ~LP_TELEPORT;
return;
@@ -976,8 +967,7 @@ sched_preempted(struct lwp *l)
* whole system if needed.
*/
tci = sched_bestcpu(l, l->l_cpu);
- if (tci != ci &&
- (tci->ci_schedstate.spc_flags & flags) == flags) {
+ if (tci != ci && cpu_is_idle_1stclass(tci)) {
l->l_target_cpu = tci;
}
}
@@ -998,8 +988,7 @@ sched_vforkexec(struct lwp *l, bool same
{
KASSERT(l == curlwp);
- if ((samecpu && ncpu > 1) ||
- (l->l_cpu->ci_schedstate.spc_flags & SPCF_1STCLASS) == 0) {
+ if ((samecpu && ncpu > 1) || !cpu_is_1stclass(l->l_cpu)) {
l->l_pflag |= LP_TELEPORT;
preempt();
}
Index: src/sys/kern/sched_4bsd.c
diff -u src/sys/kern/sched_4bsd.c:1.46 src/sys/kern/sched_4bsd.c:1.47
--- src/sys/kern/sched_4bsd.c:1.46 Wed Oct 26 23:24:09 2022
+++ src/sys/kern/sched_4bsd.c Fri Jan 17 04:11:33 2025
@@ -1,4 +1,4 @@
-/* $NetBSD: sched_4bsd.c,v 1.46 2022/10/26 23:24:09 riastradh Exp $ */
+/* $NetBSD: sched_4bsd.c,v 1.47 2025/01/17 04:11:33 mrg Exp $ */
/*
* Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2019, 2020
@@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sched_4bsd.c,v 1.46 2022/10/26 23:24:09 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sched_4bsd.c,v 1.47 2025/01/17 04:11:33 mrg Exp $");
#include "opt_ddb.h"
#include "opt_lockdebug.h"
@@ -146,7 +146,7 @@ sched_tick(struct cpu_info *ci)
*/
pri = MAXPRI_KTHREAD;
spc->spc_flags |= SPCF_SHOULDYIELD;
- } else if ((spc->spc_flags & SPCF_1STCLASS) == 0) {
+ } else if (!cpu_is_1stclass(ci)) {
/*
* For SMT or asymmetric systems push a little
* harder: if this is not a 1st class CPU, try to
Index: src/sys/sys/cpu.h
diff -u src/sys/sys/cpu.h:1.54 src/sys/sys/cpu.h:1.55
--- src/sys/sys/cpu.h:1.54 Tue Mar 5 20:59:41 2024
+++ src/sys/sys/cpu.h Fri Jan 17 04:11:33 2025
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.54 2024/03/05 20:59:41 thorpej Exp $ */
+/* $NetBSD: cpu.h,v 1.55 2025/01/17 04:11:33 mrg Exp $ */
/*-
* Copyright (c) 2007 YAMAMOTO Takashi,
@@ -115,6 +115,12 @@ cpu_name(struct cpu_info *ci)
return ci->ci_data.cpu_name;
}
+/* Scheduler helpers */
+bool cpu_is_type(struct cpu_info *, int);
+bool cpu_is_idle_1stclass(struct cpu_info *);
+bool cpu_is_1stclass(struct cpu_info *);
+bool cpu_is_better(struct cpu_info *, struct cpu_info *);
+
#ifdef CPU_UCODE
struct cpu_ucode_softc {
int loader_version;