mirror of
https://github.com/sched-ext/scx.git
synced 2024-11-25 04:00:24 +00:00
Merge pull request #518 from sched-ext/htejun/misc
scx_layered: Add `--run-example` and enable CI testing
This commit is contained in:
commit
092f5422d6
@ -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' \
|
||||
|
@ -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)
|
||||
|
@ -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)?,
|
||||
|
Loading…
Reference in New Issue
Block a user