From f428e5f509625af405300e93f51f417e2358f678 Mon Sep 17 00:00:00 2001 From: Ism Hong Date: Mon, 23 Jun 2025 18:05:43 +0800 Subject: [PATCH] tools/runqlat: Dynamically size pid/pidns histogram map When using `runqlat` with the `--pids` or `--pidnss` flags, the BPF histogram for tracking per-process or per-namespace latency is created with a fixed default size of 64 entries. On systems with a large number of processes or active namespaces, this small, fixed size can be easily exhausted. This leads to silent data loss for any PIDs or PID namespaces beyond the 64th entry, making the tool's output incomplete and misleading. To fix this, read the maximum possible PID and PID Namespace values from `/proc/sys/kernel/pid_max` and `/proc/sys/user/max_user_namespaces` respectively. Pass these values to the BPF program to dynamically size the histogram map, ensuring it is large enough to avoid dropping data. This approach is similar to the one implemented for cpudist as discussed in PR #2568. Link: https://github.com/iovisor/bcc/pull/2568 Signed-off-by: Ism Hong --- tools/runqlat.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/runqlat.py b/tools/runqlat.py index 49a111389c26..d0d7a3357774 100755 --- a/tools/runqlat.py +++ b/tools/runqlat.py @@ -268,14 +268,14 @@ pid = "pid" section = "tid" bpf_text = bpf_text.replace('STORAGE', - 'BPF_HISTOGRAM(dist, pid_key_t);') + 'BPF_HISTOGRAM(dist, pid_key_t, MAX_PID);') bpf_text = bpf_text.replace('STORE', 'pid_key_t key = {}; key.id = ' + pid + '; key.slot = bpf_log2l(delta); ' + 'dist.increment(key);') elif args.pidnss: section = "pidns" bpf_text = bpf_text.replace('STORAGE', - 'BPF_HISTOGRAM(dist, pidns_key_t);') + 'BPF_HISTOGRAM(dist, pidns_key_t, MAX_PIDNS);') bpf_text = bpf_text.replace('STORE', 'pidns_key_t key = ' + '{.id = pid_namespace(prev), ' + '.slot = bpf_log2l(delta)}; dist.atomic_increment(key);') @@ -289,8 +289,11 @@ if args.ebpf: exit() +max_pid = int(open("/proc/sys/kernel/pid_max").read()) +max_pidns = int(open("/proc/sys/user/max_pid_namespaces").read()) # load BPF program -b = BPF(text=bpf_text) +b = BPF(text=bpf_text, cflags=["-DMAX_PID=%d" % max_pid, + "-DMAX_PIDNS=%d" % max_pidns]) if not is_support_raw_tp: b.attach_kprobe(event="ttwu_do_wakeup", fn_name="trace_ttwu_do_wakeup") b.attach_kprobe(event="wake_up_new_task", fn_name="trace_wake_up_new_task")