Skip to content
This repository was archived by the owner on Jun 18, 2024. It is now read-only.

Commit 97b9dec

Browse files
Dan Schatzberghtejun
authored andcommitted
sched_ext: Add a rust userspace hybrid example scheduler
Atropos is a multi-domain BPF / userspace hybrid scheduler where the BPF part does simple round robin in each domain and the userspace part calculates the load factor of each domain and tells the BPF part how to load balance the domains. This scheduler demonstrates dividing scheduling logic between BPF and userspace and using rust to build the userspace part. An earlier variant of this scheduler was used to balance across six domains, each representing a chiplet in a six-chiplet AMD processor, and could match the performance of production setup using CFS. v4: * tools/sched_ext/atropos renamed to tools/sched_ext/scx_atropos for consistency. * LoadBalancer sometimes couldn't converge on balanced state due to restrictions it put on each balancing operation. Fixed. * Topology information refactored into struct Topology and Tuner is added. Tuner runs in shorter cycles (100ms) than LoadBalancer and dynamically adjusts scheduling behaviors, currently, based on the per-domain utilization states. * ->select_cpu() has been revamped. Combined with other improvements, this allows atropos to outperform CFS in various sub-saturation scenarios when tested with fio over dm-crypt. * Many minor code cleanups and improvements. v3: * The userspace code is substantially restructured and rewritten. The binary is renamed to scx_atropos and can now figure out the domain topology automatically based on L3 cache configuration. The LB logic which was rather broken in the previous postings are revamped and should behave better. * Updated to support weighted vtime scheduling (can be turned off with --fifo-sched). Added a couple options (--slice_us, --kthreads-local) to modify scheduling behaviors. * Converted to use BPF inline iterators. v2: * Updated to use generic BPF cpumask helpers. Signed-off-by: Dan Schatzberg <dschatzberg@meta.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent 3b7b9da commit 97b9dec

File tree

9 files changed

+2367
-2
lines changed

9 files changed

+2367
-2
lines changed

tools/sched_ext/Makefile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ CFLAGS += -g -O2 -rdynamic -pthread -Wall -Werror $(GENFLAGS) \
8585
-I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR) \
8686
-I$(TOOLSINCDIR) -I$(APIDIR)
8787

88+
CARGOFLAGS := --release
89+
8890
# Silence some warnings when compiled with clang
8991
ifneq ($(LLVM),)
9092
CFLAGS += -Wno-unused-command-line-argument
@@ -115,7 +117,7 @@ BPF_CFLAGS = -g -D__TARGET_ARCH_$(SRCARCH) \
115117
-Wall -Wno-compare-distinct-pointer-types \
116118
-O2 -mcpu=v3
117119

118-
all: scx_simple scx_qmap scx_central scx_pair scx_flatcg scx_userland
120+
all: scx_simple scx_qmap scx_central scx_pair scx_flatcg scx_userland scx_atropos
119121

120122
# sort removes libbpf duplicates when not cross-building
121123
MAKE_DIRS := $(sort $(BUILD_DIR)/libbpf $(HOST_BUILD_DIR)/libbpf \
@@ -190,12 +192,19 @@ scx_userland: scx_userland.c scx_userland.skel.h scx_userland.h user_exit_info.h
190192
$(CC) $(CFLAGS) -c $< -o $@.o
191193
$(CC) -o $@ $@.o $(HOST_BPFOBJ) $(LDFLAGS)
192194

195+
scx_atropos: export RUSTFLAGS = -C link-args=-lzstd -C link-args=-lz -C link-args=-lelf -L $(BPFOBJ_DIR)
196+
scx_atropos: export ATROPOS_CLANG = $(CLANG)
197+
scx_atropos: export ATROPOS_BPF_CFLAGS = $(BPF_CFLAGS)
198+
scx_atropos: $(INCLUDE_DIR)/vmlinux.h
199+
cargo build --manifest-path=scx_atropos/Cargo.toml $(CARGOFLAGS)
200+
193201
clean:
202+
cargo clean --manifest-path=scx_atropos/Cargo.toml
194203
rm -rf $(SCRATCH_DIR) $(HOST_SCRATCH_DIR)
195204
rm -f *.o *.bpf.o *.skel.h *.subskel.h
196205
rm -f scx_simple scx_qmap scx_central scx_pair scx_flatcg scx_userland
197206

198-
.PHONY: all clean
207+
.PHONY: all scx_atropos clean
199208

200209
# delete failed targets
201210
.DELETE_ON_ERROR:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
src/bpf/.output
2+
Cargo.lock
3+
target
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[package]
2+
name = "scx_atropos"
3+
version = "0.5.0"
4+
authors = ["Dan Schatzberg <dschatzberg@meta.com>", "Meta"]
5+
edition = "2021"
6+
description = "Userspace scheduling with BPF"
7+
license = "GPL-2.0-only"
8+
9+
[dependencies]
10+
anyhow = "1.0.65"
11+
bitvec = { version = "1.0", features = ["serde"] }
12+
clap = { version = "4.1", features = ["derive", "env", "unicode", "wrap_help"] }
13+
ctrlc = { version = "3.1", features = ["termination"] }
14+
hex = "0.4.3"
15+
libbpf-rs = "0.19.1"
16+
libbpf-sys = { version = "1.0.4", features = ["novendor", "static"] }
17+
libc = "0.2.137"
18+
log = "0.4.17"
19+
ordered-float = "3.4.0"
20+
simplelog = "0.12.0"
21+
22+
[build-dependencies]
23+
bindgen = { version = "0.61.0" }
24+
libbpf-cargo = "0.13.0"
25+
26+
[features]
27+
enable_backtrace = []
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) Meta Platforms, Inc. and affiliates.
2+
3+
// This software may be used and distributed according to the terms of the
4+
// GNU General Public License version 2.
5+
extern crate bindgen;
6+
7+
use std::env;
8+
use std::fs::create_dir_all;
9+
use std::path::Path;
10+
use std::path::PathBuf;
11+
12+
use libbpf_cargo::SkeletonBuilder;
13+
14+
const HEADER_PATH: &str = "src/bpf/atropos.h";
15+
16+
fn bindgen_atropos() {
17+
// Tell cargo to invalidate the built crate whenever the wrapper changes
18+
println!("cargo:rerun-if-changed={}", HEADER_PATH);
19+
20+
// The bindgen::Builder is the main entry point
21+
// to bindgen, and lets you build up options for
22+
// the resulting bindings.
23+
let bindings = bindgen::Builder::default()
24+
// The input header we would like to generate
25+
// bindings for.
26+
.header(HEADER_PATH)
27+
// Tell cargo to invalidate the built crate whenever any of the
28+
// included header files changed.
29+
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
30+
// Finish the builder and generate the bindings.
31+
.generate()
32+
// Unwrap the Result and panic on failure.
33+
.expect("Unable to generate bindings");
34+
35+
// Write the bindings to the $OUT_DIR/bindings.rs file.
36+
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
37+
bindings
38+
.write_to_file(out_path.join("atropos-sys.rs"))
39+
.expect("Couldn't write bindings!");
40+
}
41+
42+
fn gen_bpf_sched(name: &str) {
43+
let bpf_cflags = env::var("ATROPOS_BPF_CFLAGS").unwrap();
44+
let clang = env::var("ATROPOS_CLANG").unwrap();
45+
eprintln!("{}", clang);
46+
let outpath = format!("./src/bpf/.output/{}.skel.rs", name);
47+
let skel = Path::new(&outpath);
48+
let src = format!("./src/bpf/{}.bpf.c", name);
49+
SkeletonBuilder::new()
50+
.source(src.clone())
51+
.clang(clang)
52+
.clang_args(bpf_cflags)
53+
.build_and_generate(&skel)
54+
.unwrap();
55+
println!("cargo:rerun-if-changed={}", src);
56+
}
57+
58+
fn main() {
59+
bindgen_atropos();
60+
// It's unfortunate we cannot use `OUT_DIR` to store the generated skeleton.
61+
// Reasons are because the generated skeleton contains compiler attributes
62+
// that cannot be `include!()`ed via macro. And we cannot use the `#[path = "..."]`
63+
// trick either because you cannot yet `concat!(env!("OUT_DIR"), "/skel.rs")` inside
64+
// the path attribute either (see https://github.com/rust-lang/rust/pull/83366).
65+
//
66+
// However, there is hope! When the above feature stabilizes we can clean this
67+
// all up.
68+
create_dir_all("./src/bpf/.output").unwrap();
69+
gen_bpf_sched("atropos");
70+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Get help on options with `rustfmt --help=config`
2+
# Please keep these in alphabetical order.
3+
edition = "2021"
4+
group_imports = "StdExternalCrate"
5+
imports_granularity = "Item"
6+
merge_derives = false
7+
use_field_init_shorthand = true
8+
version = "Two"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) Meta Platforms, Inc. and affiliates.
2+
3+
// This software may be used and distributed according to the terms of the
4+
// GNU General Public License version 2.
5+
#![allow(non_upper_case_globals)]
6+
#![allow(non_camel_case_types)]
7+
#![allow(non_snake_case)]
8+
#![allow(dead_code)]
9+
10+
include!(concat!(env!("OUT_DIR"), "/atropos-sys.rs"));

0 commit comments

Comments
 (0)