Source code for kSTEP: Characterization and Deterministic Testing of Linux CPU Scheduler Bugs. (OSDI '26).
Tingjia Cao, Shawn Wanxiang Zhong, Caeden Whitaker, Ke Han, Andrea Arpaci-Dusseau, and Remzi Arpaci-Dusseau
📄 Paper · 💻 Code (osdi26) · 🌐 Website · 📚 Study · 📊 Results
# 📦 Clone the repository (add `--branch osdi26` to reproduce the paper exactly)
git clone --recurse-submodules https://github.com/kstep-dev/kstep && cd kstep# 💾 Install dependencies
./setup.sh# 🐞 Reproduce bugs
# ./kstep.sh reproduce <name|all|extra> [--steps buggy fixed plot]
# 1. Checks out the buggy and fixed kernels
# 2. Builds and runs the bug's driver on each
# 3. Plots the two traces
./kstep.sh reproduce sync_wakeup| kSTEP Driver, Fix, and Output | Figure |
|---|---|
| sync_wakeup.c Official Fix: linux@aa3ee4f Our Fix: sync_wakeup.patch buggy.jsonl, fixed.jsonl |
![]() |
| vruntime_overflow.c Fix: linux@bbce3de buggy.jsonl, fixed.jsonl |
![]() |
| freeze.c Fix: linux@cd9626e buggy.jsonl, fixed.jsonl |
![]() |
| extra_balance.c Fix: linux@6d7e478 buggy.jsonl, fixed.jsonl |
![]() |
| driver_util_avg.c Fix: linux@17e3e88 buggy.jsonl, fixed.jsonl |
![]() |
| long_balance.c Fix: linux@2feab24 buggy.jsonl, fixed.jsonl |
![]() |
| lag_vruntime.c Fix: linux@5068d84 buggy.jsonl, fixed.jsonl |
![]() |
| even_idle_cpu.c Fix: even_idle_cpu.patch buggy.jsonl, fixed.jsonl |
![]() |
| local_group_imbalance.c Fix: fix_local_group_imbalanced.patch buggy.jsonl, fixed.jsonl |
![]() |
| util_avg_jump.c Fix: fix_util_avg_jump.patch buggy.jsonl, fixed.jsonl |
![]() |
| rt_runtime_toggle.c Fix: linux@9b58e97 buggy.jsonl, fixed.jsonl |
![]() |
| uclamp_inversion.c Fix: linux@0213b70 buggy.jsonl, fixed.jsonl |
![]() |
| h_nr_runnable.c Fix: linux@3429dd5 buggy.jsonl, fixed.jsonl |
![]() |
For driver development, please refer to AGENTS.md for recommended workflow and tips.
./kstep.sh checkout <ref> [<name>] [--git] [--patch <file>] [--keep-current]<ref>: Linux tag (e.g.,v6.14) or commit hash (e.g.,6d7e478,5068d84~1).- Default: download a tarball from kernel.org / GitHub (fast, one-shot).
--git: add a worktree ofbuild/master(multi-version dev, supportsgit log/git diff). - Example:
./kstep.sh checkout v6.14 foo_buggychecks out Linux v6.14 underbuild/foo_buggy/linux/and pointsbuild/currentatbuild/foo_buggy/.
./kstep.sh build [<name>] # kmod + user + rootfs.cpio; builds the kernel first if needed
./kstep.sh build [<name>] --linux [--config F] # reconfigure and rebuild the kernel; run after Linux file changes[<name>]: build directory underbuild/; defaults to whateverbuild/currentpoints to. A bug's build (<bug>_buggy,<bug>_fixed) or a Linux version (v6.18) is checked out first if missing.
./kstep.sh run [<name>] [<driver>] [--num-cpus <n>] [--mem-mb <mb>] [-o <dir>] [-i <file>]-
[<name>]: kernel build to run against (defaults tobuild/current). A bug's build,<bug>_buggyor<bug>_fixed, brings the bug's driver and machine frombugs.yaml. -
[<driver>]: driver to run (see*.cfiles inkmod/drivers/); defaults tocli, an interactive session: type commands (listed at the top ofkmod/cli.c), see the machine after each.-i <file>or a pipe scripts one. -
[-o <dir>]: subdir underresults/for output; defaults to a timestampedtmp_*dir.results/latestsymlinks to it. -
--debugstarts the guest stopped with a gdb stub;./kstep.sh gdb [<name>]attaches. -
Example:
./kstep.sh run sync_wakeup_buggyruns thesync_wakeupdriver on its buggy kernel, checking it out and building it first if needed.
-
kmod/: Kernel module (
kmod.ko) loaded at bootdrivers/: bug-specific drivers (one.cper bug)checkers/: rules over scheduler state and decisions, enabled by the cli'scheckverbcli.c: interactive driver behind the website playground (text commands in and JSON replies out on the virtio console port)cpu.c: topology, capacity and frequency setup, behind thecpu-topo/cpu-cap/cpu-freqcli verbsdriver.h: public API for drivers (task creation, ticking, cgroups, etc.)internal.hand other top-level*.c: framework primitives
-
user/: Minimal userspace (
user.c) that mounts filesystems and loadskmod.ko -
linux/: Project-static kernel files (committed to git)
config.kstep*: Kconfig fragments merged into the buildcov.c,Kconfig.kstep,Makefile.kstep: scheduler-coverage instrumentation*.patch: Fixes for specific bugs
-
build/: Per-kernel build artifacts (gitignored, regenerable)
current: symlink to the active<name>/(set bykstep checkout)master/: kernel clone reused bykstep checkout --gituser: statically linked userspace binary<name>/:kernel(the image QEMU boots: the bzImage on x86, the Image on arm64; plusvmlinuxfor gdb/addr2line) androotfs.cpio(kmod.ko + user);linux/source tree;kmod/module build dir withkmod.koand the clangdcompile_commands.json(the project root symlinks to it)
-
results/: Run outputs. See
results/README.md.repro_<bug>/is tracked;tmp_*are gitignored. The fuzzer's per-client runs land infuzz_<build>_<n>/. -
crates/: the Rust tooling.
core/is what the website's wasm decoder shares with the binaries (thekmod/shm.hdecoder, generated from the header, and the QEMU command line);kstep/is thekstepcommand (./kstep.sh): checkout, build, run, reproduce, viz;fuzz/is the LibAFL fuzzer (./kstep-fuzz.sh <bug>), a host-side client of theclidriver, with corpora and findings underfuzz/(gitignored)- the earlier in-guest fuzzer is kept for reference in
docs/archive/old_fuzzer/
- the earlier in-guest fuzzer is kept for reference in
-
scripts/: the plot scripts (Python, self-contained:
uv run --script scripts/plot_<format>.py <bug>), whichkstep reproduceruns. -
bugs.yaml: one entry per bug -- how to build, run, reproduce and fuzz it; read by
kstep run,kstep reproduceand the fuzzer












