如何从宿主机精准统计QEMU/KVM虚拟机内执行的指令数?
我尝试使用perf kvm stat -p vmpid命令统计虚拟机内执行的指令数,但发现即使手动通过echo c > /proc/sysrq-trigger触发虚拟机内核崩溃(预期指令数趋近于0)的状态下,该命令仍会报告大量指令,示例输出如下:
3,835.91 msec task-clock:G # 1.000 CPUs utilized 25 context-switches:G # 0.007 K/sec 7 cpu-migrations:G # 0.002 K/sec 0 page-faults:G # 0.000 K/sec 10,879,172,713 cycles:G # 2.836 GHz 905,371,317 instructions:G # 0.08 insn per cycle 150,903,724 branches:G # 39.340 M/sec 23,387 branch-misses:G # 0.02% of all branches
请问是否有替代方法可以仅统计虚拟机内部执行的指令数?我的虚拟机基于QEMU/KVM平台,恳请提供宿主机端精准统计该数据的见解或建议。
解决方案与建议
1. 使用perf kvm的--guest-only过滤参数
默认的perf kvm stat会同时统计host侧处理VM的指令(比如VMEXIT后的host逻辑、QEMU自身线程的指令),这就是VM崩溃后仍有大量统计数据的核心原因。添加--guest-only参数可以仅捕获虚拟机guest模式下执行的指令:
perf kvm stat --guest-only -p <vmpid>
该参数会过滤掉所有host侧的性能事件,只保留VM内实际执行的指令统计,VM崩溃后指令数会趋近于0,符合预期。
2. 针对特定指令域的精准统计
如果需要区分VM内的用户态或内核态指令,可以结合事件过滤:
- 统计VM用户态指令:
perf kvm stat --guest-only -p <vmpid> -e instructions:u
- 统计VM内核态指令:
perf kvm stat --guest-only -p <vmpid> -e instructions:k
3. 利用QEMU内置的指令计数功能
启动VM时添加调试参数可以开启指令执行统计:
qemu-system-x86_64 [其他启动参数] -d exec,cpu
运行过程中可以通过QEMU monitor(默认按Ctrl+Alt+2切换)执行命令查看累计指令数:
info jit
如果需要运行时动态查询,也可以通过QMP接口发送指令获取统计数据,适合自动化场景。
4. 硬件虚拟化性能计数器配置
Intel VT-x和AMD-V都支持性能计数器虚拟化(PCV),可以让宿主机直接捕获guest的硬件性能事件。确保内核开启了KVM_INTEL_PMU或KVM_AMD_PMU模块,然后使用perf配合kvm子系统的事件即可实现精准统计,无需额外配置,--guest-only参数会自动利用该特性。
内容的提问来源于stack exchange,提问作者ray

