电子说
简单地说,SR-IOV是一种让一台主机上的多台虚拟机和主机系统本身合用同一张物理网卡的技术,每台虚拟机都认为自己拥有一张独立的网卡(即一个VF),而其实它们都被骗了~~
由于手上只有一台Linux主机和一张Mellanox ConnectX-4 LX 10G网卡(双物理网口),为了研究SR-IOV,我只能搭建了如下图所示的极简测试环境。这块网卡支持RoCE(RDMA),但在这里只使用它的以太网功能。
对于宿主机的操作系统来说,这块网卡的两个物理网口可以看作两个独立的网卡/网络接口。如果运行ifconfig,可以看到系统中存在enp6s0f0np0和enp6s0f1np1两个网口。
之所以会这样,是因为硬件向系统展现了两个PCIe设备,准确地说是两个功能号。
比如用下面这个命令,可以看到这两个PCIe设备的"bus:slot.func",即"总线号:设备号:功能号"。
$ lspci -D | grep Mellanox
0000:06:00.0 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
0000:06:00.1 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
一旦网卡被插在PCIe插槽上,它的bus和slot就确定了,并且是唯一的。但硬件只要提供两个独立的func,就会被Linux检测为两个独立的PCIe设备,从而对应两个独立的网口。
准备好上述硬件连接和操作系统(Ubuntu 20.04.6)后,我们需要做如下几件事才能使用SR-IOV功能。此处主要的参考文献为《HOWTO CONFIGURE SR-IOV FOR CONNECTX-4/CONNECTX-5/CONNECTX-6 WITH KVM (ETHERNET)》。本文并非操作手册,所以一些网上可以很容易搜到的东西我就不详细说明了。
安装文件为MLNX_OFED_LINUX-5.8-2.0.3.0-ubuntu20.04-x86_64.tgz,需要从NVIDIA网站下载。
如果以后要看代码还需要下载MLNX_OFED_SRC-debian-5.8-2.0.3.0.tgz 。
*sudo mlxconfig -d /dev/mst/mt4117_pciconf0 set SRIOV_EN=1 NUM_OF_VFS=8*
比如运行如下命令,使能4个VF。
echo 4 > /sys/class/net/enp6s0f1np1/device/sriov_numvfs
此时系统中会呈现4个VFs(每个都是一个PCIe设备),分别对应下面的后四行,即0000:06:00.2(后三个数就是"bus:slot.func")、0000:06:00.3、0000:06:00.4和0000:06:00.5。
$ lspci -D | grep Mellanox
0000:06:00.0 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
0000:06:00.1 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
0000:06:01.2 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
0000:06:01.3 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
0000:06:01.4 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
0000:06:01.5 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
这里给一个配置虚拟机的参考图。
此时我们会得到如下图所示的测试环境。
如果我们在虚拟机里把enp6s0的IP设置为192.168.8.1。
然后在宿主机里把两个原有的非VF的系统网口的IP设置为192.168.8.2(enp6s0f0np0)和192.168.8.3(enp6s0f1np1),并把VF3(在宿主机中)对应的网口enp6s0f1v3的IP设置为192.168.8.4。
在虚拟机中是可以ping通上述后三个IP的。
当然在这三种情况下数据走的物理通路是不同的。
按照我浅薄的认识,我认为从虚拟机中ping后面三个IP时,应该对应下图中三条彩色虚线所示的数据通路。
对于不同的物理网口,数据肯定会通过光纤。
对于属于相同物理网口的PF(对应原系统网口)和VFs,我认为网卡硬件中存在一个内部的交换机机制,使得所有PF和VFs之间都可以转发数据包。之所以这样想,是由于做了如下测试:
①在虚拟机中连续地ping 192.168.8.5,这是一个并不存在的地址。
②同时在宿主机上依次用“tcpdump -i enpXXXX”命令监视每个网口,包括未配置IP的VF。
可以发现每个网口都会持续收到ARP报文。如果数据没有经过硬件而是在操作系统内部直接处理掉了,那这么做是完全没必要的,因为系统知道每个网口的IP。并且ifconfig命令输出中也会显示每个网口的RX计数在持续增加,这种计数一般在驱动中实现,而且只有驱动真正从硬件收到包时才会增加计数。
在今后阅读相关驱动代码时我还会关注这一点。欢迎高手来拍砖。
本文只是搭建了一个简单的测试环境,尝试使用SR-IOV功能。接下来我会研究Linux系统和Mellanox驱动中做了哪些事情支持SR-IOV功能,以及猜测需要硬件做哪些工作。
全部0条评论
快来发表一下你的评论吧 !