pub struct Scheduler {
pub name: &'static str,
pub binary: SchedulerSpec,
pub sysctls: &'static [Sysctl],
pub kargs: &'static [&'static str],
pub assert: Assert,
pub cgroup_parent: Option<CgroupPath>,
pub sched_args: &'static [&'static str],
pub topology: Topology,
pub constraints: TopologyConstraints,
pub config_file: Option<&'static str>,
pub config_file_def: Option<(&'static str, &'static str)>,
pub kernels: &'static [&'static str],
}Expand description
Definition of a scheduler for the test framework.
Captures everything the framework needs to know about a scheduler: its name, binary spec, sysctls, kernel args, scheduler args, cgroup parent, default topology, gauntlet topology constraints, config-file plumbing, kernel sweep set, and assertion overrides.
Construct via the declare_scheduler! macro (the production
path) or the Scheduler::named const builder chain. Test bodies
reference declared schedulers via the scheduler = MY_SCHED
attribute on #[ktstr_test].
Fields§
§name: &'static strShort human name for the scheduler, used in logs and sidecar metadata.
binary: SchedulerSpecSource of the scheduler: a built-in spec variant (Eevdf,
Discover, Path, or KernelBuiltin).
The declare_scheduler! macro exposes three pseudo-keys that
each map to one SchedulerSpec variant — the macro never
accepts an enum literal, so authors must pick the matching
key:
binary = "scx_name"→SchedulerSpec::Discover("scx_name")(PATH lookup in the guest).binary_path = "/abs/path"→SchedulerSpec::Path("/abs/path")(explicit absolute path).kernel_builtin_enable = "…", kernel_builtin_disable = "…"(paired) →SchedulerSpec::KernelBuiltin.
Code that constructs a Scheduler outside the macro
(manual ..Scheduler::EEVDF spread, programmatic builders)
uses the typed SchedulerSpec enum directly — see the
chainable Scheduler::binary_discover sugar for the
Discover common case.
sysctls: &'static [Sysctl]Guest sysctls applied before the scheduler starts (injected
into the guest kernel cmdline as sysctl.<key>=<value>).
Applied in order; duplicate keys last-write-wins.
kargs: &'static [&'static str]Extra guest kernel command-line arguments appended when booting
the VM. This is the GUEST KERNEL cmdline, not the scheduler
binary’s CLI — use sched_args for that.
Do not override the kargs ktstr injects itself (console=,
loglevel=, init=): those break guest-side init
and leave the VM unable to run tests.
assert: AssertScheduler-wide assertion overrides merged on top of
Assert::default_checks() and below each per-entry assert.
Construct via crate::assert::Assert::NO_OVERRIDES (the
zero-overrides baseline) chained through the Assert builder
methods. The Assert builder surface (every overridable
threshold + scheduler-tunable knob) is documented at the
Checking
guide chapter; see crate::assert::Assert for the full
per-method threshold list.
cgroup_parent: Option<CgroupPath>Cgroup parent path. Must begin with / and must not be "/"
alone (that is the cgroup root). Example: "/ktstr".
When set, the init creates the sysfs directory before starting
the scheduler, and --cell-parent-cgroup {path} is injected
into scheduler args.
sched_args: &'static [&'static str]Scheduler CLI args, prepended before per-test extra_sched_args.
topology: TopologyDefault VM topology for tests using this scheduler. Tests inherit
this topology unless they override numa_nodes, llcs, cores,
or threads explicitly in #[ktstr_test].
constraints: TopologyConstraintsGauntlet topology constraints. Tests inherit these unless they
override specific fields in #[ktstr_test].
config_file: Option<&'static str>Host-side path to an opaque config file passed to the scheduler
binary inside the VM. The file is included in the initramfs at
/include-files/{filename} and --config /include-files/{filename}
is prepended to sched_args.
config_file_def: Option<(&'static str, &'static str)>Declares how an inline config is passed to the scheduler.
First element: CLI arg template with {file} placeholder
(e.g. "f:{file}", "--config {file}"). Second element:
guest filesystem path where the JSON is written
(e.g. "/include-files/layered.json"). The framework
mkdir -ps the parent and writes the config content there.
kernels: &'static [&'static str]Per-scheduler filter on the verifier sweep matrix.
Each entry is a string consumed by KernelId::parse
at verifier runtime — same parser as the
cargo ktstr verifier --kernel <SPEC> CLI flag. Accepts exact
versions ("6.14"), closed ranges spelled either .. or ..=
("6.14..7.0" or "6.14..=7.0" — both inclusive on both
endpoints), git refs ("git+URL#tag=NAME"), paths, and cache keys.
The verifier sweep matrix is driven by the operator’s
cargo ktstr verifier --kernel <SPEC> set (which the
dispatcher always populates into KTSTR_KERNEL_LIST — even
the no---kernel case synthesizes a single auto-discovered
entry). For each scheduler,
list_verifier_cells_all in test_support::dispatch
emits a cell per (kernel-list entry that passes this filter ×
accepted gauntlet topology preset).
Match semantics per spec variant:
Version: raw-label string equality OR sanitized-label match against the kernel-list entry.Range: range-membership check viadecompose_version_for_compareon the entry’s raw version string. Lets a scheduler declaringkernels = ["6.14..6.16"]match any operator-supplied kernel whose version falls in[6.14, 6.16]inclusive.Path/CacheKey/Git: sanitized-label equality.
Empty (&[]) means no filter — the scheduler verifies
against every entry in KTSTR_KERNEL_LIST.
Implementations§
Source§impl Scheduler
impl Scheduler
Sourcepub const EEVDF: Scheduler
pub const EEVDF: Scheduler
Placeholder scheduler representing “no scx scheduler.” Tests
that use Scheduler::EEVDF run under the kernel’s default
scheduler (EEVDF on current kernels), with no scheduler binary
launched. Useful as a baseline and for tests that exercise
framework behavior independent of any scx scheduler.
The .name is the compile-time-fixed string "eevdf" — NOT
runtime-derived from the live kernel. A sidecar written on a
kernel whose default is a successor scheduling class still
records "eevdf" here as long as the test attributes this
Scheduler to a run. The sidecar reads
self.name directly via the scheduler field
projection.
The sidecar itself does not carry the mapping from kernel
version to scheduling class: the host.kernel_release
field records the live kernel’s release string (6.6.12,
6.14.2, …) and nothing else. Consumers that need to answer
“did this run actually use EEVDF?” must combine
host.kernel_release with version-to-class knowledge
maintained OUTSIDE the sidecar — e.g. an external lookup
table that records the default scheduling class per upstream
kernel release. A sidecar alone cannot distinguish a true
EEVDF run from a run on a successor-class kernel that
reused the same "eevdf" label via
Scheduler::EEVDF’s compile-time-fixed .name.
Sourcepub const fn named(name: &'static str) -> Scheduler
pub const fn named(name: &'static str) -> Scheduler
Const constructor for defining schedulers in static context.
Caller chains Self::binary (or
Self::binary_discover) plus any of the other const-fn
builders to override the per-field defaults; the unset
fields stay at the values below.
Defaults (intentional — these compose with the
per-test #[ktstr_test] attributes via merge, so every
field has a no-op identity that lets per-test overrides
take precedence):
binary:SchedulerSpec::Eevdf— kernel default scheduling class, no scheduler binary launched. Override viaSelf::binary/Self::binary_discover.sysctls/kargs/sched_args: empty slices — no guest sysctls applied, no extra kernel cmdline args, no extra scheduler CLI args.assert:crate::assert::Assert::NO_OVERRIDES— no threshold overrides on top ofcrate::assert::Assert::default_checks.cgroup_parent:None— no--cell-parent-cgroupinjection.topology:1 numa × 1 llc × 2 cores × 1 thread— smallest meaningful topology for a quick smoke scheduler. Override viaSelf::topology.constraints:TopologyConstraints::DEFAULT— no gauntlet limits.config_file/config_file_def:None— no config file plumbing. Setting both at construction is rejected at validation time.kernels: empty slice — verifies against every kernel in the operator’s--kernelset (no per-scheduler filter).
Sourcepub const fn binary(self, binary: SchedulerSpec) -> Self
pub const fn binary(self, binary: SchedulerSpec) -> Self
Set the binary spec. Returns self for const chaining.
Sourcepub const fn binary_discover(self, name: &'static str) -> Self
pub const fn binary_discover(self, name: &'static str) -> Self
Sugar for .binary(SchedulerSpec::Discover(name)) — the
dominant Scheduler construction path. Use when the scheduler
binary is on PATH under the named filename (e.g.
.binary_discover("scx_rusty")) and the framework should
resolve it at guest-init time via which-style lookup.
Equivalent to:
Scheduler::named("rusty").binary(SchedulerSpec::Discover("scx_rusty"))
// is equivalent to
Scheduler::named("rusty").binary_discover("scx_rusty")For an explicit absolute path (no PATH lookup), call
.binary(SchedulerSpec::Path("/absolute/path")) directly —
the path variant has no chainable sugar because absolute
paths are the rare case (cross-compiled trees, ad-hoc
installs) and a path-typed setter would obscure the intent.
Sourcepub const fn sysctls(self, sysctls: &'static [Sysctl]) -> Self
pub const fn sysctls(self, sysctls: &'static [Sysctl]) -> Self
Set sysctls. Returns self for const chaining.
Sourcepub const fn kargs(self, kargs: &'static [&'static str]) -> Self
pub const fn kargs(self, kargs: &'static [&'static str]) -> Self
Set kernel args. Returns self for const chaining.
Sourcepub const fn assert(self, assert: Assert) -> Self
pub const fn assert(self, assert: Assert) -> Self
Set assertion config. Returns self for const chaining.
Sourcepub const fn cgroup_parent(self, path: &'static str) -> Self
pub const fn cgroup_parent(self, path: &'static str) -> Self
Set cgroup parent path. See the cgroup_parent
field for path format requirements (must begin with /, must
not be "/" alone).
Sourcepub const fn sched_args(self, args: &'static [&'static str]) -> Self
pub const fn sched_args(self, args: &'static [&'static str]) -> Self
Set scheduler CLI args prepended before per-test
extra_sched_args.
Sourcepub const fn topology(
self,
numa_nodes: u32,
llcs: u32,
cores: u32,
threads: u32,
) -> Self
pub const fn topology( self, numa_nodes: u32, llcs: u32, cores: u32, threads: u32, ) -> Self
Set the default VM topology for tests using this scheduler.
Tests inherit this unless they override individual dimensions
explicitly in #[ktstr_test].
Sourcepub const fn constraints(self, constraints: TopologyConstraints) -> Self
pub const fn constraints(self, constraints: TopologyConstraints) -> Self
Set gauntlet topology constraints. Tests inherit these unless
they override specific fields in #[ktstr_test].
Sourcepub const fn min_numa_nodes(self, n: u32) -> Self
pub const fn min_numa_nodes(self, n: u32) -> Self
Set minimum number of NUMA nodes.
Sourcepub const fn max_numa_nodes(self, n: u32) -> Self
pub const fn max_numa_nodes(self, n: u32) -> Self
Set maximum number of NUMA nodes.
Sourcepub const fn requires_smt(self, v: bool) -> Self
pub const fn requires_smt(self, v: bool) -> Self
Set whether the scheduler requires SMT.
Sourcepub const fn config_file(self, path: &'static str) -> Self
pub const fn config_file(self, path: &'static str) -> Self
Set a host-side config file path. The file is included in the
guest initramfs and --config is injected into scheduler args.
Sourcepub const fn config_file_def(
self,
arg_template: &'static str,
guest_path: &'static str,
) -> Self
pub const fn config_file_def( self, arg_template: &'static str, guest_path: &'static str, ) -> Self
Declare how inline config content is passed to the scheduler.
arg_template: CLI arg with {file} placeholder for the
guest path (e.g. "f:{file}", "--config {file}").
guest_path: where the JSON is written in the guest
(e.g. "/include-files/layered.json").
Sourcepub const fn kernels(self, kernels: &'static [&'static str]) -> Self
pub const fn kernels(self, kernels: &'static [&'static str]) -> Self
Set the kernel specs the verifier should exercise this scheduler
against. See Self::kernels for the
accepted string shapes.
Sourcepub const fn has_active_scheduling(&self) -> bool
pub const fn has_active_scheduling(&self) -> bool
Whether this scheduler runs an active scheduling policy
(anything other than the kernel default EEVDF). Forwards to
SchedulerSpec::has_active_scheduling.
Kept (unlike the trivial name / binary accessors that were
dropped) because the 11+ call sites in crate::test_support::eval / probe.rs
would otherwise spell entry.scheduler.binary.has_active_scheduling()
at every dispatch decision — the .binary. indirection
repeats noise without adding meaning. The forwarder is one
line of glue for a recurring readability win.
Returns true for KernelBuiltin schedulers. See
Self::has_bpf_scheduler for the narrower gate that
excludes them (the right gate when callers assume a
userspace BPF binary is attached).
Sourcepub const fn has_bpf_scheduler(&self) -> bool
pub const fn has_bpf_scheduler(&self) -> bool
Whether this scheduler attaches a userspace BPF binary.
Forwards to SchedulerSpec::has_bpf_scheduler.
Same .binary. elision rationale as
Self::has_active_scheduling — saves
entry.scheduler.binary.has_bpf_scheduler() ceremony at
every BPF-attach-intent dispatch site.
Returns false for KernelBuiltin (no userspace binary)
AND Eevdf (no scheduler). Use this whenever the caller
would react to BPF artifacts — verifier_stats wiring,
monitor thresholds, auto-repro probe gating.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Scheduler
impl RefUnwindSafe for Scheduler
impl Send for Scheduler
impl Sync for Scheduler
impl Unpin for Scheduler
impl UnwindSafe for Scheduler
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more