1、问题背景
在ARM
(NXP ARM64)平台上搭建了kvm虚拟化平台,测试了原生Linux转发性能(64字节,单口收、单口发),组网如下图所示:1)
、左边NET-TEST
为测试发包仪器;2)
、右边为NXP
的ARM平台;3)
、数据流程为1.1.1.1 ---- > 1.1.1.2 ------ > 1.1.1.3 ------> 2.2.2.3 -----> 2.2.2.2 ------>2.2.2.1
;4)
、虚拟机的I/O
采用vhost模式。
测试组网图根据以上的组网图,对比测试在宿主机和虚拟机的转发性能,结果如下:1)
、宿主机 最大转发性能:14800002)
、虚拟机 最大转发性能:200000
从上面的数据可以看出,在ARM
平台下,虚拟机的转发性能只有宿主机的13%左右,性能劣化差异明显,因此需要定位其劣化根因。2、定位过程
1)
、当使用宿主机准发时,查看宿主机的中断情况,发现收发包过程,宿主机的每个cpu
都有中断,这说明该ARM板子的网卡是一个多队列网卡,网卡的每个队列可以绑定一个cpu核,支持SMP多核并行处理收发包;
宿主机CPU
中断处理情况2)
、进一步通过perf
工具查看宿主机的每个cpu处理情况,从perf数据看,也确实每个cpu核都在处理收发包,如下所示:
宿主机CPU
处理情况3)
、同样的在虚拟机转发场景下,查看虚拟机的vcpu
处理情况时,如下所示:
虚拟机VCPU
处理情况从上面的虚拟机vcpu
处理情况可以看出,在虚拟机转发的时候只有vcpu0在做收发包处理,其余的vcpu核都处于idle状态,也就是说虚拟机转发的时候并没有多核并行处理收发包,这与物理机转发的时候有很大区别,这也是导致虚拟机转发时候性能低的一个很重要原因。4)
、分析KVM vhost
机制
Vhost
原理图如上图为vhost
的基本原理,VM与HOST之间共享一个环形vring buffer,通过共享buffer可以保证报文在VM与HOST之间零拷贝,当tap设备收到报文时,vhost利用irqfd机制,往某个特定的fd文件去write,并触发KVM向VM注入虚拟中断,VM收到虚拟中断后,将报文从vring上取出;当VM需要发送报文时,将报文填充到vring里,然后陷出到KVM,并通过event机制唤醒vhost线程,vhost线程从vring上取出报文,再通过bridge转发到对应的物理口设备上。QEMU
在分配vhost资源的时候,会将fd与virq以及对应的vcpu信息先通告给KVM。当vhost往对应的fd write一个值的时候,触发KVM往VM注入虚拟中断,此时KVM会根据需要注入的vriq号找到对应的vcpu,然后将virq信息写到对应vcpu的lr寄存器里,这样当该vcpu重新回到guest的时候就可以从lr寄存器里获取对应的虚拟中断信息,也就是说当前中断注入的时候只能往一个vcpu里注入,这也应证了之前为什么在VM里只能看到一个vcpu在处理收发报文的情况。 
ARM
设置virq pending状态3、定位结论
从以上的定位过程可以看出,在宿主机转发的时候可以多个cpu
并行处理,但在虚拟机转发的时候只能由单个vcpu核处理,这也是导致虚拟机转发性能这么低的一个很重要原因,当然,应该还存在其它瓶颈点,有待下一步分析。4、优化
multiqueue