RTLA is an interface to the kernel osnoise and timerlat tracers, and as such, operates on all CPUs seen by the kernel, regardless of any applied user space CPU isolation. Currently, it uses libc's get_nprocs_conf() function to get the total number of valid (configured) CPUs on the system.
The number reported by the function may vary depending on both the libc implementation and the environment. This can cause discrepancies, including: - RTLA crashing because of out-of-bounds access and/or memory corruption, as a result of reading kernel events with cpu >= nr_cpus and using it to index an nr_cpus-length buffer. - nr_cpus mismatching the return value of libbpf_num_possible_cpus(), which is used in the per-CPU map size check, leading RTLA to fail to read BPF data. To address both issues, this patchset switches RTLA to unconditionally use the CPU count exposed through sysfs (/sys/devices/system/cpu/possible) - the same interface through which the tracers are accessed. As several places in RTLA assume the CPU count correlates with the maximum CPU (pre-existing limitation), the new mechanism also rejects possible CPU lists with holes or starting with non-zero CPU. As a safety measure, trace events are further validated and rejected if their cpu field is greater or equal to nr_cpus. nr_cpus is additionally validated for equality against osnoise's "all" cpu setting. This is done to catch environments where sysfs is virtualized and reports a different number of CPUs than the kernel. Note: As an alternative approach - reading only the osnoise cpu "all" setting and using it for nr_cpus - was considered. While it would make patch 3 unnecessary and make RTLA compatible with environments with virtualized sysfs, it would require separate handling of userspace and kernel CPU number, as nr_cpus is also used to guard -H/--housekeeping option argument. That does not appear to me to be worth it just to cover for a very rare corner case; if such use case appears in the future, RTLA can always be fixed. Tomas Glozar (5): rtla: Replace get_nprocs_conf() with sysfs possible cpus rtla: Discard trace entries with cpu >= nr_cpus rtla: Abort on nr_cpus mismatch with tracer rtla/tests: Add unit test for cpu_list_iterate() rtla/tests: Add unit test for get_max_cpu_from_list() tools/tracing/rtla/src/common.c | 29 +++- tools/tracing/rtla/src/common.h | 3 +- tools/tracing/rtla/src/osnoise.c | 70 +++++++++- tools/tracing/rtla/src/osnoise.h | 2 + tools/tracing/rtla/src/osnoise_hist.c | 1 + tools/tracing/rtla/src/osnoise_top.c | 1 + tools/tracing/rtla/src/timerlat_hist.c | 1 + tools/tracing/rtla/src/timerlat_top.c | 1 + tools/tracing/rtla/src/trace.c | 7 + tools/tracing/rtla/src/trace.h | 1 + tools/tracing/rtla/src/utils.c | 181 +++++++++++++++++++++---- tools/tracing/rtla/src/utils.h | 6 + tools/tracing/rtla/tests/unit/utils.c | 71 ++++++++++ 13 files changed, 342 insertions(+), 32 deletions(-) -- 2.55.0
