Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scx_utils: expose possible and online cpus from Topology #1132

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions rust/scx_utils/src/topology.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,16 @@ pub struct Topology {
pub all_llcs: BTreeMap<usize, Arc<Llc>>,
pub all_cores: BTreeMap<usize, Arc<Core>>,
pub all_cpus: BTreeMap<usize, Arc<Cpu>>,

pub possible_cpus: Cpumask,
}

impl Topology {
fn instantiate(span: Cpumask, mut nodes: BTreeMap<usize, Node>) -> Result<Self> {
fn instantiate(
span: Cpumask,
possible_cpus: Cpumask,
mut nodes: BTreeMap<usize, Node>,
) -> Result<Self> {
// Build skip indices prefixed with all_ for easy lookups. As Arc
// objects can only be modified while there's only one reference,
// skip indices must be built from bottom to top.
Expand Down Expand Up @@ -239,12 +245,15 @@ impl Topology {
all_llcs: topo_llcs,
all_cores: topo_cores,
all_cpus: topo_cpus,
possible_cpus,
})
}

/// Build a complete host Topology
pub fn new() -> Result<Topology> {
let span = cpus_online()?;
let possible = cpus_possible()?;

let mut topo_ctx = TopoCtx::new();
// If the kernel is compiled with CONFIG_NUMA, then build a topology
// from the NUMA hierarchy in sysfs. Otherwise, just make a single
Expand All @@ -255,14 +264,16 @@ impl Topology {
create_default_node(&span, &mut topo_ctx, false)?
};

Self::instantiate(span, nodes)
Self::instantiate(span, possible, nodes)
}

pub fn with_flattened_llc_node() -> Result<Topology> {
let span = cpus_online()?;
let possible = cpus_possible()?;

let mut topo_ctx = TopoCtx::new();
let nodes = create_default_node(&span, &mut topo_ctx, true)?;
Self::instantiate(span, nodes)
Self::instantiate(span, possible, nodes)
}

/// Get a vec of all GPUs on the hosts.
Expand Down Expand Up @@ -339,17 +350,24 @@ impl TopoCtx {
}

fn cpus_online() -> Result<Cpumask> {
let path = "/sys/devices/system/cpu/online";
let online = std::fs::read_to_string(&path)?;
let online_groups: Vec<&str> = online.split(',').collect();
parse_cpus("/sys/devices/system/cpu/online")
}

fn cpus_possible() -> Result<Cpumask> {
parse_cpus("/sys/devices/system/cpu/possible")
}

fn parse_cpus(path: &str) -> Result<Cpumask> {
let cpus = std::fs::read_to_string(&path)?;
let cpus: Vec<&str> = cpus.split(',').collect();
let mut mask = Cpumask::new();
for group in online_groups.iter() {
for group in cpus.iter() {
let (min, max) = match sscanf!(group.trim(), "{usize}-{usize}") {
Ok((x, y)) => (x, y),
Err(_) => match sscanf!(group.trim(), "{usize}") {
Ok(x) => (x, x),
Err(_) => {
bail!("Failed to parse online cpus {}", group.trim());
bail!("Failed to parse cpus from {}: {}", path, group.trim());
}
},
};
Expand Down