perf kvm

From KVM
Jump to: navigation, search

This page describes how to count and trace performance events in the KVM kernel module.

There are two tools, kvm_stat and kvm_trace, which were previously used for these tasks. Now this can be done using standard Linux tracing tools.

Counting events

Often you want event counts after running a benchmark:

$ sudo mount -t debugfs none /sys/kernel/debug
$ sudo ./perf stat -e 'kvm:*' -a sleep 1h
^C
 Performance counter stats for 'sleep 1h':

           8330  kvm:kvm_entry            #      0.000 M/sec
              0  kvm:kvm_hypercall        #      0.000 M/sec
           4060  kvm:kvm_pio              #      0.000 M/sec
              0  kvm:kvm_cpuid            #      0.000 M/sec
           2681  kvm:kvm_apic             #      0.000 M/sec
           8343  kvm:kvm_exit             #      0.000 M/sec
            737  kvm:kvm_inj_virq         #      0.000 M/sec
              0  kvm:kvm_page_fault       #      0.000 M/sec
              0  kvm:kvm_msr              #      0.000 M/sec
            664  kvm:kvm_cr               #      0.000 M/sec
            872  kvm:kvm_pic_set_irq      #      0.000 M/sec
              0  kvm:kvm_apic_ipi         #      0.000 M/sec
            738  kvm:kvm_apic_accept_irq  #      0.000 M/sec
            874  kvm:kvm_set_irq          #      0.000 M/sec
            874  kvm:kvm_ioapic_set_irq   #      0.000 M/sec
              0  kvm:kvm_msi_set_irq      #      0.000 M/sec
            433  kvm:kvm_ack_irq          #      0.000 M/sec
           2685  kvm:kvm_mmio             #      0.000 M/sec

    3.493562100  seconds time elapsed

The perf tool is part of the Linux kernel tree in tools/perf.

Tracing events

Detailed traces can be generated using ftrace:

# mount -t debugfs none /sys/kernel/debug
# echo 1 >/sys/kernel/debug/tracing/events/kvm/enable
# cat /sys/kernel/debug/tracing/trace_pipe
[...]
             kvm-5664  [000] 11906.220178: kvm_entry: vcpu 0
             kvm-5664  [000] 11906.220181: kvm_exit: reason apic_access rip 0xc011518c
             kvm-5664  [000] 11906.220183: kvm_mmio: mmio write len 4 gpa 0xfee000b0 val 0x0
             kvm-5664  [000] 11906.220183: kvm_apic: apic_write APIC_EOI = 0x0
             kvm-5664  [000] 11906.220184: kvm_ack_irq: irqchip IOAPIC pin 11
             kvm-5664  [000] 11906.220185: kvm_entry: vcpu 0
             kvm-5664  [000] 11906.220188: kvm_exit: reason io_instruction rip 0xc01e4473
             kvm-5664  [000] 11906.220188: kvm_pio: pio_read at 0xc13e size 2 count 1
             kvm-5664  [000] 11906.220193: kvm_entry: vcpu 0
^D
# echo 0 >/sys/kernel/debug/tracing/events/kvm/enable

Recording events

Events can be recorded to a file for later reporting and analysis. You can record events for the host using the --host option. You can record events for a guest using the --guest option. You can use both options at the same time to record events for both the host and a guest.

If you use just the --host option the default output file will be perf.data.host. If you use just the --guest option the default output file will be perf.data.guest. If you use both options the default output file will be perf.data.kvm. Use the -o option after the record key word to save the output to a different file name.

# perf kvm --host --guest [kvm options] record -a -o my.perf.data

Recording events for a guest

Using copies of guest files

In order to record events for a guest, the perf tool needs the /proc/kallsyms and /proc/modules for the guest. These are passed to perf with the --guestkallsyms and --guestmodules options. The files will have to be on the host, but you can get them easily using ssh.

# ssh guest "cat /proc/kallsyms" > /tmp/guest.kallsyms
# ssh guest "cat /proc/modules" > /tmp/guest.modules

It is better to use ssh to cat the files and redirect the output than to use scp. Experience has shown that scp guest:/proc/kallsyms /tmp/guest.kallsyms will return an empty file.

Using these options you can record the events for a host and a guest with the following command

# perf kvm --host --guest --guestkallsyms=/tmp/guest.kallsyms --guestmodules=/tmp/guest.modules record -a

The order of the arguments is important. In general, the syntax for using perf to profile kvm is: perf kvm <perf kvm args> <perf command> <perf command args> In this case the perf kvm arguments are --host --guest --guestkallsyms=/tmp/guest.kallsyms --guestmodules=/tmp/guest.modules, the perf command is record, and the perf command argument is -a (profile all processes).

perf will record events until it is terminated with SIGINT. It must be SIGINT. If perf is terminated with any other signal, such as SIGTERM or SIGQUIT, the pref kvm report command (see below) won't correctly process the file generated. It will just list the headers with no data.

Using sshfs

perf kvm has a way of getting the guest's kallsyms and modules by itself instead of you hving to provide them. It makes use of sshfs to mount the root file system of the guest so that it can get the files directly from the guest.

sshfs depends on fuse, the Filesystem in Userspace. If your Linux distribution does not have fuse, see the fuse project page on SourceForge. If your Linux distribution does not have sshfs, see the sshfs project page on SourceForge.

Here's how it works. You create a directory, e.g., /tmp/guestmount. You then create a subdirectory that has for its name the PID of the qemu process for the guest. Then you use sshfs to mount the guest's root file system on that subdirectory. For example:

# mkdir -p /tmp/guestmount
# ps -eo pid,cmd | grep qemu | grep -v grep
24764 /usr/libexec/qemu-kvm -M pc -m 4096 -smp 4 -name guest01 -boot c -drive file=/var/lib/libvirt/images/guest01.img ...
# mkdir /tmp/guestmount/24764
# sshfs -o allow_other,direct_io guest:/ /tmp/guestmount/24764

Then, instead of using the --guestkallsyms and --guestmodules options, you use the --guestmount option.

# perf kvm --host --guest --guestmount=/tmp/guestmount

When you are finished recording, unmount the guest file system using fusermount.

# fusermount -u /tmp/guestmount/24764

Reporting events

Use the perf kvm report command to generate a report from a data file created by perf kvm record. To generate a report for the host, use the --host argument.

# perf kvm --host --guestmount=/tmp/guestmount report

To generate a report for the guest, use the --guest argument.

# perf kvm --guest --guestmount=/tmp/guestmount report

By default the perf report command will read perf.data.host for a host report and perf.data.guest for a guest report. Use the -i option if you want to use a different input file.

# perf kvm --host --guestmount=/tmp/guestmount report -i /tmp/perf.data.kvm

The perf report command sends its output to standard out. If you want the output to go to a file, redirect the output to a file. Don't use the -o option. Contrary to the help text, it does not work.

Links

<think>好的,用户现在问的是“KVM_EXIT_HYPERV”,我需要先理解这个术语的具体含义。根据之前的对话,用户可能已经对KVM有一定的了解,比如KVM-CPUs和HVF的区别,但现在他们深入到了更具体的退出原因。 首先,KVM_EXIT_HYPERV看起来像是KVM中的一个退出原因(exit reason)。KVM在处理虚拟机时,当客户机执行需要宿主干预的操作时,会触发VM-Exit,此时KVM会处理并可能返回不同的退出原因。KVM_EXIT_HYPERV可能涉及到Hyper-V相关的功能。 接下来,我需要确认这个术语的正确性。查阅资料时发现,KVM确实有一个退出原因叫KVM_EXIT_HYPERV,通常在客户机使用Hyper-V的扩展功能时触发。这可能是在Linux作为宿主机运行Windows虚拟机时常见的情况,因为Windows会使用Hyper-V的指令。 用户可能是在调试虚拟机性能问题或配置Hyper-V相关功能时遇到这个退出原因,需要了解其背后的原因和解决方法。他们可能想知道为什么会出现这个退出,如何优化或避免它,或者如何正确配置KVM来支持Hyper-V的特性。 需要解释KVM_EXIT_HYPERV的定义、触发条件、常见场景以及如何处理。比如,当客户机使用Hyper-V的hypercall时,KVM需要模拟这些调用,否则可能导致频繁的退出,影响性能。解决方案可能包括启用KVM的Hyper-V扩展支持,如evmcs或synic,或者调整虚拟机的配置参数。 另外,用户可能对如何诊断这类问题感兴趣,比如使用工具检查退出原因的频率,或者调整日志级别来获取更多信息。需要给出具体的命令和配置示例,帮助他们实际操作。 最后,确保回答结构清晰,分点解释,结合示例,让用户能够逐步理解和解决问题。同时,注意使用中文,避免技术术语过于晦涩,必要时进行解释。</think>### **KVM_EXIT_HYPERV 详解** `KVM_EXIT_HYPERV` 是 Linux 内核虚拟化模块 **KVM** 中的一个 **虚拟机退出原因(VM-Exit Reason)**,表示客户机(Guest OS)触发了需要宿主机(Host)干预的 **Hyper-V 特定操作**。它通常出现在以下场景: - 客户机是 **Windows 系统**(依赖 Hyper-V 扩展功能)。 - 客户机配置启用了 Hyper-V 兼容性特性(如 Hyper-V Enlightenments)。 - KVM 需模拟 Hyper-V 的 hypercall、事件或同步机制。 --- ### **1. 核心概念** #### **什么是 VM-Exit?** 在硬件虚拟化(如 Intel VT-x/AMD-V)中,当客户机执行某些敏感指令或访问特定资源时,CPU 会触发 **VM-Exit**,将控制权交还给宿主机(KVM),由 KVM 处理后再恢复客户机运行。 - **退出原因**KVM 根据触发原因定义多种 `KVM_EXIT_*` 常量,如 `KVM_EXIT_IO`(I/O 操作)、`KVM_EXIT_HYPERV`(Hyper-V 相关操作)。 #### **Hyper-V 与 KVM 的交互** - **Hyper-V** 是微软的虚拟化技术,定义了一套 hypercall(类似系统调用)和特性(如计时器、事件通知)。 - **KVM** 需要模拟 Hyper-V 的行为以兼容 Windows 客户机,否则客户机会因无法调用 Hyper-V 功能而频繁触发 `KVM_EXIT_HYPERV`,导致性能下降。 --- ### **2. 触发场景与原因** `KVM_EXIT_HYPERV` 可能由以下操作触发: | **触发原因** | **说明** | |----------------------------|-------------------------------------------------------------------------| | **Hyper-V hypercall** | 客户机通过 `VMCALL` 指令调用 Hyper-V 功能(如内存管理、事件通知)。 | | **Hyper-V SynIC 访问** | 客户机访问 **Synthetic Interrupt Controller**(合成中断控制器)相关寄存器。 | | **Hyper-V TLB 刷新请求** | 客户机请求刷新 TLB(需宿主机模拟)。 | | **Hyper-V 计时器操作** | 客户机使用 Hyper-V 特定的计时器(如 `HvTimer`)。 | --- ### **3. 性能影响与优化** #### **问题表现** - **频繁 VM-Exit**:若 KVM 未正确配置 Hyper-V 模拟,客户机每次调用 Hyper-V 功能都会触发 `KVM_EXIT_HYPERV`,导致上下文切换开销增大,显著降低虚拟机性能。 - **典型症状**- Windows 客户机运行缓慢。 - `perf kvm stat` 显示大量 `KVM_EXIT_HYPERV` 事件。 #### **优化方案** 1. **启用 KVM 的 Hyper-V 扩展支持** 在虚拟机配置中显式启用 Hyper-V 特性,减少不必要的退出: ```bash # QEMU 命令行示例 -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time ``` - **关键参数**- `hv_relaxed`: 启用 relaxed timing(降低时钟同步开销)。 - `hv_vapic`: 启用虚拟 APIC(加速中断处理)。 - `hv_time`: 使用 Hyper-V 计时器替代传统计时器。 2. **配置 Hyper-V Enlightenments** 在 Libvirt XML 中为 Windows 客户机添加 Hyper-V 特性: ```xml <features> <hyperv> <relaxed state='on'/> <vapic state='on'/> <spinlocks state='on' retries='8192'/> </hyperv> </features> ``` 3. **使用 `evmcs` 加速嵌套虚拟化** 若需在 Windows 客户机内运行 Hyper-V(嵌套虚拟化),需启用 `evmcs`(Enlightened VMCS): ```bash # 加载 KVM 模块时启用 evmcs modprobe kvm_intel evmcs=1 ``` --- ### **4. 调试与诊断** #### **步骤 1:检查退出原因频率** 使用 `perf` 工具统计 `KVM_EXIT_HYPERV` 发生次数: ```bash sudo perf kvm stat --event=vmexit ``` 输出示例: ``` VM-EXIT Samples Samples% Time% Reasons ... KVM_EXIT_HYPERV 1200 15.3% 12.7% [Hyper-V hypercall] ... ``` #### **步骤 2:追踪具体操作** 启用 KVM 调试日志,查看触发 `KVM_EXIT_HYPERV` 的详细信息: ```bash echo 1 | sudo tee /sys/module/kvm/parameters/trace_enabled dmesg -w | grep "KVM_EXIT_HYPERV" ``` 输出示例: ``` [ 1234.567] kvm: vcpu0: KVM_EXIT_HYPERV type=0x0 (HVCALL_NOTIFY_LONG_SPIN_WAIT) ``` #### **步骤 3:验证 Hyper-V 特性是否生效** 在 Windows 客户机内运行 PowerShell 命令,检查 Hyper-V 服务状态: ```powershell Get-Service vm* | Where Status -eq Running ``` --- ### **5. 常见问题与解决** #### **Q1:Windows 客户机频繁卡顿,`perf` 显示大量 `KVM_EXIT_HYPERV`** **解决**- 确保虚拟机配置启用了 `hv_relaxed`、`hv_vapic` 等参数(参考优化方案 1)。 - 更新 QEMU 和 Linux 内核至最新版本(修复已知兼容性问题)。 #### **Q2:嵌套虚拟化(Hyper-V in KVM)性能极差** **解决**- 加载 `evmcs` 模块:`modprobe kvm_intel evmcs=1`。 - 在客户机 XML 中添加 `<feature policy='require' name='vmx'/>`。 #### **Q3:如何彻底禁用 Hyper-V 相关退出?** **不建议**:禁用 Hyper-V 特性可能导致 Windows 客户机无法启动或性能更差。若必须禁用,可尝试: ```bash -cpu host,-hv_vapic,-hv_time ``` --- ### **6. 总结** - **核心意义**:`KVM_EXIT_HYPERV` 是 KVM 处理 Hyper-V 兼容性操作的关键机制,合理配置可大幅优化 Windows 客户机性能。 - **最佳实践**- 始终为 Windows 客户机启用 Hyper-V Enlightenments。 - 定期更新宿主机的 KVM/QEMU 版本以支持最新 Hyper-V 特性。 - 使用性能分析工具(如 `perf`)监控 VM-Exit 频率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值