aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2023-02-09 15:40:29 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2023-02-09 16:01:32 +0000
commit1029dab63457f23dace4dab3b698f1c177939b93 (patch)
treefb24264e322d90ae159f1a4b707950b26ae2ad8b
parentbff02948ed87a9e791fa901557a88ae545bf3df7 (diff)
downloadsrc-1029dab63457f23dace4dab3b698f1c177939b93.tar.gz
src-1029dab63457f23dace4dab3b698f1c177939b93.zip
mi_switch(): clean up switch types and their usage
Overall, this is a non-functional change, except for kernels built with SCHED_STATS. However, the switch types are useful for communicating the intent of the caller. 1. Ensure that every caller provides a type. In most cases, we upgrade the basic yield to sched_relinquish() aka SWT_RELINQUISH. 2. The case of sched_bind() is distinct, so add a new switch type SWT_BIND. 3. Remove the two unused types, SWT_PREEMPT and SWT_SLEEPQTIMO. 4. Remove SWT_NONE altogether and assert that callers always provide a type flag. 5. Reference the mi_switch(9) man page in the comments, as these flags will be documented there. Reviewed by: kib, markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D38184
-rw-r--r--sys/dev/dpaa/bman_portals.c3
-rw-r--r--sys/dev/dpaa/qman_portals.c3
-rw-r--r--sys/kern/kern_poll.c3
-rw-r--r--sys/kern/kern_switch.c12
-rw-r--r--sys/kern/kern_synch.c9
-rw-r--r--sys/kern/sched_4bsd.c2
-rw-r--r--sys/kern/sched_ule.c2
-rw-r--r--sys/kern/vfs_bio.c4
-rw-r--r--sys/sys/proc.h28
9 files changed, 31 insertions, 35 deletions
diff --git a/sys/dev/dpaa/bman_portals.c b/sys/dev/dpaa/bman_portals.c
index 9ef2bf7aa61c..d3c027bb29f8 100644
--- a/sys/dev/dpaa/bman_portals.c
+++ b/sys/dev/dpaa/bman_portals.c
@@ -141,8 +141,7 @@ bman_portal_setup(struct bman_softc *bsc)
}
/* Not inititialized and "owned" by another thread */
- thread_lock(curthread);
- mi_switch(SW_VOL);
+ sched_relinquish(curthread);
}
/* Map portal registers */
diff --git a/sys/dev/dpaa/qman_portals.c b/sys/dev/dpaa/qman_portals.c
index 92461665def2..37f9b4eec178 100644
--- a/sys/dev/dpaa/qman_portals.c
+++ b/sys/dev/dpaa/qman_portals.c
@@ -146,8 +146,7 @@ qman_portal_setup(struct qman_softc *qsc)
}
/* Not inititialized and "owned" by another thread */
- thread_lock(curthread);
- mi_switch(SW_VOL);
+ sched_relinquish(curthread);
}
/* Map portal registers */
diff --git a/sys/kern/kern_poll.c b/sys/kern/kern_poll.c
index 8232f98f59ef..64deb7132710 100644
--- a/sys/kern/kern_poll.c
+++ b/sys/kern/kern_poll.c
@@ -565,8 +565,7 @@ poll_idle(void)
if (poll_in_idle_loop && poll_handlers > 0) {
idlepoll_sleeping = 0;
ether_poll(poll_each_burst);
- thread_lock(td);
- mi_switch(SW_VOL);
+ sched_relinquish(td);
} else {
idlepoll_sleeping = 1;
tsleep(&idlepoll_sleeping, 0, "pollid", hz * 3);
diff --git a/sys/kern/kern_switch.c b/sys/kern/kern_switch.c
index 9d48ab188e13..aee0c9cbd1ae 100644
--- a/sys/kern/kern_switch.c
+++ b/sys/kern/kern_switch.c
@@ -83,25 +83,19 @@ SYSCTL_INT(_kern_sched, OID_AUTO, preemption, CTLFLAG_RD,
SYSCTL_NODE(_kern_sched, OID_AUTO, stats, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"switch stats");
-/* Switch reasons from mi_switch(). */
+/* Switch reasons from mi_switch(9). */
DPCPU_DEFINE(long, sched_switch_stats[SWT_COUNT]);
-SCHED_STAT_DEFINE_VAR(uncategorized,
- &DPCPU_NAME(sched_switch_stats[SWT_NONE]), "");
-SCHED_STAT_DEFINE_VAR(preempt,
- &DPCPU_NAME(sched_switch_stats[SWT_PREEMPT]), "");
SCHED_STAT_DEFINE_VAR(owepreempt,
&DPCPU_NAME(sched_switch_stats[SWT_OWEPREEMPT]), "");
SCHED_STAT_DEFINE_VAR(turnstile,
&DPCPU_NAME(sched_switch_stats[SWT_TURNSTILE]), "");
SCHED_STAT_DEFINE_VAR(sleepq,
&DPCPU_NAME(sched_switch_stats[SWT_SLEEPQ]), "");
-SCHED_STAT_DEFINE_VAR(sleepqtimo,
- &DPCPU_NAME(sched_switch_stats[SWT_SLEEPQTIMO]), "");
SCHED_STAT_DEFINE_VAR(relinquish,
&DPCPU_NAME(sched_switch_stats[SWT_RELINQUISH]), "");
SCHED_STAT_DEFINE_VAR(needresched,
&DPCPU_NAME(sched_switch_stats[SWT_NEEDRESCHED]), "");
-SCHED_STAT_DEFINE_VAR(idle,
+SCHED_STAT_DEFINE_VAR(idle,
&DPCPU_NAME(sched_switch_stats[SWT_IDLE]), "");
SCHED_STAT_DEFINE_VAR(iwait,
&DPCPU_NAME(sched_switch_stats[SWT_IWAIT]), "");
@@ -111,6 +105,8 @@ SCHED_STAT_DEFINE_VAR(remotepreempt,
&DPCPU_NAME(sched_switch_stats[SWT_REMOTEPREEMPT]), "");
SCHED_STAT_DEFINE_VAR(remotewakeidle,
&DPCPU_NAME(sched_switch_stats[SWT_REMOTEWAKEIDLE]), "");
+SCHED_STAT_DEFINE_VAR(bind,
+ &DPCPU_NAME(sched_switch_stats[SWT_BIND]), "");
static int
sysctl_stats_reset(SYSCTL_HANDLER_ARGS)
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 7d0cb6178fc3..63a78353e9a5 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -483,7 +483,7 @@ kdb_switch(void)
}
/*
- * The machine independent parts of context switching.
+ * mi_switch(9): The machine-independent parts of context switching.
*
* The thread lock is required on entry and is no longer held on return.
*/
@@ -500,10 +500,15 @@ mi_switch(int flags)
if (!TD_ON_LOCK(td) && !TD_IS_RUNNING(td))
mtx_assert(&Giant, MA_NOTOWNED);
#endif
+ /* thread_lock() performs spinlock_enter(). */
KASSERT(td->td_critnest == 1 || KERNEL_PANICKED(),
- ("mi_switch: switch in a critical section"));
+ ("mi_switch: switch in a critical section"));
KASSERT((flags & (SW_INVOL | SW_VOL)) != 0,
("mi_switch: switch must be voluntary or involuntary"));
+ KASSERT((flags & SW_TYPE_MASK) != 0,
+ ("mi_switch: a switch reason (type) must be specified"));
+ KASSERT((flags & SW_TYPE_MASK) < SWT_COUNT,
+ ("mi_switch: invalid switch reason %d", (flags & SW_TYPE_MASK)));
/*
* Don't perform context switches from the debugger.
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index f0da4f8d8496..e81b0c9d46ec 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -1582,7 +1582,7 @@ sched_bind(struct thread *td, int cpu)
if (PCPU_GET(cpuid) == cpu)
return;
- mi_switch(SW_VOL);
+ mi_switch(SW_VOL | SWT_BIND);
thread_lock(td);
#endif
}
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index ba179caf5d34..881413ca5e73 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -2922,7 +2922,7 @@ sched_bind(struct thread *td, int cpu)
return;
ts->ts_cpu = cpu;
/* When we return from mi_switch we'll be on the correct cpu. */
- mi_switch(SW_VOL);
+ mi_switch(SW_VOL | SWT_BIND);
thread_lock(td);
}
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index cb94f3390d8a..3a5afec88a02 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
#include <sys/refcount.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
+#include <sys/sched.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/syscallsubr.h>
@@ -1425,8 +1426,7 @@ bufshutdown(int show_busybufs)
* threads to run.
*/
for (subiter = 0; subiter < 50 * iter; subiter++) {
- thread_lock(curthread);
- mi_switch(SW_VOL);
+ sched_relinquish(curthread);
DELAY(1000);
}
#endif
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index d031c2a73ce6..c6670bdc96f8 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -904,22 +904,20 @@ struct proc {
#ifdef _KERNEL
-/* Types and flags for mi_switch(). */
+/* Types and flags for mi_switch(9). */
#define SW_TYPE_MASK 0xff /* First 8 bits are switch type */
-#define SWT_NONE 0 /* Unspecified switch. */
-#define SWT_PREEMPT 1 /* Switching due to preemption. */
-#define SWT_OWEPREEMPT 2 /* Switching due to owepreempt. */
-#define SWT_TURNSTILE 3 /* Turnstile contention. */
-#define SWT_SLEEPQ 4 /* Sleepq wait. */
-#define SWT_SLEEPQTIMO 5 /* Sleepq timeout wait. */
-#define SWT_RELINQUISH 6 /* yield call. */
-#define SWT_NEEDRESCHED 7 /* NEEDRESCHED was set. */
-#define SWT_IDLE 8 /* Switching from the idle thread. */
-#define SWT_IWAIT 9 /* Waiting for interrupts. */
-#define SWT_SUSPEND 10 /* Thread suspended. */
-#define SWT_REMOTEPREEMPT 11 /* Remote processor preempted. */
-#define SWT_REMOTEWAKEIDLE 12 /* Remote processor preempted idle. */
-#define SWT_COUNT 13 /* Number of switch types. */
+#define SWT_OWEPREEMPT 1 /* Switching due to owepreempt. */
+#define SWT_TURNSTILE 2 /* Turnstile contention. */
+#define SWT_SLEEPQ 3 /* Sleepq wait. */
+#define SWT_RELINQUISH 4 /* yield call. */
+#define SWT_NEEDRESCHED 5 /* NEEDRESCHED was set. */
+#define SWT_IDLE 6 /* Switching from the idle thread. */
+#define SWT_IWAIT 7 /* Waiting for interrupts. */
+#define SWT_SUSPEND 8 /* Thread suspended. */
+#define SWT_REMOTEPREEMPT 9 /* Remote processor preempted. */
+#define SWT_REMOTEWAKEIDLE 10 /* Remote processor preempted idle. */
+#define SWT_BIND 11 /* Thread bound to a new CPU. */
+#define SWT_COUNT 12 /* Number of switch types. */
/* Flags */
#define SW_VOL 0x0100 /* Voluntary switch. */
#define SW_INVOL 0x0200 /* Involuntary switch. */