Merge pull request #518 from sched-ext/htejun/misc

scx_layered: Add `--run-example` and enable CI testing
This commit is contained in:
Tejun Heo 2024-08-20 21:42:45 -10:00 committed by GitHub
commit 092f5422d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 84 additions and 68 deletions

View File

@ -13,12 +13,18 @@ GUEST_TIMEOUT=60
# List of schedulers to test
#
# TODO:
# - scx_layered: temporarily excluded because it
# cannot run with a default configuration
# - scx_flatcg, scx_pair: excluded until cgroup support lands upstream
# - scx_mitosis: not ready yet
#
SCHEDULERS="scx_simple scx_central scx_nest scx_rusty scx_rustland scx_bpfland"
declare -A SCHEDS
SCHEDS["scx_simple"]=""
SCHEDS["scx_central"]=""
SCHEDS["scx_nest"]=""
SCHEDS["scx_rusty"]=""
SCHEDS["scx_rustland"]=""
SCHEDS["scx_bpfland"]=""
SCHEDS["scx_layered"]="--run-example"
if [ ! -x `which vng` ]; then
echo "vng not found, please install virtme-ng to enable testing"
@ -30,7 +36,8 @@ if [ $# -lt 1 ]; then
fi
kernel=$1
for sched in ${SCHEDULERS}; do
for sched in ${!SCHEDS[@]}; do
args=${SCHEDS[$sched]}
sched_path=$(find -type f -executable -name ${sched})
if [ ! -n "${sched_path}" ]; then
echo "${sched}: binary not found"
@ -42,7 +49,7 @@ for sched in ${SCHEDULERS}; do
rm -f /tmp/output
timeout --preserve-status ${GUEST_TIMEOUT} \
vng --force-9p -v -r ${kernel} -- \
"timeout --foreground --preserve-status ${TEST_TIMEOUT} ${sched_path}" \
"timeout --foreground --preserve-status ${TEST_TIMEOUT} ${sched_path} ${args}" \
2> >(tee /tmp/output) </dev/null
grep -v " Speculative Return Stack Overflow" /tmp/output | \
sed -n -e '/\bBUG:/q1' \

View File

@ -72,9 +72,70 @@ const NR_LSTATS: usize = bpf_intf::layer_stat_idx_NR_LSTATS as usize;
const NR_LAYER_MATCH_KINDS: usize = bpf_intf::layer_match_kind_NR_LAYER_MATCH_KINDS as usize;
const CORE_CACHE_LEVEL: u32 = 2;
#[rustfmt::skip]
lazy_static::lazy_static! {
static ref NR_POSSIBLE_CPUS: usize = libbpf_rs::num_possible_cpus().unwrap();
static ref USAGE_DECAY: f64 = 0.5f64.powf(1.0 / USAGE_HALF_LIFE_F64);
static ref EXAMPLE_CONFIG: LayerConfig =
LayerConfig {
specs: vec![
LayerSpec {
name: "batch".into(),
comment: Some("tasks under system.slice or tasks with nice value > 0".into()),
matches: vec![
vec![LayerMatch::CgroupPrefix("system.slice/".into())],
vec![LayerMatch::NiceAbove(0)],
],
kind: LayerKind::Confined {
cpus_range: Some((0, 16)),
util_range: (0.8, 0.9),
min_exec_us: 1000,
yield_ignore: 0.0,
preempt: false,
preempt_first: false,
exclusive: false,
perf: 1024,
nodes: vec![],
llcs: vec![],
},
},
LayerSpec {
name: "immediate".into(),
comment: Some("tasks under workload.slice with nice value < 0".into()),
matches: vec![vec![
LayerMatch::CgroupPrefix("workload.slice/".into()),
LayerMatch::NiceBelow(0),
]],
kind: LayerKind::Open {
min_exec_us: 100,
yield_ignore: 0.25,
preempt: true,
preempt_first: false,
exclusive: true,
perf: 1024,
nodes: vec![],
llcs: vec![],
},
},
LayerSpec {
name: "normal".into(),
comment: Some("the rest".into()),
matches: vec![vec![]],
kind: LayerKind::Grouped {
cpus_range: None,
util_range: (0.5, 0.6),
min_exec_us: 200,
yield_ignore: 0.0,
preempt: false,
preempt_first: false,
exclusive: false,
perf: 1024,
nodes: vec![],
llcs: vec![],
},
},
],
};
}
/// scx_layered: A highly configurable multi-layer sched_ext scheduler
@ -339,6 +400,10 @@ struct Opts {
#[clap(short = 'e', long)]
example: Option<String>,
/// Run with example layer specifications (useful for e.g. CI pipelines)
#[clap(long)]
run_example: bool,
/// Enable stats monitoring with the specified interval. If no layer
/// specs are specified, run in monitor mode.
#[clap(long)]
@ -1745,71 +1810,11 @@ impl<'a, 'b> Drop for Scheduler<'a, 'b> {
}
fn write_example_file(path: &str) -> Result<()> {
let example = LayerConfig {
specs: vec![
LayerSpec {
name: "batch".into(),
comment: Some("tasks under system.slice or tasks with nice value > 0".into()),
matches: vec![
vec![LayerMatch::CgroupPrefix("system.slice/".into())],
vec![LayerMatch::NiceAbove(0)],
],
kind: LayerKind::Confined {
cpus_range: Some((0, 16)),
util_range: (0.8, 0.9),
min_exec_us: 1000,
yield_ignore: 0.0,
preempt: false,
preempt_first: false,
exclusive: false,
perf: 1024,
nodes: vec![],
llcs: vec![],
},
},
LayerSpec {
name: "immediate".into(),
comment: Some("tasks under workload.slice with nice value < 0".into()),
matches: vec![vec![
LayerMatch::CgroupPrefix("workload.slice/".into()),
LayerMatch::NiceBelow(0),
]],
kind: LayerKind::Open {
min_exec_us: 100,
yield_ignore: 0.25,
preempt: true,
preempt_first: false,
exclusive: true,
perf: 1024,
nodes: vec![],
llcs: vec![],
},
},
LayerSpec {
name: "normal".into(),
comment: Some("the rest".into()),
matches: vec![vec![]],
kind: LayerKind::Grouped {
cpus_range: None,
util_range: (0.5, 0.6),
min_exec_us: 200,
yield_ignore: 0.0,
preempt: false,
preempt_first: false,
exclusive: false,
perf: 1024,
nodes: vec![],
llcs: vec![],
},
},
],
};
let mut f = fs::OpenOptions::new()
.create_new(true)
.write(true)
.open(path)?;
Ok(f.write_all(serde_json::to_string_pretty(&example)?.as_bytes())?)
Ok(f.write_all(serde_json::to_string_pretty(&*EXAMPLE_CONFIG)?.as_bytes())?)
}
fn verify_layer_specs(specs: &[LayerSpec]) -> Result<()> {
@ -1942,7 +1947,11 @@ fn main() -> Result<()> {
return Ok(());
}
let mut layer_config = LayerConfig { specs: vec![] };
let mut layer_config = match opts.run_example {
true => EXAMPLE_CONFIG.clone(),
false => LayerConfig { specs: vec![] },
};
for (idx, input) in opts.specs.iter().enumerate() {
layer_config.specs.append(
&mut LayerSpec::parse(input)

View File

@ -509,7 +509,7 @@ pub fn monitor(intv: Duration, shutdown: Arc<AtomicBool>) -> Result<()> {
Err(e) => match e.downcast_ref::<std::io::Error>() {
Some(ioe) => {
info!("Connection to stats_server failed ({})", &ioe);
sleep(Duration::from_secs(1));
sleep(Duration::from_secs(1));
break;
}
None => Err(e)?,