This repository has been archived by the owner on Jun 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sched_ext: Add scx_layered, a highly configurable multi-layer scheduler
scx_layered allows classifying tasks into multiple layers and applying different scheduling policies to them. The configuration is specified in json and composed of two parts - matches and policies. The matches classify tasks into a layer and different scheduling policies can be applied to the layer. For example, if a layer is "Confined", its tasks are confined to the CPUs that are allocated to the layer. The CPU allocation is dynamically adjusted to target CPU utilization in a specific range. This can be used to e.g. confine managerial workloads to a small number of CPUs while leaving the rest for latency sensitive workloads. A layer can also be configured to preempt other non-preempting layers. This scheduler is limited in that it assumes homogenous CPUs in a single node and the load based CPU allocation limit doesn't work well yet. However, even in the current form, in an experimental deployment over ~1000 machines, it showed a significant (>5%) bandwidth gain with a large-scale latency sensitive workload. As sched_ext scheduler development style and cadence are different from kernel proper, the plan is to keep simpler example schedulers and one more generic scheduler (scx_rusty) in tree and publish others in a separate repository. This scheduler will be a part of that repo once ready. NOT_FOR_UPSTREAM_INCLUSION
- Loading branch information
Showing
10 changed files
with
2,912 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
src/bpf/.output | ||
Cargo.lock | ||
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
[package] | ||
name = "scx_layered" | ||
version = "0.0.1" | ||
authors = ["Tejun Heo <[email protected]>", "Meta"] | ||
edition = "2021" | ||
description = "Userspace scheduling with BPF for Ads" | ||
license = "GPL-2.0-only" | ||
|
||
[dependencies] | ||
anyhow = "1.0" | ||
bitvec = "1.0" | ||
clap = { version = "4.1", features = ["derive", "env", "unicode", "wrap_help"] } | ||
ctrlc = { version = "3.1", features = ["termination"] } | ||
fb_procfs = "0.7" | ||
lazy_static = "1.4" | ||
libbpf-rs = "0.21" | ||
libbpf-sys = { version = "1.2.0", features = ["novendor", "static"] } | ||
libc = "0.2" | ||
log = "0.4" | ||
serde = { version = "1.0", features = ["derive"] } | ||
serde_json = "1.0" | ||
simplelog = "0.12" | ||
|
||
[build-dependencies] | ||
bindgen = { version = "0.61" } | ||
libbpf-cargo = "0.21" | ||
glob = "0.3" | ||
|
||
[features] | ||
enable_backtrace = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright (c) Meta Platforms, Inc. and affiliates. | ||
|
||
// This software may be used and distributed according to the terms of the | ||
// GNU General Public License version 2. | ||
extern crate bindgen; | ||
|
||
use std::env; | ||
use std::fs::create_dir_all; | ||
use std::path::Path; | ||
use std::path::PathBuf; | ||
|
||
use glob::glob; | ||
use libbpf_cargo::SkeletonBuilder; | ||
|
||
const HEADER_PATH: &str = "src/bpf/layered.h"; | ||
|
||
fn bindgen_layered() { | ||
// Tell cargo to invalidate the built crate whenever the wrapper changes | ||
println!("cargo:rerun-if-changed={}", HEADER_PATH); | ||
|
||
// The bindgen::Builder is the main entry point | ||
// to bindgen, and lets you build up options for | ||
// the resulting bindings. | ||
let bindings = bindgen::Builder::default() | ||
// The input header we would like to generate | ||
// bindings for. | ||
.header(HEADER_PATH) | ||
// Tell cargo to invalidate the built crate whenever any of the | ||
// included header files changed. | ||
.parse_callbacks(Box::new(bindgen::CargoCallbacks)) | ||
// Finish the builder and generate the bindings. | ||
.generate() | ||
// Unwrap the Result and panic on failure. | ||
.expect("Unable to generate bindings"); | ||
|
||
// Write the bindings to the $OUT_DIR/bindings.rs file. | ||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
bindings | ||
.write_to_file(out_path.join("layered_sys.rs")) | ||
.expect("Couldn't write bindings!"); | ||
} | ||
|
||
fn gen_bpf_sched(name: &str) { | ||
let bpf_cflags = env::var("SCX_RUST_BPF_CFLAGS").unwrap(); | ||
let clang = env::var("SCX_RUST_CLANG").unwrap(); | ||
eprintln!("{}", clang); | ||
let outpath = format!("./src/bpf/.output/{}.skel.rs", name); | ||
let skel = Path::new(&outpath); | ||
let src = format!("./src/bpf/{}.bpf.c", name); | ||
let obj = format!("./src/bpf/.output/{}.bpf.o", name); | ||
SkeletonBuilder::new() | ||
.source(src.clone()) | ||
.obj(obj) | ||
.clang(clang) | ||
.clang_args(bpf_cflags) | ||
.build_and_generate(skel) | ||
.unwrap(); | ||
|
||
// Trigger rebuild if any .[hc] files are changed in the directory. | ||
for path in glob("./src/bpf/*.[hc]").unwrap().filter_map(Result::ok) { | ||
println!("cargo:rerun-if-changed={}", path.to_str().unwrap()); | ||
} | ||
} | ||
|
||
fn main() { | ||
bindgen_layered(); | ||
// It's unfortunate we cannot use `OUT_DIR` to store the generated skeleton. | ||
// Reasons are because the generated skeleton contains compiler attributes | ||
// that cannot be `include!()`ed via macro. And we cannot use the `#[path = "..."]` | ||
// trick either because you cannot yet `concat!(env!("OUT_DIR"), "/skel.rs")` inside | ||
// the path attribute either (see https://github.com/rust-lang/rust/pull/83366). | ||
// | ||
// However, there is hope! When the above feature stabilizes we can clean this | ||
// all up. | ||
create_dir_all("./src/bpf/.output").unwrap(); | ||
gen_bpf_sched("layered"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Get help on options with `rustfmt --help=config` | ||
# Please keep these in alphabetical order. | ||
edition = "2021" | ||
group_imports = "StdExternalCrate" | ||
imports_granularity = "Item" | ||
merge_derives = false | ||
use_field_init_shorthand = true | ||
version = "Two" |
Oops, something went wrong.