High CPU Usage in Idle Windows 7 KVM Guest: Diagnostics and Optimization Techniques


2 views

When running Windows 7 and Ubuntu 10.04 as KVM guests on an Ubuntu 10.04 host, I noticed significant CPU disparity during idle states. Monitoring through top and virt-manager revealed:

Host CPU usage:
Ubuntu guest: 1%
Windows 7 guest: 45-50%

Despite being a fresh installation with no background processes (confirmed via Task Manager showing 1-2% CPU usage), the Windows VM maintains abnormally high CPU consumption.

The initial setup used paravirtualized drivers for storage and network:

<domain type='kvm'>
    <devices>
        <disk type='file' device='disk'>
            <driver name='qemu' type='qcow2' cache='none' io='native'/>
            <source file='/path/to/windows.qcow2'/>
            <target dev='vda' bus='virtio'/>
        </disk>
        <interface type='network'>
            <mac address='52:54:00:xx:xx:xx'/>
            <source network='default'/>
            <model type='virtio'/>
        </interface>
    </devices>
</domain>

Several Windows-specific behaviors could explain this phenomenon:

# Check for CPU steal time in guest
Get-Counter '\Hyper-V Hypervisor Logical Processor(*)\% Total Run Time'
Get-Counter '\Hyper-V Hypervisor Virtual Processor(*)\% Guest Run Time'

Implement these KVM configuration tweaks for Windows guests:

<domain>
    <features>
        <hyperv>
            <relaxed state='on'/>
            <vapic state='on'/>
            <spinlocks state='on' retries='8191'/>
        </hyperv>
        <kvm>
            <hidden state='on'/>
        </kvm>
    </features>
    <clock offset='localtime'>
        <timer name='hypervclock' present='yes'/>
    </clock>
</domain>

Apply these registry modifications in the Windows guest:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
"LargeSystemCache"=dword:00000001
"SecondLevelDataCache"=dword:00000100

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile]
"NetworkThrottlingIndex"=dword:ffffffff

Create a PowerShell script to log CPU usage patterns:

$logFile = "C:\cpu_monitor_$(Get-Date -Format 'yyyyMMdd').csv"
while($true) {
    $cpu = Get-Counter '\Processor(_Total)\% Processor Time'
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$timestamp,$($cpu.CounterSamples.CookedValue)" | Out-File $logFile -Append
    Start-Sleep -Seconds 5
}

For persistent issues, consider these advanced configurations:

# CPU pinning example
virsh vcpupin win7-guest 0 2
virsh vcpupin win7-guest 1 3

# NUMA configuration
numactl --cpunodebind=0 --membind=0 virsh start win7-guest

When monitoring my KVM virtualization environment on Ubuntu 10.04 hosting both Linux and Windows 7 guests, I noticed a significant discrepancy in idle CPU usage. The Linux VM sits comfortably at 1% CPU utilization when logged out, while the Windows 7 VM consistently hovers around 45-50% despite showing idle in Task Manager.

Multiple monitoring tools confirm this behavior:

  • top shows high host CPU usage for the Windows VM
  • virt-manager graphs display sustained CPU activity
  • Guest Task Manager reports minimal process activity (1-2% CPU)

Even with paravirtualized drivers installed, several Windows-specific factors could contribute:

# Check current CPU steal time in the guest
Get-Counter '\Hyper-V Hypervisor Logical Processor(_Total)\% Total Run Time'
Get-Counter '\Hyper-V Hypervisor Logical Processor(_Total)\% Hypervisor Run Time'

The default Windows 7 installation includes several services that don't properly idle in virtual environments:

# List problematic services in PowerShell
Get-Service | Where-Object {
    $_.Status -eq 'Running' -and 
    ($_.Name -like '*Windows Search*' -or 
     $_.Name -like '*Superfetch*' -or
     $_.Name -like '*Defrag*')
} | Stop-Service -PassThru | Set-Service -StartupType Disabled

Add these parameters to your libvirt XML configuration:

<cpu mode='host-passthrough' check='none'>
  <topology sockets='1' cores='2' threads='1'/>
</cpu>
<features>
  <hyperv>
    <relaxed state='on'/>
    <vapic state='on'/>
    <spinlocks state='on' retries='8191'/>
  </hyperv>
</features>

After applying changes, verify CPU usage with:

# Host-side monitoring
virsh vcpuinfo [domain-name]
virsh domstats [domain-name] --cpu-total

# Guest-side verification using Performance Monitor
perfmon.exe /res

For persistent issues, consider:

  1. Updating to virtio-win 0.1.240 or later drivers
  2. Enabling MSI interrupts for virtio devices
  3. Testing with different CPU pinning configurations
# Check interrupt affinity in Windows
wmic path Win32_DeviceGuard get /format:list