mirror of
https://github.com/JakeHillion/scx.git
synced 2024-11-29 04:40:22 +00:00
scx_layered: Add stats for XNUMA/XLLC migrations
Add stats for XNUMA/XLLC migrations. An example of the output is shown: ``` hodgesd : util/frac= 5.4/ 0.1 load/frac= 301.0/ 0.3 tasks= 476 tot= 3168 local=97.82 wake/exp/reenq= 2.18/ 0.00/ 0.00 keep/max/busy= 0.03/ 0.00/ 0.03 kick= 0.00 yield/ign= 0.09/ 0 open_idle= 0.00 mig= 6.82 xnuma_mig= 6.82 xllc_mig= 4.86 affn_viol= 0.00 preempt/first/idle/fail= 0.00/ 0.00/ 0.00/ 0.00 min_exec= 0.00/ 0.00ms cpus= 2 [ 2, 4] 00000000 00000010 00001000 normal : util/frac= 28.7/ 0.7 load/frac= 101704.7/ 95.8 tasks= 2450 tot= 4660 local=99.06 wake/exp/reenq= 0.88/ 0.06/ 0.00 keep/max/busy= 1.03/ 0.00/ 0.00 kick= 0.06 yield/ign= 0.04/ 400 open_idle=15.73 mig=23.45 xnuma_mig=23.45 xllc_mig= 3.07 affn_viol= 0.00 preempt/first/idle/fail= 0.00/ 0.00/ 0.00/ 0.88 min_exec= 0.00/ 0.00ms cpus= 2 [ 2, 2] 00000001 00000100 00000000 excl_coll=12.55 excl_preempt= 0.00 random : util/frac= 0.0/ 0.0 load/frac= 0.0/ 0.0 tasks= 0 tot= 0 local= 0.00 wake/exp/reenq= 0.00/ 0.00/ 0.00 keep/max/busy= 0.00/ 0.00/ 0.00 kick= 0.00 yield/ign= 0.00/ 0 open_idle= 0.00 mig= 0.00 xnuma_mig= 0.00 xllc_mig= 0.00 affn_viol= 0.00 preempt/first/idle/fail= 0.00/ 0.00/ 0.00/ 0.00 min_exec= 0.00/ 0.00ms cpus= 0 [ 0, 0] 00000000 00000000 00000000 excl_coll= 0.00 excl_preempt= 0.00 stress-ng: util/frac= 4189.1/ 99.2 load/frac= 4200.0/ 4.0 tasks= 43 tot= 62 local= 0.00 wake/exp/reenq= 0.00/100.0/ 0.00 keep/max/busy=2433.9/177.4/ 0.00 kick=100.0 yield/ign= 3.23/ 0 open_idle= 0.00 mig=54.84 xnuma_mig=54.84 xllc_mig=35.48 affn_viol= 0.00 preempt/first/idle/fail= 0.00/ 0.00/ 0.00/ 0.00 min_exec= 0.00/ 0.00ms cpus= 4 [ 4, 4] 00000300 00030000 00000000 excl_coll= 0.00 excl_preempt= 0.00 ``` Signed-off-by: Daniel Hodges <hodges.daniel.scott@gmail.com>
This commit is contained in:
parent
85863d0e1c
commit
43ec8bfe82
@ -71,6 +71,8 @@ enum layer_stat_idx {
|
||||
LSTAT_YIELD,
|
||||
LSTAT_YIELD_IGNORE,
|
||||
LSTAT_MIGRATION,
|
||||
LSTAT_XNUMA_MIGRATION,
|
||||
LSTAT_XLLC_MIGRATION,
|
||||
NR_LSTATS,
|
||||
};
|
||||
|
||||
@ -86,6 +88,8 @@ struct cpu_ctx {
|
||||
u64 lstats[MAX_LAYERS][NR_LSTATS];
|
||||
u64 ran_current_for;
|
||||
u32 layer_idx;
|
||||
u32 node_idx;
|
||||
u32 cache_idx;
|
||||
};
|
||||
|
||||
struct cache_ctx {
|
||||
|
@ -136,9 +136,6 @@ static u32 cpu_to_llc_id(s32 cpu_id)
|
||||
return *llc_ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Numa node context
|
||||
*/
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__type(key, u32);
|
||||
@ -147,6 +144,30 @@ struct {
|
||||
__uint(map_flags, 0);
|
||||
} node_data SEC(".maps");
|
||||
|
||||
static struct node_ctx *lookup_node_ctx(u32 node)
|
||||
{
|
||||
struct node_ctx *nodec;
|
||||
|
||||
nodec = bpf_map_lookup_elem(&node_data, &node);
|
||||
return nodec;
|
||||
}
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__type(key, u32);
|
||||
__type(value, struct cache_ctx);
|
||||
__uint(max_entries, MAX_DOMS);
|
||||
__uint(map_flags, 0);
|
||||
} cache_data SEC(".maps");
|
||||
|
||||
static struct cache_ctx *lookup_cache_ctx(u32 cache_idx)
|
||||
{
|
||||
struct cache_ctx *cachec;
|
||||
|
||||
cachec = bpf_map_lookup_elem(&cache_data, &cache_idx);
|
||||
return cachec;
|
||||
}
|
||||
|
||||
static void gstat_inc(enum global_stat_idx idx, struct cpu_ctx *cctx)
|
||||
{
|
||||
if (idx < 0 || idx >= NR_GSTATS) {
|
||||
@ -1166,6 +1187,7 @@ static s32 create_node(u32 node_id)
|
||||
u32 cpu;
|
||||
struct bpf_cpumask *cpumask;
|
||||
struct node_ctx *nodec;
|
||||
struct cpu_ctx *cctx;
|
||||
s32 ret;
|
||||
|
||||
nodec = bpf_map_lookup_elem(&node_data, &node_id);
|
||||
@ -1198,8 +1220,58 @@ static s32 create_node(u32 node_id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (*nmask & (1LLU << (cpu % 64)))
|
||||
if (*nmask & (1LLU << (cpu % 64))) {
|
||||
bpf_cpumask_set_cpu(cpu, cpumask);
|
||||
if (!(cctx = lookup_cpu_ctx(-1))) {
|
||||
scx_bpf_error("cpu ctx error");
|
||||
ret = -ENOENT;
|
||||
break;
|
||||
}
|
||||
cctx->node_idx = node_id;
|
||||
}
|
||||
}
|
||||
|
||||
bpf_rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static s32 create_cache(u32 cache_id)
|
||||
{
|
||||
u32 cpu, llc_id;
|
||||
struct bpf_cpumask *cpumask;
|
||||
struct cache_ctx *cachec;
|
||||
struct cpu_ctx *cctx;
|
||||
s32 ret;
|
||||
|
||||
cachec = bpf_map_lookup_elem(&cache_data, &cache_id);
|
||||
if (!cachec) {
|
||||
scx_bpf_error("No cache%u", cache_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
cachec->id = cache_id;
|
||||
|
||||
ret = create_save_cpumask(&cachec->cpumask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bpf_rcu_read_lock();
|
||||
cpumask = cachec->cpumask;
|
||||
if (!cpumask) {
|
||||
bpf_rcu_read_unlock();
|
||||
scx_bpf_error("Failed to lookup node cpumask");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
bpf_for(cpu, 0, MAX_CPUS) {
|
||||
llc_id = cpu_to_llc_id(cpu);
|
||||
if (llc_id != cache_id)
|
||||
continue;
|
||||
|
||||
bpf_cpumask_set_cpu(cpu, cpumask);
|
||||
if (!(cctx = lookup_cpu_ctx(-1))) {
|
||||
scx_bpf_error("cpu ctx error"); ret = -ENOENT; break;
|
||||
}
|
||||
cctx->cache_idx = cache_id;
|
||||
}
|
||||
|
||||
bpf_rcu_read_unlock();
|
||||
@ -1225,14 +1297,27 @@ void BPF_STRUCT_OPS(layered_running, struct task_struct *p)
|
||||
struct cpu_ctx *cctx;
|
||||
struct task_ctx *tctx;
|
||||
struct layer *layer;
|
||||
struct node_ctx *nodec;
|
||||
struct cache_ctx *cachec;
|
||||
s32 task_cpu = scx_bpf_task_cpu(p);
|
||||
|
||||
if (!(cctx = lookup_cpu_ctx(-1)) || !(tctx = lookup_task_ctx(p)) ||
|
||||
!(layer = lookup_layer(tctx->layer)))
|
||||
return;
|
||||
|
||||
if (tctx->last_cpu >= 0 && tctx->last_cpu != task_cpu)
|
||||
if (tctx->last_cpu >= 0 && tctx->last_cpu != task_cpu) {
|
||||
lstat_inc(LSTAT_MIGRATION, layer, cctx);
|
||||
if (!(nodec = lookup_node_ctx(cctx->node_idx)))
|
||||
return;
|
||||
if (nodec->cpumask &&
|
||||
!bpf_cpumask_test_cpu(tctx->last_cpu, nodec->cpumask))
|
||||
lstat_inc(LSTAT_XNUMA_MIGRATION, layer, cctx);
|
||||
if (!(cachec = lookup_cache_ctx(cctx->cache_idx)))
|
||||
return;
|
||||
if (cachec->cpumask &&
|
||||
!bpf_cpumask_test_cpu(tctx->last_cpu, cachec->cpumask))
|
||||
lstat_inc(LSTAT_XLLC_MIGRATION, layer, cctx);
|
||||
}
|
||||
tctx->last_cpu = task_cpu;
|
||||
|
||||
if (vtime_before(layer->vtime_now, p->scx.dsq_vtime))
|
||||
@ -1560,6 +1645,11 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(layered_init)
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
bpf_for(i, 0, nr_llcs) {
|
||||
ret = create_cache(i);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
dbg("CFG: Dumping configuration, nr_online_cpus=%d smt_enabled=%d",
|
||||
nr_online_cpus, smt_enabled);
|
||||
|
@ -100,6 +100,10 @@ pub struct LayerStats {
|
||||
pub yield_ignore: u64,
|
||||
#[stat(desc = "% migrated across CPUs")]
|
||||
pub migration: f64,
|
||||
#[stat(desc = "% migrated across NUMA nodes")]
|
||||
pub xnuma_migration: f64,
|
||||
#[stat(desc = "% migrated across LLCs")]
|
||||
pub xllc_migration: f64,
|
||||
#[stat(desc = "mask of allocated CPUs", _om_skip)]
|
||||
pub cpus: Vec<u32>,
|
||||
#[stat(desc = "# of CPUs assigned")]
|
||||
@ -189,6 +193,8 @@ impl LayerStats {
|
||||
yielded: lstat_pct(bpf_intf::layer_stat_idx_LSTAT_YIELD),
|
||||
yield_ignore: lstat(bpf_intf::layer_stat_idx_LSTAT_YIELD_IGNORE) as u64,
|
||||
migration: lstat_pct(bpf_intf::layer_stat_idx_LSTAT_MIGRATION),
|
||||
xnuma_migration: lstat_pct(bpf_intf::layer_stat_idx_LSTAT_XNUMA_MIGRATION),
|
||||
xllc_migration: lstat_pct(bpf_intf::layer_stat_idx_LSTAT_XLLC_MIGRATION),
|
||||
cpus: Self::bitvec_to_u32s(&layer.cpus),
|
||||
cur_nr_cpus: layer.cpus.count_ones() as u32,
|
||||
min_nr_cpus: nr_cpus_range.0 as u32,
|
||||
@ -236,10 +242,12 @@ impl LayerStats {
|
||||
|
||||
writeln!(
|
||||
w,
|
||||
" {:<width$} open_idle={} mig={} affn_viol={}",
|
||||
" {:<width$} open_idle={} mig={} xnuma_mig={} xllc_mig={} affn_viol={}",
|
||||
"",
|
||||
fmt_pct(self.open_idle),
|
||||
fmt_pct(self.migration),
|
||||
fmt_pct(self.xnuma_migration),
|
||||
fmt_pct(self.xllc_migration),
|
||||
fmt_pct(self.affn_viol),
|
||||
width = header_width,
|
||||
)?;
|
||||
|
Loading…
Reference in New Issue
Block a user