perf top 是实时查看 cpu 热点的命令,能直接显示用户态和内核态函数,默认采样 cpu-cycles 事件;需满足 config_kallsyms=y、/proc/kallsyms 可读等条件才能解析内核函数名。

perf top 是一个实时查看 CPU 热点的命令,它能直接显示当前系统中正在消耗 CPU 时间的函数(包括用户态和内核态),无需提前录制数据,适合快速定位“谁在烧 CPU”。
它默认采样的是 cpu-cycles 事件,但关键在于:只要内核符号表可用,就能看到内核函数名,比如 do_syscall_64、__x64_sys_read、ext4_file_read_iter、tcp_transmit_skb 等。
一、前提条件:确保能看到内核符号
perf top 要解析出内核函数名,必须满足:
- 内核开启了
CONFIG_KALLSYMS=y(主流发行版默认开启) -
/proc/kallsyms可读(普通用户需sudo;或临时开放:echo 0 | sudo tee /proc/sys/kernel/kptr_restrict) - 安装了对应内核版本的
linux-image-extra或kernel-debuginfo包(仅调试深度场景需要,基础函数名通常已有)
⚠️ 如果你看到一堆
[unknown]或0xffffffffxxxxxx,大概率是kptr_restrict=2拦住了符号地址,先执行:sudo sysctl -w kernel.kptr_restrict=0
二、基础用法:实时看内核函数热点
sudo perf top
默认界面会滚动刷新,顶部显示采样频率、事件类型等,主体是按 CPU 占用倒序排列的符号列表,例如:
12.34% [kernel] [k] __softirqentry_text_start 8.76% [kernel] [k] do_syscall_64 5.21% [kernel] [k] native_write_msr 3.98% [kernel] [k] ext4_da_write_begin 2.45% libc-2.31.so [.] __libc_read
其中 [k] 表示内核态函数,[.] 表示用户态函数。
三、常用增强选项(聚焦内核)
| 选项 | 说明 |
|---|---|
-K |
只显示内核态符号(隐藏所有用户态函数,专注看 kernel) |
-G |
启用调用图(call-graph),按函数调用关系展开(需内核支持 CONFIG_FRAME_POINTER 或 CONFIG_UNWINDER_ORC) |
-e cycles,instructions,cache-misses |
指定多个硬件事件联合采样(如想看缓存未命中是否拖慢内核) |
-p PID |
只监控指定进程(含它的内核上下文,比如某服务频繁触发 ext4 或 tcp 栈) |
✅ 推荐组合(快速抓内核热点):
sudo perf top -K -G --no-children
-
-K:过滤掉用户代码,只留[k] -
-G:显示调用栈(如do_syscall_64 → __x64_sys_read → vfs_read → ext4_file_read_iter) -
--no-children:避免子函数时间被父函数重复累加,更准确反映各层真实开销
四、进阶技巧:识别典型内核瓶颈模式
- 看到大量
__softirqentry_text_start+net_rx_action:软中断处理过载,可能是网卡收包太快、NAPI 轮询不及时 - 高占比
cpuidle_enter_state或mwait_idle_with_hints:CPU 在空闲,实际不是内核问题,而是负载低或进程阻塞 -
futex_wait_queue_me/futex_wait占比高:用户态线程在等锁,但内核 futex 路径被频繁调用(说明锁竞争激烈) -
ext4_*或xfs_*函数持续上榜:文件 IO 密集,结合iostat -x 1看 await、r_await 是否异常
? 小提示:按
h键可呼出帮助菜单;按P可将当前排序结果保存为文本;按q退出。
不需要改代码、不用重启服务,perf top -K 就是一台对准内核执行路径的实时显微镜。重点不在“怎么运行”,而在于读懂那些函数名背后的真实路径——它们就是内核正在为你干活的地方。











