ktstr/scenario/
affinity.rs1use super::Ctx;
4use super::backdrop::Backdrop;
5use super::ops::{
6 CgroupDef, CpusetSpec, HoldSpec, Op, Step, execute_scenario, execute_scenario_with,
7};
8use crate::assert::{Assert, AssertResult};
9use crate::workload::AffinityIntent;
10use anyhow::Result;
11use std::collections::BTreeSet;
12use std::time::Duration;
13
14pub fn custom_cgroup_affinity_change(ctx: &Ctx) -> Result<AssertResult> {
20 let backdrop = Backdrop::new()
21 .push_cgroup(CgroupDef::named("cg_0"))
22 .push_cgroup(CgroupDef::named("cg_1"));
23 let mut steps = vec![Step::new(vec![], ctx.settled_hold(0.2))];
24
25 let pool = ctx.topo.all_cpuset();
30 let count = (pool.len() / 2).max(1);
31 let intent = AffinityIntent::RandomSubset { from: pool, count };
32
33 for _ in 0..4 {
34 steps.push(Step::new(
35 vec![
36 Op::set_affinity("cg_0", intent.clone()),
37 Op::set_affinity("cg_1", intent.clone()),
38 ],
39 HoldSpec::frac(0.2),
40 ));
41 }
42
43 execute_scenario(ctx, backdrop, steps)
44}
45
46pub fn custom_cgroup_multicpu_pin(ctx: &Ctx) -> Result<AssertResult> {
50 let all = ctx.topo.all_cpus();
51 let pin_cpus: BTreeSet<usize> = if all.len() >= 2 {
52 all[..2].iter().copied().collect()
53 } else {
54 all.iter().copied().collect()
55 };
56
57 let checks = Assert::default_checks().max_spread_pct(75.0);
61
62 let settle = ctx.settle.max(Duration::from_millis(500));
73 let backdrop = Backdrop::new()
74 .push_cgroup(CgroupDef::named("cg_0"))
75 .push_cgroup(CgroupDef::named("cg_1"));
76 let steps = vec![
77 Step::new(vec![], HoldSpec::fixed(settle)),
78 Step::new(
79 vec![
80 Op::set_affinity("cg_0", AffinityIntent::Exact(pin_cpus.clone())),
81 Op::set_affinity("cg_1", AffinityIntent::Exact(pin_cpus)),
82 ],
83 HoldSpec::fixed(ctx.duration),
84 ),
85 ];
86
87 execute_scenario_with(ctx, backdrop, steps, Some(&checks))
88}
89
90pub fn custom_cgroup_cpuset_multicpu_pin(ctx: &Ctx) -> Result<AssertResult> {
94 let usable = ctx.topo.usable_cpus();
95 let mid = usable.len() / 2;
96 let a: BTreeSet<usize> = usable[..mid].iter().copied().collect();
97 let b: BTreeSet<usize> = usable[mid..].iter().copied().collect();
98
99 let pin_a: BTreeSet<usize> = a.iter().copied().take(2.min(a.len())).collect();
100 let pin_b: BTreeSet<usize> = b.iter().copied().take(2.min(b.len())).collect();
101
102 let checks = Assert::default_checks().max_spread_pct(75.0);
105
106 let backdrop = Backdrop::new().extend_cgroups([
107 CgroupDef::named("cg_0").cpuset(CpusetSpec::disjoint(0, 2)),
108 CgroupDef::named("cg_1").cpuset(CpusetSpec::disjoint(1, 2)),
109 ]);
110 let steps = vec![
111 Step::new(vec![], HoldSpec::fixed(ctx.settle)),
112 Step::new(
113 vec![
114 Op::set_affinity("cg_0", AffinityIntent::Exact(pin_a)),
115 Op::set_affinity("cg_1", AffinityIntent::Exact(pin_b)),
116 ],
117 HoldSpec::fixed(ctx.duration),
118 ),
119 ];
120
121 execute_scenario_with(ctx, backdrop, steps, Some(&checks))
122}