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 */
|
/* Not inititialized and "owned" by another thread */
|
||||||
thread_lock(curthread);
|
sched_relinquish(curthread);
|
||||||
mi_switch(SW_VOL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map portal registers */
|
/* Map portal registers */
|
||||||
|
@ -146,8 +146,7 @@ qman_portal_setup(struct qman_softc *qsc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Not inititialized and "owned" by another thread */
|
/* Not inititialized and "owned" by another thread */
|
||||||
thread_lock(curthread);
|
sched_relinquish(curthread);
|
||||||
mi_switch(SW_VOL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map portal registers */
|
/* Map portal registers */
|
||||||
|
@ -565,8 +565,7 @@ poll_idle(void)
|
|||||||
if (poll_in_idle_loop && poll_handlers > 0) {
|
if (poll_in_idle_loop && poll_handlers > 0) {
|
||||||
idlepoll_sleeping = 0;
|
idlepoll_sleeping = 0;
|
||||||
ether_poll(poll_each_burst);
|
ether_poll(poll_each_burst);
|
||||||
thread_lock(td);
|
sched_relinquish(td);
|
||||||
mi_switch(SW_VOL);
|
|
||||||
} else {
|
} else {
|
||||||
idlepoll_sleeping = 1;
|
idlepoll_sleeping = 1;
|
||||||
tsleep(&idlepoll_sleeping, 0, "pollid", hz * 3);
|
tsleep(&idlepoll_sleeping, 0, "pollid", hz * 3);
|
||||||
|
@ -83,20 +83,14 @@ SYSCTL_INT(_kern_sched, OID_AUTO, preemption, CTLFLAG_RD,
|
|||||||
SYSCTL_NODE(_kern_sched, OID_AUTO, stats, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
|
SYSCTL_NODE(_kern_sched, OID_AUTO, stats, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
|
||||||
"switch stats");
|
"switch stats");
|
||||||
|
|
||||||
/* Switch reasons from mi_switch(). */
|
/* Switch reasons from mi_switch(9). */
|
||||||
DPCPU_DEFINE(long, sched_switch_stats[SWT_COUNT]);
|
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,
|
SCHED_STAT_DEFINE_VAR(owepreempt,
|
||||||
&DPCPU_NAME(sched_switch_stats[SWT_OWEPREEMPT]), "");
|
&DPCPU_NAME(sched_switch_stats[SWT_OWEPREEMPT]), "");
|
||||||
SCHED_STAT_DEFINE_VAR(turnstile,
|
SCHED_STAT_DEFINE_VAR(turnstile,
|
||||||
&DPCPU_NAME(sched_switch_stats[SWT_TURNSTILE]), "");
|
&DPCPU_NAME(sched_switch_stats[SWT_TURNSTILE]), "");
|
||||||
SCHED_STAT_DEFINE_VAR(sleepq,
|
SCHED_STAT_DEFINE_VAR(sleepq,
|
||||||
&DPCPU_NAME(sched_switch_stats[SWT_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,
|
SCHED_STAT_DEFINE_VAR(relinquish,
|
||||||
&DPCPU_NAME(sched_switch_stats[SWT_RELINQUISH]), "");
|
&DPCPU_NAME(sched_switch_stats[SWT_RELINQUISH]), "");
|
||||||
SCHED_STAT_DEFINE_VAR(needresched,
|
SCHED_STAT_DEFINE_VAR(needresched,
|
||||||
@ -111,6 +105,8 @@ SCHED_STAT_DEFINE_VAR(remotepreempt,
|
|||||||
&DPCPU_NAME(sched_switch_stats[SWT_REMOTEPREEMPT]), "");
|
&DPCPU_NAME(sched_switch_stats[SWT_REMOTEPREEMPT]), "");
|
||||||
SCHED_STAT_DEFINE_VAR(remotewakeidle,
|
SCHED_STAT_DEFINE_VAR(remotewakeidle,
|
||||||
&DPCPU_NAME(sched_switch_stats[SWT_REMOTEWAKEIDLE]), "");
|
&DPCPU_NAME(sched_switch_stats[SWT_REMOTEWAKEIDLE]), "");
|
||||||
|
SCHED_STAT_DEFINE_VAR(bind,
|
||||||
|
&DPCPU_NAME(sched_switch_stats[SWT_BIND]), "");
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sysctl_stats_reset(SYSCTL_HANDLER_ARGS)
|
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.
|
* 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))
|
if (!TD_ON_LOCK(td) && !TD_IS_RUNNING(td))
|
||||||
mtx_assert(&Giant, MA_NOTOWNED);
|
mtx_assert(&Giant, MA_NOTOWNED);
|
||||||
#endif
|
#endif
|
||||||
|
/* thread_lock() performs spinlock_enter(). */
|
||||||
KASSERT(td->td_critnest == 1 || KERNEL_PANICKED(),
|
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,
|
KASSERT((flags & (SW_INVOL | SW_VOL)) != 0,
|
||||||
("mi_switch: switch must be voluntary or involuntary"));
|
("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.
|
* Don't perform context switches from the debugger.
|
||||||
|
@ -1582,7 +1582,7 @@ sched_bind(struct thread *td, int cpu)
|
|||||||
if (PCPU_GET(cpuid) == cpu)
|
if (PCPU_GET(cpuid) == cpu)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mi_switch(SW_VOL);
|
mi_switch(SW_VOL | SWT_BIND);
|
||||||
thread_lock(td);
|
thread_lock(td);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2922,7 +2922,7 @@ sched_bind(struct thread *td, int cpu)
|
|||||||
return;
|
return;
|
||||||
ts->ts_cpu = cpu;
|
ts->ts_cpu = cpu;
|
||||||
/* When we return from mi_switch we'll be on the correct 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);
|
thread_lock(td);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/refcount.h>
|
#include <sys/refcount.h>
|
||||||
#include <sys/resourcevar.h>
|
#include <sys/resourcevar.h>
|
||||||
#include <sys/rwlock.h>
|
#include <sys/rwlock.h>
|
||||||
|
#include <sys/sched.h>
|
||||||
#include <sys/smp.h>
|
#include <sys/smp.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/syscallsubr.h>
|
#include <sys/syscallsubr.h>
|
||||||
@ -1425,8 +1426,7 @@ bufshutdown(int show_busybufs)
|
|||||||
* threads to run.
|
* threads to run.
|
||||||
*/
|
*/
|
||||||
for (subiter = 0; subiter < 50 * iter; subiter++) {
|
for (subiter = 0; subiter < 50 * iter; subiter++) {
|
||||||
thread_lock(curthread);
|
sched_relinquish(curthread);
|
||||||
mi_switch(SW_VOL);
|
|
||||||
DELAY(1000);
|
DELAY(1000);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -904,22 +904,20 @@ struct proc {
|
|||||||
|
|
||||||
#ifdef _KERNEL
|
#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 SW_TYPE_MASK 0xff /* First 8 bits are switch type */
|
||||||
#define SWT_NONE 0 /* Unspecified switch. */
|
#define SWT_OWEPREEMPT 1 /* Switching due to owepreempt. */
|
||||||
#define SWT_PREEMPT 1 /* Switching due to preemption. */
|
#define SWT_TURNSTILE 2 /* Turnstile contention. */
|
||||||
#define SWT_OWEPREEMPT 2 /* Switching due to owepreempt. */
|
#define SWT_SLEEPQ 3 /* Sleepq wait. */
|
||||||
#define SWT_TURNSTILE 3 /* Turnstile contention. */
|
#define SWT_RELINQUISH 4 /* yield call. */
|
||||||
#define SWT_SLEEPQ 4 /* Sleepq wait. */
|
#define SWT_NEEDRESCHED 5 /* NEEDRESCHED was set. */
|
||||||
#define SWT_SLEEPQTIMO 5 /* Sleepq timeout wait. */
|
#define SWT_IDLE 6 /* Switching from the idle thread. */
|
||||||
#define SWT_RELINQUISH 6 /* yield call. */
|
#define SWT_IWAIT 7 /* Waiting for interrupts. */
|
||||||
#define SWT_NEEDRESCHED 7 /* NEEDRESCHED was set. */
|
#define SWT_SUSPEND 8 /* Thread suspended. */
|
||||||
#define SWT_IDLE 8 /* Switching from the idle thread. */
|
#define SWT_REMOTEPREEMPT 9 /* Remote processor preempted. */
|
||||||
#define SWT_IWAIT 9 /* Waiting for interrupts. */
|
#define SWT_REMOTEWAKEIDLE 10 /* Remote processor preempted idle. */
|
||||||
#define SWT_SUSPEND 10 /* Thread suspended. */
|
#define SWT_BIND 11 /* Thread bound to a new CPU. */
|
||||||
#define SWT_REMOTEPREEMPT 11 /* Remote processor preempted. */
|
#define SWT_COUNT 12 /* Number of switch types. */
|
||||||
#define SWT_REMOTEWAKEIDLE 12 /* Remote processor preempted idle. */
|
|
||||||
#define SWT_COUNT 13 /* Number of switch types. */
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
#define SW_VOL 0x0100 /* Voluntary switch. */
|
#define SW_VOL 0x0100 /* Voluntary switch. */
|
||||||
#define SW_INVOL 0x0200 /* Involuntary switch. */
|
#define SW_INVOL 0x0200 /* Involuntary switch. */
|
||||||
|
Loading…
Reference in New Issue
Block a user