Skip to content

Commit 94142ae

Browse files
committed
feat: add cpu isolation for system, perf and benchmark
1 parent 9eb9fc8 commit 94142ae

5 files changed

Lines changed: 95 additions & 1 deletion

File tree

Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ debugid = "0.8.0"
5454
memmap2 = "0.9.5"
5555
nix = { version = "0.29.0", features = ["fs"] }
5656
futures = "0.3.31"
57+
num_cpus = "1.17.0"
5758

5859
[target.'cfg(target_os = "linux")'.dependencies]
5960
procfs = "0.17.0"
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use super::setup::run_with_sudo;
2+
3+
pub struct CpuIsolation {
4+
nproc: u32,
5+
}
6+
7+
impl CpuIsolation {
8+
pub fn new() -> Self {
9+
Self {
10+
nproc: num_cpus::get() as u32,
11+
}
12+
}
13+
14+
pub fn nproc(&self) -> u32 {
15+
self.nproc
16+
}
17+
18+
fn set_allowed_cpus(scope: &str, allowed_cpus: &[u32]) -> anyhow::Result<()> {
19+
let cpus = allowed_cpus
20+
.iter()
21+
.map(|cpu| cpu.to_string())
22+
.collect::<Vec<_>>()
23+
.join(",");
24+
25+
run_with_sudo(&[
26+
"systemctl",
27+
"set-property",
28+
scope,
29+
&format!("AllowedCPUs={}", cpus),
30+
])?;
31+
32+
Ok(())
33+
}
34+
35+
pub fn isolate_system(&self, allowed_cpus: &[u32]) -> anyhow::Result<()> {
36+
Self::set_allowed_cpus("system.slice", allowed_cpus)?;
37+
Self::set_allowed_cpus("init.scope", allowed_cpus)?;
38+
39+
Ok(())
40+
}
41+
42+
pub fn isolate_user(&self, allowed_cpus: &[u32]) -> anyhow::Result<()> {
43+
Self::set_allowed_cpus("user.slice", allowed_cpus)?;
44+
45+
Ok(())
46+
}
47+
48+
pub fn reset_isolation(nproc: u32) -> anyhow::Result<()> {
49+
let allowed_cpus = (0..nproc).collect::<Vec<_>>();
50+
Self::set_allowed_cpus("system.slice", &allowed_cpus)?;
51+
Self::set_allowed_cpus("user.slice", &allowed_cpus)?;
52+
Self::set_allowed_cpus("init.scope", &allowed_cpus)?;
53+
54+
Ok(())
55+
}
56+
}
57+
58+
impl Drop for CpuIsolation {
59+
fn drop(&mut self) {
60+
Self::reset_isolation(self.nproc)
61+
.unwrap_or_else(|e| eprintln!("Failed to reset CPU isolation: {}", e));
62+
}
63+
}

src/run/runner/helpers/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod env;
22
pub mod get_bench_command;
3+
pub mod isolation;
34
pub mod profile_folder;
45
pub mod run_command_with_log_pipe;
56
pub mod setup;

src/run/runner/wall_time/perf/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![cfg_attr(not(unix), allow(dead_code, unused_mut))]
22

33
use crate::prelude::*;
4+
use crate::run::runner::helpers::isolation::CpuIsolation;
45
use crate::run::runner::helpers::run_command_with_log_pipe::run_command_with_log_pipe_and_callback;
56
use crate::run::runner::helpers::setup::run_with_sudo;
67
use crate::run::runner::valgrind::helpers::ignored_objects_path::get_objects_path_to_ignore;
@@ -96,10 +97,21 @@ impl PerfRunner {
9697
};
9798
debug!("Using call graph mode: {}", cg_mode);
9899

100+
const PERF_CPU: u32 = 2;
101+
const BENCH_CPU: u32 = 3;
102+
const BENCH_CPUS: [u32; 2] = [PERF_CPU, BENCH_CPU];
103+
const HOST_CPUS: [u32; 2] = [0, 1];
104+
105+
let cpu_isolation = CpuIsolation::new();
106+
assert!(cpu_isolation.nproc() >= 4);
107+
cpu_isolation.isolate_system(&HOST_CPUS)?;
108+
cpu_isolation.isolate_user(&BENCH_CPUS)?;
109+
99110
cmd.args([
100111
"-c",
101112
&format!(
102-
"perf record --user-callchains --freq=999 --switch-output --control=fifo:{},{} --delay=-1 -g --call-graph={cg_mode} --output={} -- {bench_cmd}",
113+
"taskset -c {PERF_CPU} perf record --user-callchains --freq=999 --switch-output --control=fifo:{},{} --delay=-1 -g --call-graph={cg_mode} --output={} -- \
114+
taskset -c {BENCH_CPU} {bench_cmd}",
103115
perf_fifo.ctl_fifo_path.to_string_lossy(),
104116
perf_fifo.ack_fifo_path.to_string_lossy(),
105117
perf_file.path().to_string_lossy()

0 commit comments

Comments
 (0)