适用于 mlx5 网卡的 Linux SR-IOV 配置教程
为基于使用 mlx5 驱动的网卡写一个 Linux 上的 SR-IOV 教程,顺带写一点遇到的问题。
mlx5 网卡列表
mlx5 是 mlx5_core
驱动的简称,使用此驱动的网卡主要是 NVIDIA Mellanox ConnectX-4 或者更新的系列,具体应该有下面这些,其中常见网卡型号有:CX4121A、CX542B
- ConnectX-4
- ConnectX-4 Lx
- ConnectX-5
- ConnectX-6
- ConnectX-6 Dx
- ConnectX-7
查看网卡使用的驱动,使用该命令:lspci -nnk | grep -A3 -i eth
开启 SR-IOV
重启设备可能会导致下面的更改被复原。请参考文章后半部分的 固化 章节来持久化配置。
先使用 lspci | grep Mellanox
查找网卡的 PCI 设备位置
1 |
|
以上是插入了 2 块 CX6 网卡、每块网卡有 2 个网络接口的典型输出。通过 PCI 设备 ID 可看出前两个、后两个设备都分别是同一张网卡的不同接口。
然后我们使用下面的命令来开启 SR-IOV:
1 |
|
将 4 替换为你需要的 SR-IOV VF 数量,然后将 0000\:01\:00.0 替换为网卡接口的 PCI 位置(这里通常可以用 Tab 补全)
有多个网卡或接口时,对每个接口分别设置。
若要撤销更改(删除 SR-IOV 设备),将 VF 数量设为 0。
执行这条命令时卡了很久?
此命令执行耗时一般不会太长(每个 VF 大约需要不到 1 秒来配置),但是在少数机器上,此命令可能需要几分钟甚至几个小时才能完成,且执行完成后部分 VF 不能正常使用。
此故障一般是主板问题导致:你的设备不完整支持 ARI,后期我会单独写一篇文章解释。
解决方案:确保每张网卡(不是每个端口)的 VF 数不超过 6,或者换个主板
PCI 设备路径
开始之前,先普及一下 PCI 设备路径的组成(如果你已经有了此部分知识,跳过本章):
PCI 设备路径(也有 PCI 位置 或者类似的称呼)类似 0000:01:00.0
,是由冒号分隔的十六进制数,每一段的含义是:
1 |
|
具体的:
- Domain(域):
多数系统只有一个 domain 即 0000(例外一般是虚拟机),用于支持大型系统或多个 PCI host bridge。 - Bus Number(总线):
PCI 总线的编号,主板上的每个 PCI 控制器或桥接芯片可能生成一个或多个总线。 - Device Number(设备):
该总线上的设备编号(通常为 0~31),一个总线最多可挂载 32 个设备。 - Function Number(功能):
该设备的功能号(0~7),一个设备最多支持 8 个功能。
其中 domain 有时可以省略(指代默认的 0000),function 有时也可以省略(指代该设备的全部 function)
VF 的 PCI 位置
此章节只有演示讲解,你不需要执行任何查询信息以外的命令
为了方便解释,本节展示使用 1 张双接口网卡(两个 PF),对每个接口开启 4 个 VF 进行 SR-IOV 的配置。
为两个 PF 分别创建 4 个 VF:
1 |
|
创建后重新使用 lspci | grep Mellanox
查找网卡的 PCI 设备位置
1 |
|
可以看到 VF 已经成功创建(01:00.2
到 01:01.1
)。
由于 PCI 每个设备只能拥有 8 个功能,PCIe 3.0 引入了 ARI 技术,原理大体上是将设备和功能合并到一起,功能数量从 8 个扩展到 256 个。
使用 ARI 后,01:00.0
网卡创建的第 9 个功能路径会显示为 01:01.0
(功能号满 8 就对设备号进位)
由于上面我们先对端口 0 设置 4 个 VF,然后再是端口 1,所以按顺序:01:00.2
到 01:00.5
是端口 0 的 VF,其余则是端口 1 的 VF。VF 设备路径的顺序取决于创建 VF 时命令执行顺序。
SR-IOV 下的网卡名
默认规则产生的网卡名会比较长,如果你觉得有必要,可以自己设置个网卡命名规则(具体方法后续补充在这里)。
默认规则下:
- PF
一般命名类似enp1s0f0np0
p[PCI Bus ID]s[PCI Device ID]f[PCI Function ID]n[pX]
n 后面(pX)是网卡驱动提供的网卡名字段,从 0 开始 - VF
一般命名类似enp1s0f0npf0vf1
p[PCI Bus ID]s[PF PCI Device ID]f[PF PCI Function ID]n[pfXvfY]
前面使用 PF 的 ID,n 后面(pfXvfY)同样是网卡驱动提供的网卡名字段,从 0 开始
为 VF 设置 MAC 地址
重启设备可能会导致下面的更改被复原。请参考文章后半部分的 固化 章节来持久化配置。
- 如果该 VF 需要直接在宿主机使用,或者用于容器如 LXC,使用该命令:
ip link set dev <VF 网卡名> address AA:BB:CC:DD:EE:FF
执行此命令需要确保 VF 已经加载驱动(默认已加载) - 如果该 VF 用于 QEMU 虚拟机(包括 KVM、Proxmox 等),使用该命令:
ip link set <PF 网卡名> vf <VF ID> AA:BB:CC:DD:EE:FF
VF ID 即该 PF 上的第 n 个 VF,从 0 开始
如果已加载驱动,重新加载驱动后才能在宿主机生效(虚拟机上使用不需要关心这个)
配置 E-Switch 分载
ConnectX-5 或更新的网卡支持 E-Switch 分载功能,可以部分改善 PF-VF 的交换性能并降低占用,并解决部分情况下宿主机 VF 无法和虚拟机 VF 正常通信的问题,可以按下面的方法开启 E-Switch 分载:
重启设备可能会导致下面的更改被复原。请参考文章后半部分的 固化 章节来持久化配置。
已知问题
开启 E-Switch 分载会导致 FreeBSD 无法加载 VF 网卡驱动。
目前未找到解决方案。
1 |
|
替换 0000:01:00.0 为实际 PF 的设备路径。
若要撤销更改,将 switchdev 替换为 legacy 执行。
执行前,请确保没有 VF 正在使用,否则卸载 VF 时会报错。建议在创建 VF 之前就执行此操作。
配合 OpenVSwitch(OvS) 使用时,建议执行:
重启设备不会导致下面的更改被复原。该命令不需要固化。
1 |
|
若要撤销更改,使用:
1 |
|
Proxmox VE 中 VM 添加 SR-IOV 网卡
1 |
|
VMID 替换为虚拟机的 ID,hostpci0 中的 0 替换为虚拟机内 PCI 设备位置(没有什么具体要求,数字不冲突即可),0000:01:00.2 替换为 VF 的 PCI 位置。
也可以通过网页后台来配置:
Proxmox VE 中 LXC 添加 SR-IOV 网卡
1 |
|
name
字段请随意设置,此参数在使用 SR-IOV 时是个摆设(如果需要设置 LXC 内的网卡名,请直接在宿主机修改 VF 网卡名);link
设置为 VF 的网卡名
如果 LXC 内添加了其他网络接口(无论是否是 SR-IOV),请注意 net 后的编号不要冲突
固化
在 /opt/local-sriov/init.sh
或者你喜欢的地方创建一个脚本:
1 |
|
根据实际情况,自行修改脚本中的参数。
chmod +x /opt/local-sriov/init.sh
,然后确保此脚本在接口启动时执行。
以 ifupdown(2/ng)
为例,修改 /etc/network/interfaces
:
1 |
|