Extremely slow disk IO in qemu-kvm VM

kvm-virtualizationqemu

I have a VM running Debian Woody (kernel 2.4.18). Qemu-2.1.2, 2 CPU cores, 512M RAM, qcow2 image connected as IDE, ext3.
The issue is that disk IO is slow. Here is a result of dd "benchmark" right after VM reboot:

(none):~# time dd if=/dev/zero of=test1 bs=102400 count=100
100+0 records in
100+0 records out

real    0m0.035s
user    0m0.000s
sys 0m0.020s
(none):~# time dd if=/dev/zero of=test1 bs=102400 count=100
100+0 records in
100+0 records out

real    0m0.022s
user    0m0.000s
sys 0m0.020s
(none):~# time dd if=/dev/zero of=test1 bs=102400 count=100
100+0 records in
100+0 records out

real    0m55.589s
user    0m0.020s
sys 0m0.560s

If I look what happens on the host I see qemu process consuming ~90% CPU (of total 600%), and reading and writing about 1.2MB/s. The HDD itself is ok, write speed is about 70MB/s.
I tried different VM settings (incl "threading" & "usafe"), converting image to raw, moving the image to freshly formatted filesystem (tried ext4 & btrfs). No visible difference.

I also noticed IO speed issues for other VM's with more recent kernels but didn't have enough time to test them well and used NFS mount to work around the issue.

What's wrong here?

UPD
Even mount -t nfs ... hangs. strace says that mount() call itself freezes:

mount("192.168.1.1:/mnt/gw/tmp", "/mnt", "nfs", 0xc0ed0000, 0x805a920) = -1 ENOSYS (Function not implemented)
mount("192.168.1.1:/mnt/gw/tmp", "/mnt", "nfs", 0xc0ed0000, 0x805a920) = -1 ENOSYS (Function not implemented)
mount("192.168.1.1:/mnt/gw/tmp", "/mnt", "nfs", 0xc0ed0000, 0x805a920) = -1 ENOSYS (Function not implemented)
mount("192.168.1.1:/mnt/gw/tmp", "/mnt", "nfs", 0xc0ed0000, 0x805a920[here it freezes for a several minutes]) = 0

Best Answer

I've been meaning to do this anyway so I did some installs.

The default for IDE style devices in this setup does seem to run at PIO mode speed thought haparm is claiming DMA ... doing this inside the VM makes it about 70 times faster on my machine.

hdparm -d1 /dev/hda
echo hdparm -d1 /dev/hda > /etc/rcS.d/S00hdparm.sh
chmod +x /etc/rcS.d/S00hdparm.sh

The other option is to use a SCSI disk emulation, on the qemu command line replace this

-hda $DISK

with this

-drive if=scsi,file=$DISK

gives an "sym53c8xx" compatible device emulation that the installer auto-detects. This has the nice effect that the device will be called "/dev/sda" rather than the old style "/dev/hda".

But beware, switching this on an already installed system isn't simple.

Note: using ahci will not work; Debian woody predates SATA.

PS: My compatibility smoke test seems mostly successful, just a couple of dumb GCC flags. Good luck with yours.