基于 libbpf 与 CO-RE(Compile Once – Run Everywhere)的 Linux 内核可观测性工具合集,覆盖内存、I/O、调度、虚拟化、文件系统与进程生命周期等场景。
| 工具 | 目录 | 说明 |
|---|---|---|
| slabtop | slabtop/ |
按进程统计 slab 内存分配速率,类似 top 的实时视图 |
| mmap | mmap/ |
追踪进程的 mmap / munmap 调用 |
| mutex | mutex/ |
统计 futex 锁竞争延迟直方图,支持调用栈 |
| io | io/ |
追踪块设备 I/O 请求,支持按进程、磁盘、延迟过滤 |
| iofsstat | iofsstat/ |
按进程/设备统计文件系统 I/O |
| psrun | psrun/ |
追踪进程调度等待时间,长等待时可打印调用栈 |
| numawake | numawake/ |
观测 CFS 唤醒路径上的跨 NUMA 决策、落地偏离与 runqueue 延迟(面向 Linux 4.19) |
| kvmpoll | kvmpoll/ |
观测 KVM halt poll 唤醒延迟、fail 路径归因与 OWN 代价模型(面向 Linux 4.19) |
| pslife | pslife/ |
追踪进程的 fork / kill 事件 |
| funcstack | funcstack/ |
对内核函数挂 kprobe/kretprobe/tracepoint,打印调用栈 |
| exec_trace | exec_trace/ |
追踪执行指定命令的进程 |
| filewatch | filewatch/ |
监控文件创建、删除与打开操作 |
| kvmmon | kvmmon/ |
KVM vmexit→vmentry 延迟直方图,支持 Prometheus 导出 |
- Linux 内核 ≥ 5.14(部分工具依赖 BTF / CO-RE)
clang、llvm、gcc、makelibelf、zlib、zstd开发库- root 权限(加载 BPF 程序需要
CAP_BPF/CAP_PERFMON或 root)
# 将 libbpf 软链到项目根目录(指向本地 libbpf 仓库)
ln -s /path/to/libbpf libbpf
# bpftool 已预置在 tools/ 目录,也可自行替换为与内核版本匹配的版本项目使用 libbpf v1.5.0 构建,各子目录 Makefile 会在编译时自动切换 libbpf 版本。例外:numawake/、kvmpoll/ 面向 Linux 4.19,使用 libbpf v0.5.0 与 vmlinux/4.19/ 头文件。
进入对应子目录执行 make,产物输出到 bin/:
cd slabtop && make # 生成 ../bin/slabtop
cd io && make # 生成 ../bin/io
# 其他工具同理for d in slabtop mmap mutex io iofsstat psrun numawake kvmpoll pslife funcstack exec_trace filewatch kvmmon; do
(cd "$d" && make)
done追踪各 slab kmem cache 的分配速率,支持按 PID 过滤与多列排序。
./bin/slabtop # 每秒刷新,按 size 排序
./bin/slabtop -p 181 # 仅追踪 PID 181
./bin/slabtop -s count # 按 count 排序
./bin/slabtop -r 100 # 显示 100 行
./bin/slabtop 5 10 # 每 5 秒汇总,共 10 次追踪进程的内存映射与解除映射事件,可选将记录写入文件供后续分析。
./bin/mmap -p 1234 # 追踪指定 PID
./bin/mmap -c myapp # 按进程名过滤
./bin/mmap -r # 将事件记录到 rd_mmap_data / rd_munmap_data配合 tools/mmap_analysis 脚本可合并 mmap/munmap 记录并做内存分析。
以直方图形式汇总 futex 锁竞争延迟,支持按 PID、TID、锁地址过滤。
./bin/mutex # 持续汇总
./bin/mutex 1 10 # 每秒输出,共 10 次
./bin/mutex -mT 1 # 毫秒级直方图 + 时间戳
./bin/mutex -p 123 -l 0x8187bb8追踪块层 I/O 请求,显示操作类型、延迟、进程与调用栈。
./bin/io -p 123 # 追踪指定进程
./bin/io -d vda # 仅追踪 vda 磁盘
./bin/io -g 10 # 仅显示延迟 > 10ms 的请求按进程、设备维度统计文件系统 I/O。
./bin/iofsstat -i 5 -n 10 # 每 5 秒输出,共 10 次
./bin/iofsstat -d vda # 按设备过滤
./bin/iofsstat -p 1234 # 按 PID 过滤
./bin/iofsstat -c nginx # 按进程名过滤追踪进程在调度器中的等待时间,超过阈值时打印内核/用户态调用栈。
./bin/psrun -p 123 # 追踪单个 PID
./bin/psrun -p 123,200-205 # 支持 PID 列表与范围
./bin/psrun -s 100 # 等待超过 100ms 时 dump 调用栈观测 CFS 唤醒路径上的 NUMA 相关调度决策:select_task_rq_fair 选核、sched_wakeup / sched_migrate_task 入队、sched_switch 首次运行。统计决策层跨 NUMA wake、入队与落地 CPU 偏离,以及 runqueue 等待延迟直方图。详见 numawake/README.md 与 numawake/SEMANTICS.md。
目标内核:Linux 4.19(kprobe/kretprobe,非 CO-RE)。
cd numawake && make # 生成 ../bin/numawake、../bin/numawake_topo
sudo ./bin/numawake -i 3 # 每 3 秒打印累计统计
sudo ./bin/numawake -p 1234 # 仅追踪指定 PID
./bin/numawake_topo # 查看 NUMA 拓扑观测 KVM kvm_vcpu_wakeup tracepoint,统计 halt poll 成功/失败路径的延迟直方图,并量化 OWN(host CPU 权衡)代价模型。fail 路径上通过 sched_switch / sched_wakeup 拆分 event_wait(B1)与 runqueue(B2);kprobe kvm_vcpu_block 入口配合调度 tracepoint 得到 poll_actual,用于 mechanism_tax 计算。详见 kvmpoll/README.md。
目标内核:Linux 4.19(tracepoint + kprobe,非 CO-RE)。
cd kvmpoll && make # 生成 ../bin/kvmpoll
sudo ./bin/kvmpoll -p $(pidof qemu-system-x86_64) -i 10
sudo ./bin/kvmpoll -p $(pidof qemu-system-x86_64) -B 3200 -d 300 -q
sudo ./bin/kvmpoll -a --scan-interval 60| 选项 | 说明 |
|---|---|
-p PID |
监控指定 QEMU 线程组 |
-a |
监控全部 QEMU(周期性 rescan) |
-i SEC |
打印间隔(默认 10) |
-d SEC -q |
固定时长采集,输出 key=value |
-B NS |
OWN 公式中的 save_time 常数 B |
-H NS |
覆盖 module halt_poll_ns 作为 E |
追踪进程的 fork 与 kill 事件,记录时间戳与进程信息。
./bin/pslife # 追踪所有进程
./bin/pslife -p 123 # 仅追踪指定 PID 的子进程事件对内核函数或 tracepoint 附加探针,在触发时打印调用栈。
./bin/funcstack -k vfs_read # kprobe
./bin/funcstack -r vfs_read # kretprobe
./bin/funcstack -t syscalls:sys_enter_execve # tracepoint
./bin/funcstack -o sys_enter # raw tracepoint监控执行特定命令的进程。
./bin/exec_trace -c ls # 追踪执行 ls 的进程
./bin/exec_trace -v # 开启 libbpf 调试输出监控文件系统操作:创建、删除,以及可选的文件打开。
./bin/filewatch # 追踪 create / unlink
./bin/filewatch open # 同时追踪 vfs_open监控 KVM 虚拟机的 vmexit→vmentry 延迟,支持单 QEMU 进程或全量监控 + Prometheus 指标导出。
./bin/kvmmon -p <qemu-pid> # 监控单个 QEMU 进程
./bin/kvmmon -p <qemu-pid> -s 5000 # 延迟 ≥ 5µs 时打印内核栈
./bin/kvmmon -a -i 60 # 监控所有 QEMU,每 60s 输出直方图
./bin/kvmmon -a --prom /path/to/vm_latency.prom.
├── libbpf/ # libbpf 软链(需自行准备)
├── tools/
│ ├── bpftool # BPF 工具链
│ ├── libbpf.a.* # 预编译的 libbpf 静态库
│ └── mmap_analysis
├── vmlinux/ # 各内核版本的 BTF 头文件
│ ├── 4.19/
│ └── 5.14/
├── bin/ # 编译产物(make 后生成)
├── slabtop/ # 各工具源码目录
├── mmap/
├── numawake/ # 跨 NUMA wake 观测(4.19)
├── kvmpoll/ # KVM halt poll 观测(4.19)
├── ...
└── LICENSE
每个工具目录结构一致:
<tool>.bpf.c— 内核态 BPF 程序<tool>.c— 用户态加载器<tool>.skel.h— bpftool 生成的 skeleton 头文件(编译时自动生成)trace_helpers.c— 符号解析、调用栈等公共辅助函数Makefile
- 所有工具需要 root 权限运行。
- 内核需开启
CONFIG_DEBUG_INFO_BTF以支持 CO-RE;部分工具在内核 4.19 上可使用vmlinux/4.19/头文件。 - numawake、kvmpoll 专为 4.19 设计,不依赖内核 BTF;numawake 需
CONFIG_KALLSYMS_ALL以挂select_task_rq_fairkretprobe,kvmpoll 需 KVM tracepoint 与kvm_vcpu_blockkprobe 可用。 RLIMIT_MEMLOCK不足时工具会自动尝试提升限制;若仍失败请手动调整。filewatch等工具通过 kprobe 挂载,在高负载场景下可能有一定性能开销。