SchedulerSpec

Enum SchedulerSpec 

Source
pub enum SchedulerSpec {
    Eevdf,
    Discover(&'static str),
    Path(&'static str),
    KernelBuiltin {
        enable: &'static [&'static str],
        disable: &'static [&'static str],
    },
}
Expand description

How to specify the scheduler for an #[ktstr_test].

The four variants form a semantic taxonomy, not a syntactic one: Eevdf is the no-scx control (“kernel default, don’t launch anything”); Discover and Path both locate a userspace scheduler binary, by name-lookup vs. explicit filesystem path respectively; and KernelBuiltin activates an in-kernel scheduling policy via shell commands rather than any binary.

Variants§

§

Eevdf

No userspace scheduler — run under the kernel’s default scheduler. On current kernels that’s EEVDF; the variant name is fixed so the assertion isn’t coupled to the kernel version’s default.

§

Discover(&'static str)

Auto-discover the scheduler binary by name (looks in KTSTR_SCHEDULER env, the ktstr binary’s sibling dir, target/debug/, target/release/, and invokes cargo build if nothing’s found).

§

Path(&'static str)

Explicit filesystem path to a scheduler binary. The file must already exist; resolve_scheduler does not auto-build this variant.

§

KernelBuiltin

Kernel-built scheduler (e.g. BPF-less sched_ext or debugfs-tuned). Activated/deactivated via shell commands rather than a userspace binary.

Fields

§enable: &'static [&'static str]

Shell commands invoked before the scenario runs to switch the kernel into this scheduling policy (e.g. write to /sys/kernel/debug/sched/...).

§disable: &'static [&'static str]

Shell commands invoked after the scenario finishes to restore the kernel’s baseline scheduling policy.

Implementations§

Source§

impl SchedulerSpec

Source

pub const fn has_active_scheduling(&self) -> bool

Whether this spec represents an active scheduling policy (anything other than the kernel default EEVDF).

Returns true for every variant except Self::Eevdf — including Self::KernelBuiltin, which runs an in-kernel non-default policy via shell enable/disable commands but has no userspace BPF binary. Callers that need “the test runs SOMETHING other than EEVDF” — e.g. enabling repro-section render, switching verbose-output mode on, gating non-default-only logic — want this method.

Callers that need “the test runs a userspace BPF scheduler binary with verifier-stats / struct_ops slab activity” — e.g. wiring monitor thresholds, surfacing verifier_stats warnings, gating the auto-repro probe — want the narrower Self::has_bpf_scheduler instead. has_active_scheduling returns true for KernelBuiltin, which is the wrong gate for any code path that assumes a BPF binary is attached.

Quick gate-picker: use has_active_scheduling when the predicate is “non-default scheduling policy”; use Self::has_bpf_scheduler when the predicate is “userspace BPF binary attached”.

Source

pub const fn has_bpf_scheduler(&self) -> bool

Whether this spec drives a userspace BPF scheduler binary (i.e. attaches a struct sched_ext_ops to the kernel).

Returns true for Self::Discover and Self::Path — both variants point at a userspace BPF binary that resolve_scheduler locates and launches. Returns false for Self::Eevdf (no scheduler) and Self::KernelBuiltin (in-kernel policy switched via shell commands, no userspace binary, no BPF verifier output, no struct_ops slab activity).

Distinct from Self::has_active_scheduling: that returns true for KernelBuiltin too (because the kernel IS running a non-default scheduling policy), which is the wrong gate for code paths that read verifier_stats, wire BPF-attach monitor thresholds, or probe for the userspace scheduler binary’s auto-repro hooks. Use this method whenever the downstream consumer assumes “BPF binary is loaded and running” rather than “the kernel is on a non-EEVDF policy”.

Source

pub const fn display_name(&self) -> &'static str

Short, human-readable name for logging and sidecar output.

Maps Eevdf"eevdf", Discover(n)n, Path(p)p, KernelBuiltin { .. }"kernel". Single source of truth for “what do we call this scheduler when telling the user” — sidecar serialization and failure-header formatting both use this, and any future consumer gets identical naming for free.

Source

pub const fn scheduler_commit(&self) -> Option<&'static str>

Best-effort git commit of the scheduler binary used for this run, or None when the commit cannot be determined honestly.

Currently ALWAYS returns None. The field is reserved on the sidecar schema so stats tooling can enrich it once a reliable source exists, but no variant today has one:

  • Eevdf — no userspace scheduler binary at all. Kernel default; the running kernel’s identity belongs in host.kernel_release, not here.
  • Discover(_)resolve_scheduler has a 5-path cascade (KTSTR_SCHEDULER env override → sibling of the ktstr binary → target/debug/target/release/ → cargo rebuild fallback). Only the rebuild path guarantees the resulting binary was built from the current tree; the four pre-built discovery paths can point at a binary whose commit is unknown to this process. Synthesizing a commit would be a lie in 4 of 5 cases and would silently attribute regressions to the wrong commit. A future enhancement can probe the binary itself (e.g. --version output, an ELF note) and return Some(..) ONLY when the actual commit is introspected; until then, None is the only honest answer.
  • Path(p) — arbitrary externally-built binary. No reliable introspection path (no shared ABI, no required --version format).
  • KernelBuiltin — in-kernel scheduler, no userspace binary commit to record.

Returning None rather than Some("unknown") keeps the sidecar schema’s nullable semantics honest: perf-delta distinguishes “unset” from “set to a sentinel” without a magic string, and a future enhancement that learns to introspect a scheduler binary can flip a single arm to Some(..) without retrofitting consumers to strip a sentinel.

Trait Implementations§

Source§

impl Clone for SchedulerSpec

Source§

fn clone(&self) -> SchedulerSpec

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SchedulerSpec

Source§

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

Formats the value using the given formatter. Read more
Source§

impl From<&SchedulerSpec> for SchedulerKind

Source§

fn from(spec: &SchedulerSpec) -> Self

Single source of truth for the SchedulerSpec → SchedulerKind mapping. Exhaustive match so adding a 5th SchedulerSpec variant triggers a compile error here, forcing the discriminator to grow in lockstep.

Source§

impl Hash for SchedulerSpec

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for SchedulerSpec

Source§

fn eq(&self, other: &SchedulerSpec) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for SchedulerSpec

Source§

impl Eq for SchedulerSpec

Source§

impl StructuralPartialEq for SchedulerSpec

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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,