diff --git a/CLAUDE.md b/CLAUDE.md index e734742..c40bbf5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,6 +20,12 @@ Collects system performance metrics using Linux sysstat utilities (mpstat, sar, - `--subtools ` — Comma-separated subtools to run (default: `mpstat,sar,iostat,pidstat`) - `--interval ` — Collection interval (default: `3`) +## mpstat CPU breakout dimensions +Beyond `num` (CPU number), mpstat metrics carry these CDM breakout dimensions, all derived from sysfs CPU topology data collected by `sysstat-start` and resolved via toolbox's `system_cpu_topology.build_cpu_topology()`/`get_cpu_topology()`/`get_cpu_node()`/`get_cpu_cache_domains()`: +- `cpu` — string alias for `num`, matching the naming already used by `tool-procstat`/`tool-kernel` +- `node` — NUMA node, when determinable. Collected into a `cpu-numa-nodes.txt` manifest by `sysstat-start` rather than copied directly from sysfs: a CPU's `nodeN` entry is a symlink, and sysfs symlinks report a zero apparent size, which breaks `cpio`'s `readlink()` call +- `shared-lN-domain` (e.g. `shared-l1-domain`, `shared-l3-domain`) — one per cache level present on the host, valued as the formatted CPU range sharing that cache instance (e.g. `"0-15"`). Dynamic per-platform on the collection side; registered in CDM's schema as explicit `shared-l1-domain` through `shared-l4-domain` fields rather than a wildcard match + ## Conventions - Primary branch is `master` - Runs as a profiler tool on master/worker/profiler roles, blocked on client/server diff --git a/sysstat-post-process.py b/sysstat-post-process.py index 18c5804..eba0bc9 100755 --- a/sysstat-post-process.py +++ b/sysstat-post-process.py @@ -16,7 +16,12 @@ from toolbox.cdm_metrics import CDMMetrics from toolbox.fileio import open_read_text_file -from toolbox.system_cpu_topology import build_cpu_topology, get_cpu_topology +from toolbox.system_cpu_topology import ( + build_cpu_topology, + get_cpu_topology, + get_cpu_node, + get_cpu_cache_domains, +) def build_netdev_types(): @@ -364,10 +369,20 @@ def process_mpstat(fork_idx, num_forks, log_file, cpu_topo): if cpu_num % num_forks != fork_idx: continue package, die, core, thread = get_cpu_topology(cpu_num, cpu_topo) + node = get_cpu_node(cpu_num, cpu_topo) + cache_domains = get_cpu_cache_domains(cpu_num, cpu_topo) for cpu_type in cpu_entry: if cpu_type == "cpu": continue - names = {"package": package, "die": die, "core": core, "thread": thread, "num": cpu_num, "type": cpu_type} + # "cpu" is a string alias for "num" (kept for backwards + # compatibility) -- stored as a string to match the + # "keyword" mapping type already used by every other tool + # that reports a "cpu" breakout (procstat, kernel). + names = {"package": package, "die": die, "core": core, "thread": thread, "num": cpu_num, "cpu": str(cpu_num), "type": cpu_type} + if node is not None: + names["node"] = str(node) + for level, domain in cache_domains.items(): + names[f"shared-l{level}-domain"] = domain if cpu_type in ("idle", "iowait", "steal"): desc["type"] = "NonBusy-CPU" else: diff --git a/sysstat-start b/sysstat-start index 48fbd2d..a5648a4 100755 --- a/sysstat-start +++ b/sysstat-start @@ -42,7 +42,21 @@ done # To be used by mpstat for post-processing if [ -e /sys/devices/system/cpu/ ]; then - find /sys/devices/system/cpu/ | grep topology | cpio -pdumv --quiet . 2>/dev/null + find /sys/devices/system/cpu/ | grep -E 'topology|cache/index[0-9]+/(level|shared_cpu_list)$' | cpio -pdumv --quiet . 2>/dev/null + + # NUMA node per CPU: sysfs exposes this as a nodeN symlink directly + # under each cpuN directory. That symlink reports a zero apparent + # size, which breaks cpio's readlink() call ("Cannot readlink: + # Invalid argument"), so resolve it ourselves into a manifest file + # instead -- same approach as netdev-types.txt below. + for cpu_dir in /sys/devices/system/cpu/cpu[0-9]*; do + for node_path in ${cpu_dir}/node[0-9]*; do + if [ -e "${node_path}" ]; then + echo "$(basename ${cpu_dir}) $(basename ${node_path})" >>cpu-numa-nodes.txt + break + fi + done + done else echo "WARNING: could not find /sys/devices/system/cpu/" fi