<p>可直接用 perf record 捕获内核函数调用栈并用 perf report 查看耗时分布;需开启 CONFIG_DEBUG_INFO=y 和 CONFIG_KALLSYMS=y,确保 /proc/kallsyms 可读,运行 sudo perf record -e cycles:u,k -g --call-graph dwarf -a -- sleep 30,再用 sudo perf report -F comm,dso,symbol,period,overhead --no-children 分析。</p>

可以直接用 perf record 捕获内核函数调用栈,再通过 perf report 查看各内核函数的采样占比——这反映的是它们在 CPU 上的实际执行耗时分布。关键在于让 perf 能正确解析内核符号,并采集到完整的调用上下文。
确保内核符号可用
perf 要识别 do_syscall_64、__schedule、tcp_v4_do_rcv 这类函数名,必须满足:
- 内核编译时开启
CONFIG_DEBUG_INFO=y和CONFIG_KALLSYMS=y - 目标系统上存在可读的
/proc/kallsyms(通常 root 可读;若权限受限,需临时提升或改配置) - 检查是否能正常读取:
sudo cat /proc/kallsyms | head -5,应看到类似ffffffff81000000 T _stext的符号行
录制含内核调用栈的样本
运行以下命令,持续采集 30 秒系统级行为(包括所有进程触发的内核态执行):
sudo perf record -e cycles:u,k -g --call-graph dwarf -a -- sleep 30
-
-e cycles:u,k:同时采样用户态(u)和内核态(k)的 CPU 周期事件,避免只看到用户代码而漏掉内核开销 -
-g --call-graph dwarf:启用 DWARF 格式调用图,对内核函数调用链还原更准确(比默认的 frame pointer 更可靠) -
-a:系统范围采样,覆盖所有 CPU 和所有进程引发的内核路径
分析内核函数热点
执行:sudo perf report -F comm,dso,symbol,period,overhead --no-children
- 重点关注
dso列为[kernel.kallsyms]的行,这些就是内核函数 -
overhead是该函数被采样到的百分比,近似对应其 CPU 占用时间比例 - 按方向键展开某一行,可看到它被哪些用户函数或中断上下文调用(例如
sys_read → vfs_read → __vfs_read → do_iter_readv)
聚焦特定内核路径(可选)
若已知问题与某类操作相关(如网络、调度、块设备),可换用更精准的事件:
- 查调度延迟:
sudo perf record -e sched:sched_stat_sleep,sched:sched_switch -a -- sleep 20 - 查软中断处理:
sudo perf record -e irq:softirq_entry,irq:softirq_exit -a -- sleep 20 - 查系统调用开销:
sudo perf record -e syscalls:sys_enter_* -a -- sleep 10(配合perf script过滤)
不需要修改内核、不依赖额外探针,只要符号就绪、权限到位、调用图开启,perf 就能如实告诉你哪些内核函数正在吃掉 CPU 时间。


















