概述及问题现象
ping是基础的网络测试命令,很多的网络问题都会体现在ping的测试中,比如网络不可达,网络性能不好导致延时变大等问题。在内部测试的某大规格虚机中要求支持32张网卡,发现偶现虚机ping虚机延时大的问题,如下图:
达到数ms级别,于是开始分析。
vdpa和virtio驱动角度分析原因
首先分析现场环境虚机规格是64核,128G内存,32网卡,1云盘作为系统盘。ping延时出现较为规律大概是10个包左右出现一次延时大的情况,top分析系统负载情况,没有重负载,内存空闲也较多,磁盘io不繁忙。查看dmesg消息发现在virtio pci驱动上面有如下打印:
这个打印看起来是有点异常的,因为我们virtio协议用的1.0,理论上应该是modern driver,但这里出现了回退到legacy driver,这是一个问题点,但是否与问题相关还需要进一步证实,这个打印只有部分的vf设备出现了,那ping延时的情况是不是对应的设备出现? 进一步测试发现确实是一一对应,前面24张网卡没有出现ping延时的问题,后8张网卡都出现了这个打印,并且都出现了ping延时问题,那就需要分析为什么出现这个打印了。
分析驱动代码:
这里可以看到是common cfg的capability的check失败了。更进一步需要分析这里出现分配失败的原因。
这里先分析出现这个回退之后为什么会出现ping延时的问题;这里由于回退了virtio协议,怀疑是在发数据时走了vdpa软件转发,通过在vdpa中加调试代码来验证:
可以在vdpa的log中发现这个打印即出现延时的原因是走了软件转发,这当然是没有直接没有直接走硬件的通知流程快。
下面分析virtio回退到legacy的原因,通过lspci可以看到如图:
ping延时的vf出现了bar4分配失败的情况,我们的硬件设计virtio 的capa 都是在bar 4空间中,这就是出现legacy回退的原因。出现VF bar空间前面分配正常,后面分配失败的原因是在bios预留空间不足。
解决方案
qemu角度解决:
从lscpi可以看出来bar 4分配的空间达到了8M,这个空间如果能够减小则后面可以分配到空间,这个vf设备是通过qemu来提供给VM,分析qemu 的pci设备模拟代码:
这里的几个size就决定了bar空间的大小,可以看到VIRTIO_QUEUE_MAX数量是1024,而我们实际的规格当中网卡的queue最多是32,是远远大于我们所需要的队列数的,将这个值修改减小,我初步是减小到128,经过计算bar只需要2M空间,编译验证发现bar分配成功,ping延时不再出现。
增加预留空间大小:
既然是预留的空间不够,那增大预留的空间即可,pci设备bar空间的预留是在bios中,qemu虚拟机用的bios是seabios,通过修改seabios源码来增加预留大小,这里涉及到seabios的升级,暂未采用这种方式。另一种方式是通过配置cmdline来配置桥预留空间的再分配,在cmdline中增加pci=realloc hpmem=256M ,这样来解决。
这个ping延时的分析解决过程中涉及的virtio驱动,vdpa数据转发流程,pci配置空间的预留和分配等内容。