VMWare: Fixing Time Drift in AMD Dual-core Systems

I've been having some really nasty time drift on VMware servers guests of late. This is a big pain because so much relies on accurate date and time.

The problem I was seeing was that the time on the guest was running very fast so I took the steps of setting the max cpu on the host machine's vmware configuration. To do this you run cat /sys/devices/system/cpu/cpu1/cpufreq/cpuinfomaxfreq and set this in /etc/vmware/config as follows:

host.cpukHz = 2300000
host.noTSC = "TRUE"
ptsc.noTSC = "TRUE"

Once you've updated the configuration you then have to shutdown all of your VMs and then restart Vmware. /etc/init.d/vmware restart and then boot back all of your VMs.

This resulted in the VM's clocks running really slow (as revealed by running the date command) and so I spent some time looking into why this was. I found a clue looking at /proc/cpuinfo as this was showing that both processors were running at 1Ghz.

I found various posts on forums talking about the cpufrequtils package which are a set of utilities to aid checking and setting the cpu configuration. They are installed with the following apt-get incantation:

sudo apt-get install cpufrequtils

The next step is to check where you settings are currently at:

muffin@winandawsome /usr/bin $ cpufreq-info
cpufrequtils 0.2: cpufreq-info (C) Dominik Brodowski 2004
Report errors and bugs to linux@brodo.de, please.
analyzing CPU 0:
  driver: powernow-k8
  CPUs which need to switch frequency at the same time: 0 1
  hardware limits: 1000 MHz - 2.30 GHz
  available frequency steps: 2.30 GHz, 2.20 GHz, 2.00 GHz, 1.80 GHz, 1000 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 1000 MHz and 2.30 GHz.
                  The governor "userspace" may decide which speed to use
                  within this range.
  current CPU frequency is 1000 MHz.
analyzing CPU 1:
  driver: powernow-k8
  CPUs which need to switch frequency at the same time: 0 1
  hardware limits: 1000 MHz - 2.30 GHz
  available frequency steps: 2.30 GHz, 2.20 GHz, 2.00 GHz, 1.80 GHz, 1000 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 1000 MHz and 2.30 GHz.
                  The governor "userspace" may decide which speed to use
                  within this range.
  current CPU frequency is 1000 MHz.

As you can see thie meant for me we are currently running at 1000Mhz (1Ghz)

Setting the cpu frequency requires swtiching to the userspace governor and then setting the value you want in kHz.

sudo cpufreq-set -g userspace
sudo cpufreq-set -f 2300000

Testing the value is set correctly is as follows:

muffin@winandawesome /usr/bin $ cpufreq-info
cpufrequtils 0.2: cpufreq-info (C) Dominik Brodowski 2004
Report errors and bugs to linux@brodo.de, please.
analyzing CPU 0:
  driver: powernow-k8
  CPUs which need to switch frequency at the same time: 0 1
  hardware limits: 1000 MHz - 2.30 GHz
  available frequency steps: 2.30 GHz, 2.20 GHz, 2.00 GHz, 1.80 GHz, 1000 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 1000 MHz and 2.30 GHz.
                  The governor "userspace" may decide which speed to use
                  within this range.
  current CPU frequency is 2.30 GHz.
analyzing CPU 1:
  driver: powernow-k8
  CPUs which need to switch frequency at the same time: 0 1
  hardware limits: 1000 MHz - 2.30 GHz
  available frequency steps: 2.30 GHz, 2.20 GHz, 2.00 GHz, 1.80 GHz, 1000 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 1000 MHz and 2.30 GHz.
                  The governor "userspace" may decide which speed to use
                  within this range.
  current CPU frequency is 2.30 GHz.

After setting the time via ntp you can test that drift is reduced. To sync with an ntp server simply run:

sudo ntpdate ntp.ubuntu.com

There are other things you can do to minimise time drift on VMWare images. For machines whose clocks are appearing to run slowly you can use VMWare tools "tools.syncTime" property in your .vmx file e.g:

tools.syncTime = "TRUE"

Do bear in mind that the VMware syncTime process cannot slow down fast clocks it can only help slow ones.

The main thing here is make sure the host machine is not doing anything which can cause CPU frequency to change dynamically - which also includes anything related to powersaving modes etc.

For further reference it's worth looking at VMWare's own paper on ways to correct time drift in VM guests which is a great starting point for working out how to attack time drift problems.