[Virtualization][qemu][kvm][virtio] 使用 QEMU/KVM 模拟网卡多队列
序:
做DPDK例子的时候,发现一些例子需要多队列,而我当前所使用的虚拟机并不是多队列的。关于我当前虚拟机的状态,可以见前文。
所以,我的需求就是,让虚拟机里的网卡,有多队列!
参考:
http://www.linux-kvm.org/page/Multiqueue
https://gist.github.com/sibiaoluo/11133723
原理上没大看懂,半懂不懂的。目的优先。
查看:
如何查看网卡是否支持多队列: 红色的行就代表支持了。 MSI-X就是支持多队列的意思,MSI是什么意思,我也不知道。
Count=64 代表支持64个队列。
[root@C4 20161206]# lspci |grep 82599 21:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) 21:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) [root@C4 20161206]# lspci -vv -s 21:00.0 |grep MSI Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+ Capabilities: [70] MSI-X: Enable+ Count=64 Masked- Capabilities: [a0] Express (v2) Endpoint, MSI 00 [root@C4 20161206]#
再查看: 队列分了四种,RX,TX,Other,Combined。 63代表 combined可以设置的最大值是63. 24代表当前的队列设置是24
[root@C4 20161206]# ethtool -l eth4 Channel parameters for eth4: Pre-set maximums: RX: 0 TX: 0 Other: 1 Combined: 63 Current hardware settings: RX: 0 TX: 0 Other: 1 Combined: 24 [root@C4 20161206]#
当然这个值是可以该的,比如将24 改为 25:
[root@dpdk ~]# ethtool -L eth1 combined 25
再查看:中断
[root@C4 20161206]# ls /sys/bus/pci/devices/0000\:21\:00.0/msi_irqs/ 100 101 102 103 104 105 106 107 108 109 110 111 87 88 89 90 91 92 93 94 95 96 97 98 99 [root@C4 20161206]#
还可以:
[root@C4 20161206]# cat /proc/interrupts |grep eth4 |awk -F ' ' '{print $27}' eth4-TxRx-0 eth4-TxRx-1 eth4-TxRx-2 eth4-TxRx-3 eth4-TxRx-4 eth4-TxRx-5 eth4-TxRx-6 eth4-TxRx-7 eth4-TxRx-8 eth4-TxRx-9 eth4-TxRx-10 eth4-TxRx-11 eth4-TxRx-12 eth4-TxRx-13 eth4-TxRx-14 eth4-TxRx-15 eth4-TxRx-16 eth4-TxRx-17 eth4-TxRx-18 eth4-TxRx-19 eth4-TxRx-20 eth4-TxRx-21 eth4-TxRx-22 eth4-TxRx-23 eth4 [root@C4 20161206]# ll /sys/
开始:
当前配置:
/home/tong/VM/dpdk [tong@T7] [12:00] > cat start.sh sudo qemu-system-x86_64 -nographic -vnc 127.0.0.1:1 -enable-kvm \ -m 2G -cpu Nehalem -smp cores=2,threads=2,sockets=2 \ -numa node,mem=1G,cpus=0-3,nodeid=0 \ -numa node,mem=1G,cpus=4-7,nodeid=1 \ -drive file=disk.img,if=virtio \ -net nic,vlan=0,model=virtio,macaddr='00:00:00:01:00:00' \ -net nic,vlan=1,model=virtio,macaddr='00:00:00:01:00:01' \ -net nic,vlan=2,model=virtio,macaddr='00:00:00:01:00:02' \ -net tap,vlan=0,ifname=tap-dpdk-ctrl \ -net tap,vlan=1,ifname=tap-dpdk-1,script=no,downscript=no \ -net tap,vlan=2,ifname=tap-dpdk-2,script=no,downscript=no & # -device vfio-pci,host='0000:00:19.0' \ #ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio /home/tong/VM/dpdk [tong@T7] [12:00] >
改完之后:红色部分为关键性修改。
vectors=32 修改了lspci中打印的那个count
mq=on 的修改可以在“ip link”中被查看到,关键字 pfifo_fast 变成了 mq
-netdev 和 -net 是有区别的。-net中包含vlan参数,即使没有显示指定它依然与queues参数相冲突。
vhost=on 并不知道有什么用。不加的话好像也是可以的。
queues=16 会在使用ethtool -l时查看到max为16
/home/tong/VM/dpdk [tong@T7] [18:21] > cat start-multiqueue.sh sudo qemu-system-x86_64 -nographic -vnc 127.0.0.1:1 -enable-kvm \ -m 2G -cpu Nehalem -smp cores=2,threads=2,sockets=2 \ -numa node,mem=1G,cpus=0-3,nodeid=0 \ -numa node,mem=1G,cpus=4-7,nodeid=1 \ -drive file=disk.img,if=virtio \ -net nic,vlan=0,model=virtio,macaddr='00:00:00:01:00:00' \ -device virtio-net-pci,netdev=dev1,mac='00:00:00:01:00:01',vectors=32,mq=on \ -device virtio-net-pci,netdev=dev2,mac='00:00:00:01:00:02',vectors=32,mq=on \ -net tap,vlan=0,ifname=tap-dpdk-ctrl \ -netdev tap,ifname=tap-dpdk-1,script=no,downscript=no,vhost=on,queues=16,id=dev1 \ -netdev tap,ifname=tap-dpdk-2,script=no,downscript=no,vhost=on,queues=16,id=dev2 & # -device vfio-pci,host='0000:00:19.0' \ #ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio
启动之后,生效的queue依然只有1,需要用ethtool修改之。
[root@dpdk ~]# ethtool -L eth2 combined 4 [root@dpdk ~]# ethtool -l eth2 Channel parameters for eth2: Pre-set maximums: RX: 0 TX: 0 Other: 0 Combined: 16 Current hardware settings: RX: 0 TX: 0 Other: 0 Combined: 4
但是在查看中断的时候,并没有变多,而是叫 virtio2-virtqueues 统一由一个中断队列处理。
[root@dpdk ~]# ll /sys/bus/pci/devices/0000\:00\:05.0/msi_irqs/ total 0 -r--r--r--. 1 root root 4096 Dec 6 19:20 31 -r--r--r--. 1 root root 4096 Dec 6 19:20 32 [root@dpdk ~]# cat /proc/interrupts |egrep "31|32" 30: 5631 0 0 0 0 0 0 0 PCI-MSI-edge virtio3-req.0 31: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-config 32: 2 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-virtqueues [root@dpdk ~]#
为啥没变多? 因为写的不太对,查看前文参考的红帽文档可以看见如下内容:
qemu-kvm -netdev tap,id=hn0,queues=M -device virtio-net-pci,netdev=hn0,vectors=2M+2
然后把前文的 vectors=32 改成 vectors=34. 在guest中可以看见中断,一共33 个。
[root@dpdk ~]# cat /proc/interrupts |grep virtio2 62: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-config 63: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.0 64: 1 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.0 65: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.1 66: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.1 67: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.2 68: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.2 69: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.3 70: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.3 71: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.4 72: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.4 73: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.5 74: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.5 75: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.6 76: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.6 77: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.7 78: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.7 79: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.8 80: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.8 81: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.9 82: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.9 83: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.10 84: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.10 85: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.11 86: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.11 87: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.12 88: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.12 89: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.13 90: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.13 91: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.14 92: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.14 93: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-input.15 94: 0 0 0 0 0 0 0 0 PCI-MSI-edge virtio2-output.15
[root@dpdk ~]# ls /sys/bus/pci/devices/0000\:00\:05.0/msi_irqs/ |wc -l
33
[root@dpdk ~]#
最终,QEMU启动命令脚本如下:
/home/tong/VM/dpdk [tong@T7] [19:50] > cat start-multiqueue.sh sudo qemu-system-x86_64 -nographic -vnc 127.0.0.1:1 -enable-kvm \ -m 2G -cpu Nehalem -smp cores=2,threads=2,sockets=2 \ -numa node,mem=1G,cpus=0-3,nodeid=0 \ -numa node,mem=1G,cpus=4-7,nodeid=1 \ -drive file=disk.img,if=virtio \ -net nic,vlan=0,model=virtio,macaddr='00:00:00:01:00:00' \ -device virtio-net-pci,netdev=dev1,mac='00:00:00:01:00:01',vectors=34,mq=on \ -device virtio-net-pci,netdev=dev2,mac='00:00:00:01:00:02',vectors=34,mq=on \ -net tap,vlan=0,ifname=tap-dpdk-ctrl \ -netdev tap,ifname=tap-dpdk-1,script=no,downscript=no,vhost=on,queues=16,id=dev1 \ -netdev tap,ifname=tap-dpdk-2,script=no,downscript=no,vhost=on,queues=16,id=dev2 & # -device vfio-pci,host='0000:00:19.0' \ #ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio /home/tong/VM/dpdk [tong@T7] [19:50] >