I've been plagued for a while by a major disparity between the CPU usage reported by a KVM host and guest. The guest will be reporting as basically idle, but the host will report one virtual core at 100% CPU.
I've finally tracked it down to a misbehaving application that ends up calling a very short nanosleep in a tight loop in the guest. The following C code will replicate the issue reliably:
#include <time.h>
void main() {
while (1) {
struct timespec ts = {0, 1024*100};
nanosleep(&ts, NULL);
}
}
If I run this program in the host, the CPU is basically idle. If I run it in the guest, the guest believes he is idle, but the host reports a core fully used.
I do intend to make the application better behaved, but I would like to understand the root cause of the mismatch. Is there potentially something misconfigured in my KVM setup that could lead to this, or is this an expected outcome somehow?
In my test setup, the host is Ubuntu 18.10, and the guest is CentOS 6. I've been able to replicate this with other guest OSes as well.
nanosleep
probably forces the guest OS to very frequently read the CPU TSC which, in turn, can cause considerable load on the host system. This is, however, very platform and setting specific.I would suggest to first read libvirt
timer
andstimer
documentation here, then give at look a the following resources:https://superuser.com/questions/1317948/qemu-enable-kvm-slower-than-pure-emulation-for-x86-64
https://docs.fedoraproject.org/en-US/Fedora/13/html/Virtualization_Guide/chap-Virtualization-KVM_guest_timing_management.html
https://wiki.qemu.org/Features/CPUModels