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
This commit is contained in:
parent
bff02948ed
commit
1029dab634
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user