Scheduler

Struct Scheduler 

Source
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 str

Short human name for the scheduler, used in logs and sidecar metadata.

§binary: SchedulerSpec

Source 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:

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: Assert

Scheduler-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: Topology

Default 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: TopologyConstraints

Gauntlet 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 via decompose_version_for_compare on the entry’s raw version string. Lets a scheduler declaring kernels = ["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

Source

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.

Source

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 via Self::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 of crate::assert::Assert::default_checks.
  • cgroup_parent: None — no --cell-parent-cgroup injection.
  • topology: 1 numa × 1 llc × 2 cores × 1 thread — smallest meaningful topology for a quick smoke scheduler. Override via Self::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 --kernel set (no per-scheduler filter).
Source

pub const fn binary(self, binary: SchedulerSpec) -> Self

Set the binary spec. Returns self for const chaining.

Source

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.

Source

pub const fn sysctls(self, sysctls: &'static [Sysctl]) -> Self

Set sysctls. Returns self for const chaining.

Source

pub const fn kargs(self, kargs: &'static [&'static str]) -> Self

Set kernel args. Returns self for const chaining.

Source

pub const fn assert(self, assert: Assert) -> Self

Set assertion config. Returns self for const chaining.

Source

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).

Source

pub const fn sched_args(self, args: &'static [&'static str]) -> Self

Set scheduler CLI args prepended before per-test extra_sched_args.

Source

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].

Source

pub const fn constraints(self, constraints: TopologyConstraints) -> Self

Set gauntlet topology constraints. Tests inherit these unless they override specific fields in #[ktstr_test].

Source

pub const fn min_numa_nodes(self, n: u32) -> Self

Set minimum number of NUMA nodes.

Source

pub const fn max_numa_nodes(self, n: u32) -> Self

Set maximum number of NUMA nodes.

Source

pub const fn min_llcs(self, n: u32) -> Self

Set minimum number of LLCs.

Source

pub const fn max_llcs(self, n: u32) -> Self

Set maximum number of LLCs.

Source

pub const fn requires_smt(self, v: bool) -> Self

Set whether the scheduler requires SMT.

Source

pub const fn min_cpus(self, n: u32) -> Self

Set minimum total CPU count.

Source

pub const fn max_cpus(self, n: u32) -> Self

Set maximum total CPU count.

Source

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.

Source

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").

Source

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.

Source

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).

Source

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§

Source§

impl Debug for Scheduler

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> MaybeSend for T
where T: Send,

§

impl<T> MaybeSend for T
where T: Send,