技术解析

请教一个虚拟化的问题, kvm 虚拟机中运行一个简单的 C 程序,导致服务主机中 CPU 占用 100%。
0
2021-06-21 01:44:51
idczone

问题描述:

  • Linux 主机,运行操作系统为 ubuntu 18.04 server,cpu:intel 8700。
  • kvm 虚拟机操作系统 archlinux。
  • 写了一个简单的 C 程序:
#include 
#include 

int main(int argc, char** argv)
{
    int i = 0;

    while(1){
        i++;
        usleep(100);
    }
}
  • 将该程序在虚拟机中运行,在虚拟机中使用 top 查看,该进程 cpu 占用率约为 1~2%。
  • 此时在 ubuntu 主机中使用 top 查看,发现 qemu-system-x86_64 进程 cpu 占用率在 100%左右。
  • 求解答,是什么原因导致了虚拟机 cpu 占用率正常,而 ubuntu 主机的 cpu 占用率这么高? CPU 切换?有没有人碰到过这样的问题?

不知道节点对不对,没发现虚拟化节点。

不确定具体怎么回事,但是有没有可能是 qemu 如何实现时钟、interrupt 的问题?比如 qemu 本身必须 busy wait 去实现虚拟机里的 sleep ?

不清楚,试了两台机器,都有这个问题,这样的话好多类似机制程序就无法安全高效的在虚拟机中运行了,改了好多配置,都搞不定这个问题。

usleep 单位是微妙,sleep 0.1 毫秒正常情况下没有人会这么干。0.1 毫秒完成 userspace 与 kernel 的切换,同时还把 CPU 控制权交个宿主机,宿主机完成调度之后还能再切换回来这个效率以及很高了。还有宿主机未必是在全速运行的。

看起来有道理。公司的一个程序,跑在了虚拟机上,导致了 host 主机 CPU 占用很高,我定位了一下,应该是 usleep 导致,这样写程序肯定不太合适,不过这个程序在物理机上运行的话,cpu 占用率是很低的,难道时间都耗费在了宿主机和虚拟机的处理器切换上?

是不是 sleep 以后中断,然后唤醒,一直中断 /唤醒导致的?去除 sleep 试试看

虚拟机也不能这么慢,难不成母鸡 cpu 用满了?

去掉 usleep,主机和虚拟机,都有一个 cpu 是 100%,这样是正常现象。在物理机上跑也是百分之百,因为是无间歇的死循环了。

在我自用的 Windows 主机上,我用 vmware 开了一个虚拟机,虚拟机系统也是 archlinux,跑这个程序,没有问题,Windows 主机和虚拟机处理器占用都很低。

1.top 是采样,不能真实地反应 cpu 情况
2.不知道 qemu 的实现方式,是不是 qemu 的调度策略导致的
3.gdb 或者 strace 或别的方法看看 qemu 的系统调用试试,以及在 qemu 里看看进程的调用试试?

这个是真的高,处理器温度从 40 升到了 60,风扇转速也上去了。明天用 gdb 追踪分析一下。

不用 GDB 吧,sar -w 看一下 context

pidstat -w -p 1 12 看一下也可以,或者看一下 proc 下面的 stack

明天去公司试一下。

你把 Ubuntu 换成 debian centos 也许就解决了

有任何一丁点的理论依据吗?

没有 只是个人建议 。Ubuntu 本身占用资源多 这是肯定的

配额多少 按理说应该虚拟机的每个 vcpu 都只是宿主机上的一个线程

虚拟机是四核 4G

还有一个机器,主机 cpu 是 2620v3, os:ubuntu16.04 ,虚拟机是 1cpu,1G,ubuntu16.04 ,也是同样的问题。

亲测。
vm:
-p 14971
top - 21:42:17 up 9 days, 11:02, 5 users, load average: 0.08, 0.03, 0.02
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.9 us, 0.4 sy, 0.0 ni, 97.7 id, 0.9 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4046344 total, 268972 free, 466868 used, 3310504 buff/cache
KiB Swap: 4194300 total, 4193488 free, 812 used. 3216164 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14971 root 20 0 4220 648 580 R 8.3 0.0 0:01.74 a.out
cpu 占用率基本在 7%左右波动

host:
-p 104384
top - 21:44:37 up 36 days, 12:04, 1 user, load average: 3.64, 3.80, 3.80
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 9.4 us, 1.7 sy, 0.0 ni, 88.8 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 65729244 total, 64605832 used, 1123412 free, 189524 buffers
KiB Swap: 66875388 total, 4046752 used, 62828636 free. 24522884 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
104384 libvirt+ 20 0 9332380 3.898g 5068 S 30.3 6.2 1530:39 qemu-system-x86
CPU 占用率基本稳定在 30 左右,观察 1 分钟

将 vm 里 a.out kill 掉。
host:
top - 21:47:45 up 36 days, 12:07, 1 user, load average: 3.99, 3.77, 3.77
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 7.9 us, 1.7 sy, 0.0 ni, 89.9 id, 0.4 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 65729244 total, 64600260 used, 1128984 free, 189736 buffers
KiB Swap: 66875388 total, 4046704 used, 62828684 free. 24526240 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
104384 libvirt+ 20 0 9332380 3.898g 5068 S 11.0 6.2 1531:24 qemu-system-x86

CPU 占用率降为 10%左右。


附:
host cpu 为 Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz,40 Core
vm 里分了 4 Core。

楼主最后解决了么,是什么原因导致的呢

没有解决,我把程序改了,这里不再使用 nanosleep。原因猜想是 nanosleep 导致了宿主机和虚拟机之间的频繁切换。。。只是猜想。

写错了,不是 nanosleep 是 usleep。

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服