Expand description
scx_mlfq, a Multilevel Feedback Queue scheduler for sched_ext.
Per-CPU, virtual-time-ordered user DSQs (Q1/Q2/Q3 per CPU) over an EEVDF virtual-time substrate. Tasks are classified into queues by a regression tree that predicts the next CPU burst from per-task features (see mlfq_tree.rs), with the EMA interactivity gauge as a tree feature and the fallback before the first model. The wakeup path is promotion-only, through the tree, the short-sleep and I/O boost and the band hysteresis. Demotion flows through the run-out gate. See README.md for the design overview.
Re-exportsยง
pub(crate) use std::collections::HashMap;๐pub(crate) use std::collections::HashSet;๐pub(crate) use std::collections::VecDeque;๐pub(crate) use std::mem::MaybeUninit;๐pub(crate) use std::mem::size_of;๐pub(crate) use std::os::fd::AsFd;๐pub(crate) use std::os::fd::AsRawFd;๐pub(crate) use std::sync::Arc;๐pub(crate) use std::sync::atomic::AtomicBool;๐pub(crate) use std::sync::atomic::Ordering;๐pub(crate) use std::time::Duration;๐pub(crate) use anyhow::Result;๐pub(crate) use clap::CommandFactory;๐pub(crate) use clap::Parser;๐pub(crate) use clap_complete::Shell;๐pub(crate) use clap_complete::generate;๐pub(crate) use crossbeam::channel::RecvTimeoutError;๐pub(crate) use libbpf_rs::AsRawLibbpf;๐pub(crate) use libbpf_rs::MapCore;๐pub(crate) use log::info;๐pub(crate) use scx_utils::UserExitInfo;๐pub(crate) use scx_utils::build_id;๐pub(crate) use scx_utils::compat;๐pub(crate) use scx_utils::libbpf_clap_opts::LibbpfOpts;๐pub(crate) use scx_utils::pm;๐pub(crate) use scx_utils::scx_ops_attach;๐pub(crate) use scx_utils::scx_ops_load;๐pub(crate) use scx_utils::scx_ops_open;๐pub(crate) use scx_utils::try_set_rlimit_infinity;๐pub(crate) use scx_utils::uei_exited;๐pub(crate) use scx_utils::uei_report;๐pub use bpf_intf::*;pub(crate) use scx_stats::prelude::*;๐
Modulesยง
- alloc ๐
- bpf_
intf - bpf_
skel ๐ - config ๐
- Userspace configuration, validated scheduling constants written into BPF rodata.
- imp
- mlfq_
tree ๐ - CART regression tree for next-CPU-burst prediction.
- stats ๐
- Stats server,
#[derive(Stats)]metrics and monitor loop. - topology ๐
- Hybrid-capacity and cache-domain topology discovery.
- types
- webui ๐
- Loopback web UI: live scheduler metrics as a small HTTP server.
Structsยง
- BpfLinks
- BpfMaps
- BpfProgs
- BpfSkel
- BpfSkel
Builder - Config ๐
- Validated scheduling constants.
- FitScratch ๐
- Scratch buffers for the CART fit, sized to the maximum window and node budget. The buffers are allocated once with the capacities below and reused across fits by clearing in place, so the training path does not allocate after the first fit. The queue holds owned sample vectors per node; those vectors are still allocated per node, but the major buffers (weights, sorted, left/right) are reused. This keeps the 60s training free of steady-state allocations while preserving the exact CART logic.
- Metrics ๐
- Model
Meta ๐ - Metadata of the committed MLFQ tree model, reported to the stats server and the exit log. Defaults describe the untrained state.
- Open
BpfMaps - Open
BpfProgs - Open
BpfSkel - Opts ๐
- Owned
Ref - Scheduler ๐
- The Scheduler facade owns the loaded skeleton, the struct_ops link, the stats server and the MLFQ tree daemon state; drives the run loop until shutdown or UEI exit.
- Struct
Ops - Train
Result ๐ - Result of one training run, handed back from the worker thread. The metrics are computed on the held-out slice so the publish gate and the reported numbers describe out-of-sample error.
- Tree
Sample ๐ - One training sample, the mirror of
struct mlfq_tree_sample.
Constantsยง
- MLFQ_
IDLE_ ๐RESUME_ LATENCY_ US - MLFQ_
MAX_ ๐CPUS - MLFQ_
TREE_ ๐MAX_ DEPTH - MLFQ_
TREE_ ๐MAX_ NODES - MLFQ_
TREE_ ๐MIN_ LEAF - MLFQ_
TREE_ ๐MIN_ PIDS - MLFQ_
TREE_ ๐MIN_ SAMPLES - MLFQ_
TREE_ ๐PER_ PID_ CAP - MLFQ_
TREE_ ๐RETRAIN_ INTERVAL - MLFQ_
TREE_ ๐WINDOW_ MAX - NSEC_
PER_ ๐USEC - SCHEDULER_
NAME ๐
Staticsยง
Functionsยง
- build_
skel_ config - full_
version ๐ - main ๐
- spawn_
train_ ๐worker - Spawn the training worker and return its job and result channels.
- split_
holdout ๐ - Split the window into the fit slice (first 90%) and the held-out evaluation slice (last 10%). The daemon only trains once the window holds MLFQ_TREE_MIN_SAMPLES samples, so the holdout is never empty in production; a window too small for a meaningful 90/10 split (< 20 samples) is an error, which the caller treats as a skipped training round (log + keep the previous model) instead of silently training and evaluating on the same slice.
- train_
model ๐ - Fit a tree and compute the holdout metrics, on the training worker.
- train_
model_ ๐with_ scratch - Fit a tree and compute holdout metrics reusing the scratch arena. The scratch buffers are cleared in place, so the second call with the same window size does not allocate.
- tree_
admit_ ๐pid - Admit one sample of
pidinto the window under the per-pid cap. Returns true when the sample is admitted and the pidโs count is incremented, false when the pid already holds its MLFQ_TREE_PER_PID_CAP share and the caller must drop the sample. Entries are pruned on eviction, not here: a pid at the cap keeps its entry until the window ages its samples out. - tree_
distinct_ ๐pids - Number of distinct pids in a slice, the concentration input for the per-pid cap.
- tree_
evict_ ๐pid - Remove one sample of
pidfrom the per-pid accounting when the window evicts its oldest sample, pruning the entry when the count reaches zero so the map cannot grow with retired pids.