Single Root IO Virtualization (SR-IOV)

Single Root IO Virtualization (SR-IOV) 是一项允许物理 PCIe 设备通过 PCIe 总线多次呈现自身的技术。该技术支持具有独立资源的设备的多个虚拟实例。NVIDIA 适配器能够为 NVIDIA ConnectX® 系列卡中的每个端口提供多达 127 个虚拟实例(虚拟功能 (VF))。然后可以单独配置这些虚拟功能。每个 VF 都可以视为连接到物理设备。它与物理功能共享相同的资源,并且其端口数量等于物理功能的端口数量。SR
-IOV 通常与启用 SR-IOV 的虚拟机管理程序结合使用,以提供虚拟机对网络资源的直接硬件访问,因此提高其性能。

在本章中,我们将演示使用 ConnectX® VPI 适配器卡在 Red Hat Linux 环境中设置和配置 SR-IOV。

System Requirements

To set up an SR-IOV environment, the following is required:

MLNX_OFED Driver

A server/blade with an SR-IOV-capable motherboard BIOS

Hypervisor that supports SR-IOV such as: Red Hat Enterprise Linux Server Version 6

NVIDIA ConnectX® VPI Adapter Card family with SR-IOV capability

设置SR-IOV

根据您的系统,执行以下步骤来设置 BIOS。本节中使用的图仅用于说明目的。有关更多信息,请参阅相应的 BIOS 用户手册:

  1. 在系统 BIOS 中启用“SR-IOV”。
  2. 怎么将固件中已启用虚拟化变成是_SR_IOV

  3. 启用“英特尔虚拟化技术”。
  4. 怎么将固件中已启用虚拟化变成是_SR_IOV_02

  5. 安装支持 SR-IOV 的虚拟机管理程序。
  6. 根据您的系统,更新 /boot/grub/grub.conf 文件以包含 Linux 内核的类似命令行加载参数。
    例如,对于 Intel 系统,添加:
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Red Hat Enterprise Linux Server (4.x.x)
        root (hd0,0)
        kernel /vmlinuz-4.x.x ro root=/dev/VolGroup00/LogVol00 rhgb quiet
        intel_iommu=on        initrd /initrd-4.x.x.img

注意intel_iommu=on:更新 /boot/grub/grub.conf 文件时请确保参数“ ”存在,否则无法加载 SR-IOV。
某些操作系统使用 /boot/grub2/grub.cfg 文件。如果您的服务器使用此类文件,请改为编辑此文件(intel_iommu=on在以“linux16”开头的行末尾添加相关菜单条目)。

配置 SR-IOV(以太网)

要在以太网模式下设置 SR-IOV,请参阅如何使用 KVM(以太网)为 ConnectX-4/ConnectX-5/ConnectX-6 配置 SR-IOV 社区帖子。

配置 SR-IOV (InfiniBand)

  1. 安装适用于支持 SR-IOV 的 Linux 的 MLNX_OFED 驱动程序。
  2. 检查固件中是否启用了 SR-IOV。
mlxconfig -d /dev/mst/mt4115_pciconf0 q
 
  Device #1:
  ----------
 
  Device type:    Connect4
  PCI device:     /dev/mst/mt4115_pciconf0
  Configurations:          Current
     SRIOV_EN              1
     NUM_OF_VFS            8
如果需要,请使用 mlxconfig 设置相关字段:
mlxconfig -d /dev/mst/mt4115_pciconf0 set SRIOV_EN=1 NUM_OF_VFS=16
  1. 重新启动服务器。
  2. 将需要为 PF 创建的虚拟功能的数量写入 sysfs 文件。您可以使用以下等效文件之一:
    您可以使用以下等效文件之一:
  • 新内核中可用的标准 Linux 内核生成的文件。
echo [num_vfs] > /sys/class/infiniband/mlx5_0/device/sriov_numvfs

注意:仅当在 grub.conf 文件中设置了 IOMMU(通过添加 intel_iommu=on,如“设置 SR-IOV ”下的第四步中所示)时,才会生成此文件。

  • 由 mlx5_core 驱动程序生成的文件,其功能与内核生成的文件相同。
echo [num_vfs] > /sys/class/infiniband/mlx5_0/device/mlx5_num_vfs

注意:该文件由不支持标准文件的旧内核使用。在此类内核中,使用 sriov_numvfs 会导致以下错误:“bash:echo:写入错误:功能未实现”。
写入这些文件时适用以下规则:

  • 如果没有分配 VF,则可以将 VF 数量更改为任何有效值(0 - 在固件刻录期间设置的最大 #VF)
  • 如果为 VM 分配了 VF,则无法更改 VF 的数量
  • 如果管理员在没有分配 VF 的情况下卸载 PF 上的驱动程序,则驱动程序将卸载并且 SRI-OV 将被禁用
  • 如果当 PF 的驱动程序卸载时,有 VF 被分配,SR-IOV 不会被禁用。这意味着 VF 将在 VM 上可见。但是,它们将无法运行。这适用于内核使用 pci_stub 而不是 vfio 的操作系统。
  • VF 驱动程序将发现这种情况并将关闭其资源
  • 当重新加载 PF 上的驱动程序时,VF 即可运行。VF 的管理员需要重新启动驱动程序才能恢复使用 VF。
  1. 加载驱动程序。验证 VF 是否已创建。执行:
lspci | grep Mellanox
08:00.0 Infiniband controller: Mellanox Technologies MT27700 Family [ConnectX-4]
08:00.1 Infiniband controller: Mellanox Technologies MT27700 Family [ConnectX-4]
08:00.2 Infiniband controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
08:00.3 Infiniband controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
08:00.4 Infiniband controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
08:00.5 Infiniband controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
  1. 配置 VF。
    创建 VF 后,每个 VF 在 /sys/class/infiniband/mlx5_/device/sriov 下有 3 个可用的 sysfs 条目(如下所示,针对 VF 0 到 2):
+-- 0
|   +-- node
|   +-- policy
|   +-- port
+-- 1
|   +-- node
|   +-- policy
|   +-- port
+-- 2
    +-- node
    +-- policy
    +-- port

对于每个虚拟功能,可以使用以下文件:

  • 节点 - 节点的 GUID:
    用户可以通过写入 /sys/class/infiniband//device/sriov//node 文件来设置节点 GUID。下面的示例显示如何设置 mlx5_0 的 VF 0 的节点 GUID。
echo 00:11:22:33:44:55:1:0 > /sys/class/infiniband/mlx5_0/device/sriov/0/node
  • 端口 - 端口的 GUID:
    用户可以通过写入 /sys/class/infiniband//device/sriov//port 文件来设置端口 GUID。以下示例显示如何设置 mlx5_0 的 VF 0 的端口 GUID。
echo 00:11:22:33:44:55:2:0 > /sys/class/infiniband/mlx5_0/device/sriov/0/port
  • 策略 - vport 的策略。用户可以通过写入 /sys/class/infiniband//device/sriov//port 文件来设置端口 GUID。该策略可以是以下之一:
  • 向下 - VPort PortState 保持“向下”
  • 向上 - 如果当前 VPort PortState 为“向下”,则将其修改为“初始化”。在所有其他州,它都没有修改。结果是 SM 可能会启动 VPort。
  • Follow - 遵循物理端口的 PortState。如果物理端口的 PortState 为“Active”,则 VPort 实施“Up”策略。否则,VPort PortState 为“Down”。

注意:

  • PF 驱动程序重新启动后,所有 vport 的策略都初始化为“Down”(VPort0 除外,其策略被 PF 驱动程序修改为“Follow”)。
  • 要查看 VF 配置,您必须取消绑定并绑定它们,或者重新启动 VM(如果已分配 VF)。

确保 OpenSM 支持虚拟化(必须启用虚拟化)

/etc/opensm/opensm.conf 文件应包含以下行:

virt_enabled 2

注意:OpenSM 和任何其他使用 SMP MAD 的实用程序(ibnetdiscover、sminfo、iblink-info、smpdump、ibqueryerr、ibdiagnet 和 smpquery)应在 PF 上运行,而不是在 VF 上运行。如果是多个 PF(多主机),OpenSM 应在 Host0 上运行。

VF初始化注意事项

由于同一个 mlx5_core 驱动程序支持物理功能和虚拟功能,因此创建虚拟功能后,PF 的驱动程序将尝试初始化它们,以便拥有 PF 的操作系统可以使用它们。如果要将虚拟功能分配给 VM,则需要确保 PF 驱动程序不使用该 VF。如果使用了VF,则应先将其解绑,然后再分配给VM。

要取消绑定设备,请使用以下命令:

  1. 获取设备的完整 PCI 地址。
lspci -D

例子:

0000:09:00.2
  1. 解绑设备。
echo 0000:09:00.2 > /sys/bus/pci/drivers/mlx5_core/unbind
  1. 绑定未绑定的VF。
echo 0000:09:00.2 > /sys/bus/pci/drivers/mlx5_core/bind

PF和VF的PCI BDF 映射

PF 及其 VF 的 PCI 地址都是连续的。假设该卡的 PCI 插槽为 05:00 并且有 2 个端口,则 PF 的 PCI 地址将为 05:00.0 和 05:00.1。
给定每个 PF 3 个 VF,VF PCI 地址将为:

05:00.2-4 for VFs 0-2 of PF 0 (mlx5_0)
05:00.5-7 for VFs 0-2 of PF 1 (mlx5_1)