windows虚拟机对应的qemu进程cpu占有率116%

1.1 现象

   在公有云平台,openstack计算节点上,如图Figure-1所示,一台windows虚拟机的qemu-kvm进程116%的占用cpu资源,如果Figure-2所示,该虚拟机仅有一个vcpu,因此该虚拟机已经满负荷的运行。

 

                           Figure-1

 

             Figure-2

1.2 分析步骤

   通过下面步骤的分析,了解qemu-kvm进程在忙什么,为什么这么忙?

1.2.1 查看进程、线程的状态

   通过top -d 3 -Hp 5180查看进程,以及该进程的相关线程的状态,分析出哪个线程在忙。如图Figure-3所示,线程5180的CPU%为26.7%,该线程是Qemu的主线程,线程5207的CPU%为90.1%,说明:

1)Qemu有线程互相间调度,不存在某个线程挂掉或者阻塞在什么资源上,把别的线程一直阻塞住的情况

2)5207线程一直90%左右的CPU占有率,是什么外部I/O事件,或者什么软件一直很忙?

   下面观察下线程5207的stack情况,stack里有函数调用的过程,使用gdb过程如图Figure-4所示:

1)gdb attach 5180

2)info thread   (线程5207的id是101)

3)t 101

4)backtrace

5)detach

6)quit

backtrace的结果可以看出,这个线程是个vcpu线程,通过kvm_vcpu_ioctl进入vm_entry。另外通过另外一种方式pstack 5207,同样可以查看线程的stack(Figure-5)。

 

                               Figure-3

 

                            Figure-4

 

                          Figure-5

1.2.2 查看GuestOS的状态

   vcpu线程一直在忙,通过vnc进入GuestOS,观察GuestOS的进程、内存等资源使用情况,这个过程参考1.2.4章节。测试发现,vnc连接可以建立(说明qemu的vnc线程正常),桌面显示这个虚拟机GuestOS是windows系列,ctrl+alt+delete尝试用户登录,系统没有任何相应和提示,系统无法响应键盘(虚拟键盘)的中断事件,有可能系统已经crack,也有可能陷在别的事件里。

1.2.3 运用Qemu tracing分析

   因不能进入windows桌面,就不能实时查看系统的CPU、I/O等资源的使用情况,怎么办呢?Qemu本身的代码就具有trace的功能,tracing的介绍和使用,可以参考qemu的文档:qemu-2.9.0/docs/tracing.txt。

   TBD

1.2.4 运用perf分析

   Linux的性能分析工具perf,可以实时的监控分析操作系统(内核、用户态),如硬件级别(CPU、PMU、Memory、Cache),软件级别(tracepoints、software counters),perf支持的事件可以通过perf list查看。

   perf查看进程消耗:

     perf record -a -g -p 5180 sleep 20

     perf report

     perf report -n --header --stdio

如图Figure-6和Figure-7所示,perf report从高到低显示了CPU执行的函数,调用栈,以及百分比,不过这个结果不易阅读,用火焰图显示的结果如图Figure-8所示(关于火焰图的使用参考flamegraph目录下的资料)。

 

                           Figure-6

 

                           Figure-7

 

                            Figure-8

从火焰图Figure-8的结果来看,这个进程号5180的虚拟机,CPU最主要的消耗在KVM操作,主要是:vmx_handle_exit,vmx_handle_external_intrvmx_save_host_state这三个函数,从火焰图上看,占用的比例分别是:12.63%、12.38%、11.79%。

既然KVM模块占了大部分,下面通过perf kvm stat了解分析下kvm的真实行为。通过下面的命令:

perf stat -e 'kvm:*' -a -p 5180 sleep 20

先来看看占比最高的vmx_handle_exit,引起vmx_handle_exit主要有两点:

访问IO port(handle_pio)

访问MMIO(handle_apic_access)

如图Figure-9所示,除了VM Entry和VM Exit事件外,最高的就是kvm_pio,说明GuestOS有大量的IO port操作,这个在Figure-8火焰图上也得到了验证。

 

                    Figure-9

 

             Figure-10

再来看看vmx_handle_external_intr,如图Figure-10所示,"call *%[entry]\n\t"这个过程调用中断处理函数(目前还没有找到方法,如何判断是哪个外设引起的中断?)。

Figure-9看到,GuestOS有大量的IO Port操作,通过下面的过程分析下是哪个设备有大量的IO操作。

perf kvm stat record -a -p 5180 sleep 10

perf kvm stat report --event=vmexit

perf kvm stat report --event=ioport

 

                            Figure-11

 

                           Figure-12

Figure-11来看,基本上都是IO造成了vm_exit,Figure-12显示,只有0x600的IO Port有IO读写事件,GuestOS可能已经处于Dead状态了。

通过Qemu后台的命令,virsh qemu-monitor-command instance-0000068c --hmp "info mtree",我们来看看0x600这个端口是哪个设备,如图Figure-13所示,这个设备是ACPI Power Manager的evt。

 

                  Figure-13

1.2.5 结论

nova stop/start重启这台虚拟后,对比Figure-14、15、16和Figure-9、11、12,虚机正常运行时,vm_exit和io_port事件都很正常,IO_INSTRUCTION、EXCEPTION_NMI是造成vm_exit的主要事件,IO读写主要是0x70、0x71这两个rtc时钟I/O端口的读写。

所以,应该是虚拟电源管理模块ACPI)异常导致了GuestOS crack。解决问题,有待研究GuestOS的电源管理,待机省电等等有关的配置。(物理机的环境下,待机后也偶尔碰到不能唤醒,蓝屏的情况)

 

                     Figure-14

 

                     Figure-15

 

                     Figure-16

另外,UCloud微博上有篇文章(https://zhuanlan.zhihu.com/p/27727903),讲到I/O端口0x608读写导致频繁的vm_exit,按照文章的提示,进行了模拟,去掉虚拟机XML里与hypervclock有关的配置(去掉下面列出的部分):

     <hyperv>

       <relaxed state='on'/>

       <vapic state='on'/>

       <spinlocks state='on' retries='8191'/>

     </hyperv>

     <clock ...>

       <timer name='hypervclock' present='yes'/>

     </clock>

这个过程,需要先关闭openstack-nova-compute.servie,然后virsh更新虚拟机配置,然后关闭虚拟机,再重启虚拟机,见下面的命令行:

systemctl stop openstack-nova-compute.service     (让libvirt管理下虚拟机)

virsh edit instance-0000068         (修改虚拟机配置)

virsh shutdown instance-0000068     (关闭虚拟机)

virsh start instance-0000068        (启动虚拟机)

 

                 Figure-17

如图Figure-17所示,GuestOS不停的在读0x608端口(ACPI-tmr),比例是40%,对虚机的性能影响最大。解决的方法就是,减少读取ACPI PM Timer而引起的VM Exit,思路就是考虑利用paravirtulization设备替代full-virtualization设备,目前Qemu已经支持的hypervclock就具备这方面的功能,相关的配置见Figure-18Figure-19。注意HypervisorGuestOSHostOSlibvirt版本是否支持该功能。

 

                     Figure-18

 

                                Figure-19

猜你喜欢

转载自blog.csdn.net/somyjun/article/details/79584811