During the last six months, running a CentOS server as a guest in Virtualbox or VMware has been as common for me as running a web browser. This is because I’ve constantly been trying to streamline the server configuration and utilize new technologies or techniques attempting to get better performance or just make it easier to maintain. The only issue I had to face during all this time was the high CPU usage on the host, which in some cases exceeded 40%, even when the guest (CentOS server) was in idle state. At first, I had thought that the host’s operating system, Windows 7 RC (Release Candidate), was somehow incompatible with Virtualbox/VMware.
It was only a few weeks ago that I decided to investigate the issue and soon I found several reports all around the web. It turned out that the real cause of the problem was the high frequency at which the stock CentOS kernel is clocked, 1000Hz. Lowering the frequency of the internal clock of the kernel on the guest OS drastically reduced the CPU utilization of the host. At first, this was only possible by recompiling the kernel, but, fortunately, now we can use some boot kernel options to adjust the clock frequency.
For instance, my virtual CentOS server GRUB configuration has the following entry:
title CentOS (2.6.18-164.6.1.el5) root (hd0,0) kernel /vmlinuz-2.6.18-164.6.1.el5 ro root=/dev/VGSERVER/LVROOT divider=10 clocksource=acpi_pm initrd /initrd-2.6.18-164.6.1.el5.img
The divider option adjusts the kernel’s internal clock by dividing its default frequency by 10. So, my kernel is now clocked at:
1000Hz / 10 = 100Hz. Well, that’s not optimal, but suits my current needs. Until CentOS/RHEL 5.3, this option also served as a workaround for time synchronization between the host and the guest OS. For CentOS 5.4 and later, we just need the “divider” in order to underclock the kernel without actually recompiling it. Also, the “clocksource” option is not required any more.
You can find information about whether the divider option is supported by your distribution by checking the Timekeeping best practices for Linux guests article on the VMware knowledge base.
But, make no mistake. All the above are just a workaround. The kernel configuration includes the option to configure it as “tickless” (CONFIG_TICK_ONESHOT & CONFIG_NO_HZ):
Processor type and features ---> [*] Tickless System (Dynamic Ticks)
From the kernel docs:
This option enables a tickless system: timer interrupts only trigger on an as-needed basis both when the system is busy and when the system is idle.
This sounds like a Real Solution™. I tried to build a minimal kernel (version 2.6.32), using the “tickless” feature, specifically for Virtualbox, but, after spending many hours with it, I could not make it recognize my root LVM volumes. So, being extremely frustrated, I abandoned the whole project and used the divider option as I mentioned above.
If anyone has built a minimal custom kernel specifically for Virtualbox or VMware, which supports LVM/RAID and can actually boot a root LVM system, please let me know.
The High CPU usage while running CentOS as guest on Virtualbox or VMware by George Notaras, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.