scx_rusty: Simplify Stats structs and take id out of the structs

to prepare for scx_stats conversion. While at it, make some cosmetic
changes.
This commit is contained in:
Tejun Heo 2024-08-21 22:54:06 -10:00
parent 4834dec684
commit b4564520e5
3 changed files with 62 additions and 70 deletions

View File

@ -153,6 +153,7 @@ use scx_utils::ravg::ravg_read;
use scx_utils::LoadAggregator;
use scx_utils::LoadLedger;
use sorted_vec::SortedVec;
use std::collections::BTreeMap;
use std::collections::VecDeque;
const RAVG_FRAC_BITS: u32 = bpf_intf::ravg_consts_RAVG_FRAC_BITS;
@ -445,24 +446,24 @@ impl NumaNode {
self.load.add_load(delta);
}
fn node_stats(&self) -> NodeStats {
let mut n_stat = NodeStats {
id: self.id,
load: self.load.clone(),
domains: Vec::new(),
fn stats(&self) -> NodeStats {
let mut stats = NodeStats {
load: self.load.load_sum(),
imbal: self.load.imbal(),
delta: self.load.delta(),
domains: BTreeMap::new(),
};
for dom in self.domains.iter() {
n_stat.domains.push(DomainStats {
id: dom.id,
load: dom.load.clone(),
});
stats.domains.insert(
dom.id,
DomainStats {
load: dom.load.load_sum(),
imbal: dom.load.imbal(),
delta: dom.load.delta(),
},
);
}
n_stat
.domains
.sort_by(|x, y| x.id.partial_cmp(&y.id).unwrap());
n_stat
stats
}
}
@ -529,15 +530,12 @@ impl<'a, 'b> LoadBalancer<'a, 'b> {
Ok(())
}
pub fn get_stats(&self) -> Vec<NodeStats> {
let mut numa_stats = Vec::with_capacity(self.dom_group.nr_nodes());
pub fn get_stats(&self) -> BTreeMap<usize, NodeStats> {
let mut stats = BTreeMap::new();
for node in self.nodes.iter() {
numa_stats.push(node.node_stats());
stats.insert(node.id, node.stats());
}
numa_stats.sort_by(|x, y| x.id.partial_cmp(&y.id).unwrap());
numa_stats
stats
}
fn create_domain_hierarchy(&mut self) -> Result<()> {

View File

@ -18,6 +18,7 @@ use load_balance::LoadBalancer;
mod stats;
use stats::NodeStats;
use std::collections::BTreeMap;
use std::mem::MaybeUninit;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
@ -309,7 +310,7 @@ impl<'a> Scheduler<'a> {
let node_cpumask_slice = &mut skel.maps.rodata_data.numa_cpumasks[numa];
let (left, _) = node_cpumask_slice.split_at_mut(raw_numa_slice.len());
left.clone_from_slice(raw_numa_slice);
info!("NUMA[{:02}] mask= {}", numa, numa_mask);
info!("NODE[{:02}] mask= {}", numa, numa_mask);
for dom in node_domains.iter() {
let raw_dom_slice = dom.mask_slice();
@ -319,7 +320,7 @@ impl<'a> Scheduler<'a> {
skel.maps.rodata_data.dom_numa_id_map[dom.id()] =
numa.try_into().expect("NUMA ID could not fit into 32 bits");
info!(" DOM[{:02}] mask= {}", dom.id(), dom.mask());
info!(" DOM[{:02}] mask= {}", dom.id(), dom.mask());
}
}
@ -458,7 +459,7 @@ impl<'a> Scheduler<'a> {
bpf_stats: &[u64],
cpu_busy: f64,
processing_dur: Duration,
node_stats: &[NodeStats],
node_stats: &BTreeMap<usize, NodeStats>,
) {
let stat = |idx| bpf_stats[idx as usize];
let total = stat(bpf_intf::stat_idx_RUSTY_STAT_WAKE_SYNC)
@ -473,13 +474,11 @@ impl<'a> Scheduler<'a> {
+ stat(bpf_intf::stat_idx_RUSTY_STAT_GREEDY_LOCAL)
+ stat(bpf_intf::stat_idx_RUSTY_STAT_GREEDY_XNUMA);
let numa_load_avg = node_stats[0].load.load_avg();
let dom_load_avg = node_stats[0].domains[0].load.load_avg();
info!(
"cpu={:7.2} bal={} numa_load_avg={:8.2} dom_load_avg={:8.2} task_err={} lb_data_err={} proc={:?}ms",
"cpu={:7.2} bal={} load={:8.2} task_err={} lb_data_err={} proc={:?}ms",
cpu_busy * 100.0,
bpf_stats[bpf_intf::stat_idx_RUSTY_STAT_LOAD_BALANCE as usize],
numa_load_avg, dom_load_avg,
node_stats.iter().map(|(_k, v)| v.load).sum::<f64>(),
bpf_stats[bpf_intf::stat_idx_RUSTY_STAT_TASK_GET_ERR as usize],
self.nr_lb_data_errors,
processing_dur.as_millis(),
@ -530,10 +529,10 @@ impl<'a> Scheduler<'a> {
info!("direct_greedy_cpumask={}", self.tuner.direct_greedy_mask);
info!(" kick_greedy_cpumask={}", self.tuner.kick_greedy_mask);
for node in node_stats.iter() {
info!("{}", node);
for dom in node.domains.iter() {
info!("{}", dom);
for (nid, node) in node_stats.iter() {
info!("{}", node.format(*nid));
for (did, dom) in node.domains.iter() {
info!("{}", dom.format(*did));
}
}
}

View File

@ -1,51 +1,46 @@
use crate::load_balance::LoadEntity;
use std::fmt;
use std::collections::BTreeMap;
fn fmt_balance_stat(
f: &mut fmt::Formatter<'_>,
load: &LoadEntity,
preamble: String,
) -> fmt::Result {
let imbal = load.imbal();
let load_sum = load.load_sum();
let load_delta = load.delta();
let get_fmt = |num: f64| {
if num >= 0.0f64 {
format!("{:+4.2}", num)
} else {
format!("{:4.2}", num)
}
};
write!(
f,
"{} load={:4.2} imbal={} load_delta={}",
preamble,
load_sum,
get_fmt(imbal),
get_fmt(load_delta)
)
fn signed(x: f64) -> String {
if x >= 0.0f64 {
format!("{:+7.2}", x)
} else {
format!("{:7.2}", x)
}
}
pub struct DomainStats {
pub id: usize,
pub load: LoadEntity,
pub load: f64,
pub imbal: f64,
pub delta: f64,
}
impl fmt::Display for DomainStats {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_balance_stat(f, &self.load, format!(" DOMAIN[{:02}]", self.id))
impl DomainStats {
pub fn format(&self, id: usize) -> String {
format!(
" DOM[{:02}] load={:6.2} imbal={} delta={}",
id,
self.load,
signed(self.imbal),
signed(self.delta)
)
}
}
pub struct NodeStats {
pub id: usize,
pub load: LoadEntity,
pub domains: Vec<DomainStats>,
pub load: f64,
pub imbal: f64,
pub delta: f64,
pub domains: BTreeMap<usize, DomainStats>,
}
impl fmt::Display for NodeStats {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_balance_stat(f, &self.load, format!("NODE[{:02}]", self.id))
impl NodeStats {
pub fn format(&self, id: usize) -> String {
format!(
" NODE[{:02}] load={:6.2} imbal={} delta={}",
id,
self.load,
signed(self.imbal),
signed(self.delta)
)
}
}