Virtio-net paravirtual drivers provide you with better network performance than emulated drivers for your guests. However you may not be taking full advantage of virtio-net if you're not making use of the linux vhost-net driver. In this post, we'll go over some configurations to ensure that you're getting maximum network performance using virtio-net and vhost-net.
The vhost architecture has been developed by Red Hat since around 2010 so it's been around for a while. The vhost-net provides much improved network performance for your guest is running virtio-net by totally bypassing qemu as a fast path for interrupting your guest. The alternative of involving qemu is very expensive due to context switches to userspace and multiple system calls. The vhost-net however runs in kernel as a kernel thread and interrups your guest with much less overhead providing near native performance.
If you're are using a management tool based on libvirt then libvirt will take care of a lot of the configuration tasks in setting up and running your guest. In order to get the best network performance for a guest running virtio-net the following conditions must be met.
So you installed the paravirtual network drivers in your guest and use virt-manager to setup your virtio nic. You've installed the most recent package of qemu-kvm. Now have you checked that vhost-net is loaded? The one common mistake I've seen many people make is assuming that vhost-net module is loaded. It's understandable too because even on a distribution like fedora, the most recent version at this time , 16, has vhost-net built into the kernel as a module so it's not loaded by default. Most people will go ahead and let virt-manager do it's magic and never bother to check that vhost-net is running.
To ensure that vhost-net is running run the following command as root in a terminal on your kvm host
Next verify that it's running with the following command
lsmod | grep vhost_net
You should then see output similar to the following showing that the module is loaded.
vhost_net 33675 1 macvtap 18183 3 vhost_net tun 22768 2 vhost_net
Now when you start your guest with virt-manager your command line generated by libvirt will contain vhost parameters. Below shows an example.
qemu 11678 1 21 Jan29 ? 1-02:11:05 /usr/bin/qemu-kvm -S -M pc-0.14 -enable-kvm -m 2048 -smp 1,sockets=1,cores=1,threads=1 -name Hitachi-XP -uuid 848b0584-7601-efe2-72b4-f3da80187e75 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/Hitachi-XP.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime -no-shutdown -boot order=c,menu=on -drive file=/home/hsolomon/images/xp-office.img,if=none,id=drive-ide0-0-0,format=qcow2 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 -drive file=/home/hsolomon/isos/virtio-win-1.4.0.iso,if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -netdev tap,fd=19,id=hostnet0,vhost=on,vhostfd=20 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:40:4a:67,bus=pci.0,addr=0x3 -chardev tty,id=charserial0,path=/dev/ttyS0 -device isa-serial,chardev=charserial0,id=serial0 -usb -device usb-tablet,id=input0 -vnc 0.0.0.0:1,password -vga qxl -global qxl-vga.vram_size=67108864 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
Run the following command to verify the vhost kernel thread is running for your instance of qemu-kvm.
ps -ef | grep vhost- | grep -v grep root 1563 2 0 Feb18 ? 00:00:00 [vhost-1561]
From the output you can see the kernel thread running for the qemu process id of 1561.
If you need to ensure that vhost-net is loaded because you use kvm guests with virtio-net one thing you can do is add the modprobe command above to your rc.local file on your linux distribution which will run whenever your machine boots. On Red Hat based distros this file is usually located at /etc/rc.d/rc.local. Below is an example of what your file will look like.
#!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local modprobe vhost-net
If you have been overlooking the vhost-net module, give it a try and feel free to post comments.