DOCA Virtio-net 服务指南
本指南提供关于如何在 NVIDIA® BlueField®-3 网络平台之上使用 DOCA virtio-net 服务容器的说明。
NVIDIA® BlueField® virtio-net 使用户能够在连接 BlueField 的系统中创建 virtio-net PCIe 设备。在传统的虚拟化环境中,virtio-net 设备可以由 hypervisor 中的 QEMU 模拟,或者将部分工作(例如,数据平面)卸载到网卡(例如,vDPA)。与这些解决方案相比,virtio-net PCIe 设备将数据和控制平面都卸载到 BlueField 网络设备。暴露给 hypervisor 的 PCIe virtio-net 设备不依赖于 QEMU 或来自 guest OS 的其他软件模拟器/供应商驱动程序。
该解决方案基于 BlueField 系列技术,构建于虚拟交换机和 OVS 之上,因此 virtio-net 设备可以受益于完整的 SDN 和硬件卸载方法。

Virtio-net-controller 是一个 systemd
服务,它在 BlueField 上运行,并带有一个命令行界面 (CLI) 前端,用于与在后台运行的服务进行通信。控制器 systemd
服务默认启用,并在部署某些固件配置后自动运行。
有关更多信息,请参阅“Virtio-net 部署”。
创建进程 virtio_net_emu
和 virtio_net_ha
以管理实时更新和高可用性。

更新 BlueField 上的操作系统镜像
要在 NVIDIA® BlueField® 上安装 BFB 捆绑包,请从 Linux hypervisor 运行以下命令
[host]# sudo bfb-install --rshim <rshimN> --bfb <image_path.bfb>
有关更多信息,请参阅NVIDIA BlueField DPU BSP 文档中“从主机使用 BFB 部署 BlueField 软件”部分。
更新网卡固件
从 BlueField 网络平台运行
[dpu]# sudo /opt/mellanox/mlnx-fw-updater/mlnx_fw_updater.pl --force-fw-update
有关更多信息,请参阅NVIDIA DOCA Linux 安装指南中的“升级固件”部分。
配置网卡固件
默认情况下,DPU 应配置为 DPU 模式。确认 DPU 在 DPU 模式下运行的简单方法是登录到 BlueField Arm 系统,并检查是否通过运行以下命令存在 p0
和 pf0hpf
。
[dpu]# ip link show
Virtio-net 完全模拟仅在 DPU 模式下工作。有关 DPU 模式配置的更多信息,请参阅BlueField 操作模式。
在启用 virtio-net 服务之前,需要通过 mlxconfig
工具配置固件。下表列出了典型配置示例和相关的 mlxconfig
条目描述。
要使 mlxconfig
配置更改生效,请执行BlueField 系统级重置。
Mlxconfig 条目 | 描述 |
| 必须设置为 |
| 设备为 virtio-net 模拟暴露的 PCIe 功能 (PF) 总数。这些功能在主机/BlueField 电源周期中保持不变。 |
| 每个 virtio-net PF 可以支持的最大虚拟功能 (VF) 数量 |
| 为 virtio-net 模拟设备的每个 PF 分配的 MSI-X 向量数,最小为 |
| 为 virtio-net 模拟设备的每个 VF 分配的 MSI-X 向量数,最小为 |
| 当 |
| 模拟交换机端口的最大数量。每个端口可以容纳单个 PCIe 设备(模拟与否)。这决定了支持的最大热插拔 virtio-net 设备数量。最大数量取决于 hypervisor PCIe 资源,并且不能超过 31。 注意
检查系统 PCIe 资源。将此条目更改为较大的数字可能会导致主机无法启动,这将需要禁用 BlueField 设备并清除主机 NVRAM。 |
| 当 |
| 当前 PF 可以支持的可扩展功能 (SF) 分区总数。仅当 注意
此条目在 BlueField 和主机侧 |
| 单个 SF 的 BAR 大小的对数(以 2 为底),以 KB 为单位。仅当 |
| 当 |
| 为 virtio-net 和原生 PF 启用单根 I/O 虚拟化 (SR-IOV) |
| 为 virtio-net 功能启用 PXE 的扩展 ROM 选项 注意
所有 virtio |
| 为基于 Arm 的主机上的 virtio-net 功能启用 UEFI 的扩展 ROM 选项 |
| 为基于 x86 的主机上的 virtio-net 功能启用 UEFI 的扩展 ROM 选项 |
支持的最大设备数量如下所示。当同时创建热插拔和 VF 时,此项不适用。
静态 PF | 热插拔 PF | VF |
31 | 31 | 1008 |
支持的最大热插拔 PF 数量取决于主机 PCI 资源,在特定系统上可能支持较少或不支持。请参阅主机 BIOS 规范。
静态 PF
静态 PF 定义为即使在 DPU 或主机断电重启后仍然存在的 virtio-net PF。它还支持创建 SR-IOV VF。
以下是仅启用 4 个静态 PF (VIRTIO_NET_EMULATION_NUM_PF
) 的系统的示例
保留 10 个 SF (PF_TOTAL_SF
) 以考虑使用 SF 的其他应用程序。
[dpu]# mlxconfig -d 03:00.0 s \
VIRTIO_NET_EMULATION_ENABLE=1 \
VIRTIO_NET_EMULATION_NUM_PF=4 \
VIRTIO_NET_EMULATION_NUM_VF=0 \
VIRTIO_NET_EMULATION_NUM_MSIX=64 \
PCI_SWITCH_EMULATION_ENABLE=0 \
PCI_SWITCH_EMULATION_NUM_PORT=0 \
PER_PF_NUM_SF=1 \
PF_TOTAL_SF=64 \
PF_BAR2_ENABLE=0 \
PF_SF_BAR_SIZE=8 \
SRIOV_EN=0
热插拔 PF
热插拔 PF 定义为可以在系统启动后动态热插拔或拔出的 virtio-net PF。
热插拔 PF 不支持创建 SR-IOV VF。
以下是启用 16 个热插拔 PF (PCI_SWITCH_EMULATION_NUM_PORT
) 的示例
[dpu]# mlxconfig -d 03:00.0 s \
VIRTIO_NET_EMULATION_ENABLE=1 \
VIRTIO_NET_EMULATION_NUM_PF=0 \
VIRTIO_NET_EMULATION_NUM_VF=0 \
VIRTIO_NET_EMULATION_NUM_MSIX=64 \
PCI_SWITCH_EMULATION_ENABLE=1 \
PCI_SWITCH_EMULATION_NUM_PORT=16 \
PER_PF_NUM_SF=1 \
PF_TOTAL_SF=64 \
PF_BAR2_ENABLE=0 \
PF_SF_BAR_SIZE=8 \
SRIOV_EN=0
SR-IOV VF
SR-IOV VF 定义为在 PF 之上创建的 virtio-net VF。每个 VF 获得一个单独的 virtio-net PCIe 设备。
VF 无法动态创建或销毁,它们只能从 X 更改为 0,或从 0 更改为 X。
当重启主机或从 virtio-net 内核驱动程序取消绑定 PF 时,VF 将被销毁。
以下是为每个静态 PF 启用 126 个 VF 的示例—总共 504 个 (4 PF x 126) VF
[dpu]# mlxconfig -d 03:00.0 s \
VIRTIO_NET_EMULATION_ENABLE=1 \
VIRTIO_NET_EMULATION_NUM_PF=4 \
VIRTIO_NET_EMULATION_NUM_VF=126 \
VIRTIO_NET_EMULATION_NUM_MSIX=64 \
VIRTIO_NET_EMULATION_NUM_VF_MSIX=64 \
PCI_SWITCH_EMULATION_ENABLE=0 \
PCI_SWITCH_EMULATION_NUM_PORT=0 \
PER_PF_NUM_SF=1 \
PF_TOTAL_SF=512 \
PF_BAR2_ENABLE=0 \
PF_SF_BAR_SIZE=8 \
NUM_VF_MSIX=0 \
SRIOV_EN=1
PF/VF 组合
支持同时创建静态/热插拔 PF 和 VF。
到外部主机的 PCIe 功能总和不得超过 256。例如
如果有 2 个没有 VF 的 PF (
NUM_OF_VFS=0
) 并且有 1 个 RShim,则剩余的静态功能为 253 (256-3)。如果配置了 1 个 virtio-net PF (
VIRTIO_NET_EMULATION_NUM_PF=1)
,则最多可以配置 252 个 virtio-net VF (VIRTIO_NET_EMULATION_NUM_VF=252
)如果配置了 2 个 virtio-net PF (
VIRTIO_NET_EMULATION_NUM_PF=2
),则最多可以配置 125 个 virtio-net VF (VIRTIO_NET_EMULATION_NUM_VF=125
)
以下是启用 15 个热插拔 PF、2 个静态 PF 和 200 个 VF (2 PF x 100) 的示例
[dpu]# mlxconfig -d 03:00.0 s \
VIRTIO_NET_EMULATION_ENABLE=1 \
VIRTIO_NET_EMULATION_NUM_PF=2 \
VIRTIO_NET_EMULATION_NUM_VF=100 \
VIRTIO_NET_EMULATION_NUM_MSIX=10 \
VIRTIO_NET_EMULATION_NUM_VF_MSIX=64 \
PCI_SWITCH_EMULATION_ENABLE=1 \
PCI_SWITCH_EMULATION_NUM_PORT=15 \
PER_PF_NUM_SF=1 \
PF_TOTAL_SF=256 \
PF_BAR2_ENABLE=0 \
PF_SF_BAR_SIZE=8 \
NUM_VF_MSIX=0 \
SRIOV_EN=1
在热插拔 virtio-net PF 和 virtio-net SR-IOV VF 设置中,最多支持 15 个热插拔设备。
系统配置
主机系统配置
对于热插拔设备配置,建议修改 hypervisor 操作系统内核启动参数并添加以下选项
pci=realloc
对于 SR-IOV 配置,首先从主机启用 SR-IOV。
请参阅 MLNX_OFED 文档中的 Features Overview and Configuration > Virtualization > Single Root IO Virtualization (SR-IOV) > Setting Up SR-IOV,以获取有关如何执行此操作的说明。
确保将以下选项添加到 Linux 启动参数。
intel_iommu=on iommu=pt
当创建超过 127 个 VF 时,将 pci=assign-busses
添加到启动命令行。如果没有此选项,可能会从主机触发以下错误,并且 virtio 驱动程序将不会探测这些设备。
pci 0000:84:00.0: [1af4:1041] type 7f class 0xffffff
pci 0000:84:00.0: unknown header type 7f, ignoring device
由于来自 BlueField 侧的控制器提供硬件资源并确认 (ACK) 来自主机 virtio-net 驱动程序的请求,因此必须先重启主机操作系统(或卸载 virtio-net 驱动程序),然后再重启 BlueField。这也适用于从 BlueField 平台重新配置控制器(例如,重新配置 LAG)。建议从主机操作系统侧卸载 virtio-net 驱动程序。
BlueField 系统配置
Virtio-net 完全模拟基于 ASAP^2。对于从主机侧创建的每个 virtio-net 设备,都会创建一个 SF representor 来表示来自 BlueField 侧的设备。必须使 SF representor 与上行链路 representor 位于同一个 OVS 网桥中。
SF representor 名称以固定模式设计,以映射不同类型的设备。
静态 PF | 热插拔 PF | SR-IOV VF | |
SF 范围 | 1000-1999 | 2000-2999 | 3000 及以上 |
例如,第一个静态 PF 获取 en3f0pf0sf1000
的 SF representor,第二个热插拔 PF 获取 en3f0pf0sf2001
的 SF representor。建议从 virtnet list
的输出中的 sf_rep_net_device
字段验证 SF representor 的名称。
[dpu]# virtnet list
{
...
"devices": [
{
"pf_id": 0,
"function_type": "static PF",
"transitional": 0,
"vuid": "MT2151X03152VNETS0D0F2",
"pci_bdf": "14:00.2",
"pci_vhca_id": "0x2",
"pci_max_vfs": "0",
"enabled_vfs": "0",
"msix_num_pool_size": 0,
"min_msix_num": 0,
"max_msix_num": 32,
"min_num_of_qp": 0,
"max_num_of_qp": 15,
"qp_pool_size": 0,
"num_msix": "64",
"num_queues": "8",
"enabled_queues": "7",
"max_queue_size": "256",
"msix_config_vector": "0x0",
"mac": "D6:67:E7:09:47:D5",
"link_status": "1",
"max_queue_pairs": "3",
"mtu": "1500",
"speed": "25000",
"rss_max_key_size": "0",
"supported_hash_types": "0x0",
"ctrl_mac": "D6:67:E7:09:47:D5",
"ctrl_mq": "3",
"sf_num": 1000,
"sf_parent_device": "mlx5_0",
"sf_parent_device_pci_addr": "0000:03:00.0",
"sf_rep_net_device": "en3f0pf0sf1000",
"sf_rep_net_ifindex": 15,
"sf_rdma_device": "mlx5_4",
"sf_cross_mkey": "0x18A42",
"sf_vhca_id": "0x8C",
"sf_rqt_num": "0x0",
"aarfs": "disabled",
"dim": "disabled"
}
]
}
找到 SF representor 名称后,将其添加到相应上行链路 representor 的同一 OVS 网桥,并确保 SF representor 处于启动状态
[dpu]# ovs-vsctl show
f2c431e5-f8df-4f37-95ce-aa0c7da738e0
Bridge ovsbr1
Port ovsbr1
Interface ovsbr1
type: internal
Port en3f0pf0sf0
Interface en3f0pf0sf0
Port p0
Interface p0
[dpu]# ovs-vsctl add-port ovsbr1 en3f0pf0sf1000
[dpu]# ovs-vsctl show
f2c431e5-f8df-4f37-95ce-aa0c7da738e0
Bridge ovsbr1
Port ovsbr1
Interface ovsbr1
type: internal
Port en3f0pf0sf0
Interface en3f0pf0sf0
Port en3f0pf0sf1000
Interface en3f0pf0sf1000
Port p0
Interface p0
[dpu]# ip link set dev en3f0pf0sf1000 up
用法
在固件/系统配置和系统断电重启后,virtio-net 设备应准备好部署。
首先,通过发出以下命令确保 mlxconfig
选项正确生效
输出有一个包含 3 列的列表:default
配置、current
配置和 next-boot
配置。验证第 2 列下的值是否与预期配置匹配。
[dpu]# mlxconfig -d 03:00.0 -e q | grep -i \*
* PER_PF_NUM_SF False(0) True(1) True(1)
* NUM_OF_VFS 16 0 0
* PF_BAR2_ENABLE True(1) False(0) False(0)
* PCI_SWITCH_EMULATION_NUM_PORT 0 8 8
* PCI_SWITCH_EMULATION_ENABLE False(0) True(1) True(1)
* VIRTIO_NET_EMULATION_ENABLE False(0) True(1) True(1)
* VIRTIO_NET_EMULATION_NUM_VF 0 126 126
* VIRTIO_NET_EMULATION_NUM_PF 0 1 1
* VIRTIO_NET_EMULATION_NUM_MSIX 2 64 64
* VIRTIO_NET_EMULATION_NUM_VF_MSIX 0 64 64
* PF_TOTAL_SF 0 508 508
* PF_SF_BAR_SIZE 0 8 8
如果系统配置正确,则 virtio-net-controller 服务应已启动并正在运行。如果该服务未显示为活动状态,请仔细检查上述固件/系统配置。
[dpu]# systemctl status virtio-net-controller.service
● virtio-net-controller.service - Nvidia VirtIO Net Controller Daemon
Loaded: loaded (/etc/systemd/system/virtio-net-controller.service; enabled; vendor preset: disabled)
Active: active (running)
Docs: file:/opt/mellanox/mlnx_virtnet/README.md
Main PID: 30715 (virtio_net_cont)
Tasks: 55
Memory: 11.7M
CGroup: /system.slice/virtio-net-controller.service
├─30715 /usr/sbin/virtio_net_controller
├─30859 virtio_net_emu
└─30860 virtio_net_ha
要重新加载或重启服务,请运行
[dpu]# systemctl restart virtio-net-controller.service
当对 virtio-net-controller 服务使用“强制终止”(即,kill -9
或 kill -SIGKILL
)时,用户应使用 kill -9 -<virtio_net_controller 进程的 pid,即上例中的 30715>
(注意 pid
之前的短划线“-
”)。
热插拔 PF 设备
创建 PF 设备
要创建热插拔 virtio-net 设备,请运行
[dpu]# virtnet hotplug -i mlx5_0 -f 0x0 -m 0C:C4:7A:FF:22:93 -t 1500 -n 3 -s 1024
信息有关完整用法,请参阅“Virtnet CLI 命令”。
此命令创建一个热插拔 virtio-net 设备,其 MAC 地址为
0C:C4:7A:FF:22:93
,MTU 为 1500,以及 3 个 virtio 队列,队列深度为 1024 个条目。该设备在mlx5_0
的物理端口上创建。该设备通过其索引唯一标识。此索引用于查询和更新设备属性。如果设备创建成功,则会显示类似于以下内容的输出{ "bdf": "15:00.0", "vuid": "MT2151X03152VNETS1D0F0", "id": 0, "transitional": 0, "sf_rep_net_device": "en3f0pf0sf2000", "mac": "0C:C4:7A:FF:22:93", "errno": 0, "errstr": "Success" }
将设备的 representor 端口添加到 OVS 网桥并启动它。运行
[dpu]# ovs-vsctl add-port <bridge> en3f0pf0sf2000 [dpu]# ip link set dev en3f0pf0sf2000 up
完成步骤 1-2 后,virtio-net PCIe 设备应可从 hypervisor 操作系统获得,并具有相同的 PCIe BDF。
[host]# lspci | grep -i virtio 15:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
探测 virtio-net 驱动程序(例如,内核驱动程序)
[host]# modprobe -v virtio-pci && modprobe -v virtio-net
应创建 virtio-net 设备。有两种方法可以定位网络设备
从主机侧检查 dmesg 以查找相应的 PCIe BDF
[host]# dmesg | tail -20 | grep 15:00.0 -A 10 | grep virtio_net [3908051.494493] virtio_net virtio2 ens2f0: renamed from eth0
检查所有网络设备并找到相应的 MAC 地址
[host]# ip link show | grep -i "0c:c4:7a:ff:22:93" -B 1 31: ens2f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 link/ether 0c:c4:7a:ff:22:93 brd ff:ff:ff:ff:ff:ff
检查探测到的驱动程序及其 BDF 是否与热插拔设备的输出匹配
[host]# ethtool -i ens2f0 driver: virtio_net version: 1.0.0 firmware-version: expansion-rom-version: bus-info: 0000:15:00.0 supports-statistics: yes supports-test: no supports-eeprom-access: no supports-register-dump: no supports-priv-flags: no
现在,热插拔 virtio-net 设备已准备好用作通用网络设备。
销毁 PF 设备
要热拔出 virtio-net 设备,请运行
[dpu]# virtnet unplug -p 0
{'id': '0x1'}
{
"errno": 0,
"errstr": "Success"
}
热插拔设备及其 representor 将被销毁。
SR-IOV VF 设备
创建 SR-IOV VF 设备
在配置固件和 BlueField/主机系统并完成正确的配置后,用户可以创建 SR-IOV VF。
以下过程提供了一个在静态 PF 之上创建一个 VF 的示例
定位暴露给主机侧的 virtio-net PF
[host]# lspci | grep -i virtio 14:00.2 Network controller: Red Hat, Inc. Virtio network device
验证 PCIe BDF 是否与来自 BlueField 侧的后端设备匹配
[dpu]# virtnet list { ... "devices": [ { "pf_id": 0, "function_type": "static PF", "transitional": 0, "vuid": "MT2151X03152VNETS0D0F2", "pci_bdf": "14:00.2", "pci_vhca_id": "0x2", "pci_max_vfs": "0", "enabled_vfs": "0", "msix_num_pool_size": 0, "min_msix_num": 0, "max_msix_num": 32, "min_num_of_qp": 0, "max_num_of_qp": 15, "qp_pool_size": 0, "num_msix": "64", "num_queues": "8", "enabled_queues": "7", "max_queue_size": "256", "msix_config_vector": "0x0", "mac": "D6:67:E7:09:47:D5", "link_status": "1", "max_queue_pairs": "3", "mtu": "1500", "speed": "25000", "rss_max_key_size": "0", "supported_hash_types": "0x0", "ctrl_mac": "D6:67:E7:09:47:D5", "ctrl_mq": "3", "sf_num": 1000, "sf_parent_device": "mlx5_0", "sf_parent_device_pci_addr": "0000:03:00.0", "sf_rep_net_device": "en3f0pf0sf1000", "sf_rep_net_ifindex": 15, "sf_rdma_device": "mlx5_4", "sf_cross_mkey": "0x18A42", "sf_vhca_id": "0x8C", "sf_rqt_num": "0x0", "aarfs": "disabled", "dim": "disabled" } ] }
从主机探测
virtio_pci
和virtio_net
模块[host]# modprobe -v virtio-pci && modprobe -v virtio-net
应创建 PF 网络设备。
[host]# ip link show | grep -i "4A:82:E3:2E:96:AB" -B 1 21: ens2f2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 4a:82:e3:2e:96:ab brd ff:ff:ff:ff:ff:ff
MAC 地址和 PCIe BDF 应在 BlueField 侧 (
virtnet list
) 和主机侧 (ethtool
) 之间匹配。[host]# ethtool -i ens2f2 driver: virtio_net version: 1.0.0 firmware-version: expansion-rom-version: bus-info: 0000:14:00.2 supports-statistics: yes supports-test: no supports-eeprom-access: no supports-register-dump: no supports-priv-flags: no
要在主机上创建 SR-IOV VF 设备,请使用 PF PCIe BDF (
0000:14:00.2
在此示例中) 运行以下命令[host]# echo 1 > /sys/bus/pci/drivers/virtio-pci/0000\:14\:00.2/sriov_numvfs
从主机创建了 1 个额外的 virtio-net 设备
[host]# lspci | grep -i virtio 14:00.2 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01) 14:00.4 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
BlueField 侧也从
virtnet list
显示 VF 信息[dpu]# virtnet list ... { "vf_id": 0, "parent_pf_id": 0, "function_type": "VF", "transitional": 0, "vuid": "MT2151X03152VNETS0D0F2VF1", "pci_bdf": "14:00.4", "pci_vhca_id": "0xD", "pci_max_vfs": "0", "enabled_vfs": "0", "num_msix": "12", "num_queues": "8", "enabled_queues": "7", "max_queue_size": "256", "msix_config_vector": "0x0", "mac": "16:FF:A2:6E:6D:A9", "link_status": "1", "max_queue_pairs": "3", "mtu": "1500", "speed": "25000", "rss_max_key_size": "0", "supported_hash_types": "0x0", "ctrl_mac": "16:FF:A2:6E:6D:A9", "ctrl_mq": "3", "sf_num": 3000, "sf_parent_device": "mlx5_0", "sf_parent_device_pci_addr": "0000:03:00.0", "sf_rep_net_device": "en3f0pf0sf3000", "sf_rep_net_ifindex": 18, "sf_rdma_device": "mlx5_5", "sf_cross_mkey": "0x58A42", "sf_vhca_id": "0x8D", "sf_rqt_num": "0x0", "aarfs": "disabled", "dim": "disabled" }
将相应的 SF representor 添加到 OVS 网桥,作为 virtio-net PF 并启动它。运行
[dpu]# ovs-vsctl add-port <bridge> en3f0pf0sf3000 [dpu]# ip link set dev en3f0pf0sf3000 up
现在,VF 可以正常工作了。
从主机侧启用 SR-IOV 需要几分钟时间。例如,创建 504 个 VF 可能需要 5 分钟。
建议在创建 VF 之前禁用 VF 自动探测。
[host]# echo 0 > /sys/bus/pci/drivers/virtio-pci/<virtio_pf_bdf>/sriov_drivers_autoprobe
[host]# echo <num_vfs> > /sys/bus/pci/drivers/virtio-pci/<virtio_pf_bdf>/sriov_numvfs
用户可以在完成后直接将 VF 直通到 VM。如果需要在 hypervisor 操作系统内部使用 VF,请绑定 VF PCIe BDF
[host]# echo <virtio_vf_bdf> > /sys/bus/pci/drivers/virtio-pci/bind
请记住重新启用自动探测以用于其他用例
[host]# echo 1 > /sys/bus/pci/drivers/virtio-pci/<virtio_pf_bdf>/sriov_drivers_autoprobe
在不同线程上为同一 PF 创建 VF 可能会导致 hypervisor 操作系统挂起。
销毁 SR-IOV VF 设备
要在主机上销毁 SR-IOV VF 设备,请运行
[host]# echo 0 > /sys/bus/pci/drivers/virtio-pci/<virtio_pf_bdf>/sriov_numvfs
当 echo 命令从主机操作系统返回时,并不一定意味着 BlueField 侧已完成其操作。要验证 BlueField 是否完成,并且可以安全地重新创建 VF,请执行以下操作之一
检查 BlueField 中的控制器日志,并确保您看到类似于以下的日志条目
[dpu]# journalctl -u virtio-net-controller.service -n 3 -f virtio-net-controller[5602]: [INFO] virtnet.c:675:virtnet_device_vfs_unload: static PF[0], Unload (1) VFs finished
从 BlueField 侧查询最后一个 VF
[dpu]# virtnet query -p 0 -v 0 -b {'all': '0x0', 'vf': '0x0', 'pf': '0x0', 'dbg_stats': '0x0', 'brief': '0x1', 'latency_stats': '0x0', 'stats_clear': '0x0'} { "Error": "Device doesn't exist" }
销毁 VF 后,从 BlueField 侧为 virtio-net 创建的 SF 不会被销毁,而是保存到 SF 池中以供以后重用。
不支持在为热插拔或 VF 执行设备创建/销毁时重启 virtio-net-controller 服务。
将 Virtio-net 设备分配给虚拟机
所有 virtio-net 设备(静态/热插拔 PF 和 VF)都支持 PCIe 直通到 VM。PCIe 直通允许设备在 VM 中获得更好的性能。
可以通过 virt-manager
或 virsh command
将 virtio-net 设备分配给 VM。
定位 Virtio-net 设备
所有 virtio-net 设备都可以由 hypervisor 操作系统中的 PCIe 子系统扫描,并显示为标准 PCIe 设备。运行以下命令以定位 virtio-net 设备及其 PCIe BDF。
[host]# lspci | grep 'Virtio network'
00:09.1 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
使用 virt-manager
启动 virt-manager
,运行以下命令
[host]# virt-manager
确保您的系统已启用 xterm 以显示 virt-manager GUI。
双击虚拟机并打开其属性。导航到详细信息 → 添加硬件 → PCIe 主机设备。

根据 virtio-net 设备虚拟功能的 PCIe 设备(例如,00:09.1)选择一个,重启或启动 VM。
使用 virsh 命令
运行以下命令以获取 VM 列表,并按
Name
字段选择目标 VM[host]# virsh list --all Id Name State ---------------------------------------------- 1 host-101-CentOS-8.5 running
编辑 VM 的 XML 文件,运行
[host]# virsh edit <VM_NAME>
使用
vfio
作为驱动程序,将目标 virtio-net 设备 PCIe BDF 分配给 VM,将BUS/SLOT/FUNCTION/BUS_IN_VM/SLOT_IN_VM/FUNCTION_IN_VM
替换为相应的设置。<
hostdev
mode
='subsystem'
type
='pci'
managed
='no'
> <driver
name
='vfio'
/> <source
> <address
domain
='0x0000'
bus='<#BUS>' slot='<#SLOT>' function='<#FUNCTION>'/> </source
> <address
type
='pci'
domain
='0x0000'
bus='<#BUS_IN_VM>' slot='<#SLOT_IN_VM>' function='<#FUNCTION_IN_VM>'/> </hostdev
>例如,将目标设备
00.09.1
分配给 VM,并且其在 VM 中的 PCIe BDF 为01:00.0
<hostdev mode=
'subsystem'
type='pci'
managed='no'
> <driver name='vfio'
/> <source> <address domain='0x0000'
bus='0x00'
slot='0x09'
function='0x1'
/> </source> <address type='pci'
domain='0x0000'
bus='0x01'
slot='0x00'
function='0x0'
/> </hostdev>如果 VM 已经启动,则销毁它
[host]# virsh destory <VM_NAME>
使用新的 XML 配置启动 VM
[host]# virsh start <VM_NAME>
配置文件选项
控制器服务有一个可选的 JSON 格式配置文件,允许用户自定义多个参数。配置文件应在 DPU 上定义,路径为 /opt/mellanox/mlnx_virtnet/virtnet.conf
。每次控制器启动时都会读取此文件。
当配置文件发生更改时,应重启控制器 systemd
服务。不支持动态更改 virtnet.conf
。
参数 | 默认值 | 类型 | 描述 | ||||||||||||||||||||||||||||
|
| 字符串 | RDMA 设备(例如, | ||||||||||||||||||||||||||||
|
| 字符串 | RDMA 设备(例如, | ||||||||||||||||||||||||||||
|
| 字符串 | 在其上创建静态 virtio PF 的 RDMA 设备(例如, | ||||||||||||||||||||||||||||
|
| 字符串 | RDMA LAG 设备(例如, | ||||||||||||||||||||||||||||
|
| 列表 | 以下子参数可用于配置静态 PF
| ||||||||||||||||||||||||||||
|
| 数字 | 指定是否使用 LAG 注意
如果使用 LAG,请确保为静态 PF 使用正确的 IB 设备 | ||||||||||||||||||||||||||||
|
| 数字 | 指定 DPU 是否为单端口设备。它与 | ||||||||||||||||||||||||||||
|
| 数字 | 指定是否启用恢复。如果未指定,则默认启用恢复。要禁用它,请将 | ||||||||||||||||||||||||||||
|
| 数字 | 将初始 SF 池大小确定为 注意
| ||||||||||||||||||||||||||||
|
| 数字 | 指定是否销毁 SF 池。设置为 1 时,控制器在停止/重启时销毁 SF 池(如果 | ||||||||||||||||||||||||||||
|
| 数字 | 指定是否启用打包 VQ 模式。如果未指定,则默认禁用打包 VQ。要启用,请将 注意
如果首次启用或修改 | ||||||||||||||||||||||||||||
|
| 数字 | 启用后,可合并缓冲区功能将与主机驱动程序协商。此功能允许 guest 驱动程序使用多个 RX 描述符链来接收单个接收数据包,从而提高带宽。 注意
如果首次启用或修改 | ||||||||||||||||||||||||||||
|
| 数字 | 指定 virtnet 应用程序的起始 DPA 核心。仅对 NVIDIA® BlueField®-3 及更高版本有效。值必须大于 0 且小于 11。与 注意
当同时运行多个 DPA 应用程序时,这是高级选项。普通用户应将此选项保留为默认值。 | ||||||||||||||||||||||||||||
|
| 数字 | 指定 virtnet 应用程序的结束 DPA 核心。仅对 BlueField-3 及更高版本有效。值必须大于 | ||||||||||||||||||||||||||||
|
| 列表 | 以下子参数可用于配置 VF
|
配置文件示例
在重启控制器之前,请验证配置文件的 JSON 格式,尤其是语法和符号。否则,控制器可能无法启动。
在双端口 BlueField 上配置 LAG
有关在 LAG 模式下配置 BlueField 的信息,请参阅“链路聚合”文档。
有关在 LAG 模式下配置 virtio-net 的信息,请参阅“链路聚合”页面。
在双端口 BlueField 上配置静态 PF
以下配置将所有静态 PF 配置为在非 LAG 配置中使用 mlx5_0
(端口 0)作为数据路径设备,以及 PF 的默认 MAC 和功能
{
"ib_dev_p0": "mlx5_0",
"ib_dev_p1": "mlx5_1",
"ib_dev_for_static_pf": "mlx5_0",
"is_lag": 0,
"static_pf": {
"mac_base": "08:11:22:33:44:55",
"features": "0x230047082b"
}
}
配置 VF 特定选项
以下配置使用默认参数配置 VF。使用此配置,每个 PF 根据 mac_base
分配 MAC,最多 126 个 VF。每个 VF 创建 4 个队列对,每个队列的深度为 256。
如果 vfs_per_pf
小于 mlxconfig 中的 VIRTIO_NET_EMULATION_NUM_VF
,并且创建了更多 VF,则重复的 MAC 将分配给不同的 VF。
{
"vf": {
"mac_base": "06:11:22:33:44:55",
"features": "0x230047082b",
"vfs_per_pf": 126,
"max_queue_pairs": 4,
"max_queue_size": 256
}
}
用户前端 CLI
为了与 virtio-net-controller 后端服务通信,BlueField 上安装了一个用户前端程序 virtnet,它基于远程过程调用 (RPC) 协议,并使用 JSON 格式输出。运行以下命令以检查其用法
usage: virtnet [-h] [-v] {hotplug,unplug,list,query,modify,log,version,restart,validate,update,health,debug,stats} ...
Nvidia virtio-net-controller command line interface v24.10.20
positional arguments:
{hotplug,unplug,list,query,modify,log,version,restart,validate,update,health,debug,stats}
** Use -h for sub-command usage
hotplug hotplug virtnet device
unplug unplug virtnet device
list list all virtnet devices
query query all or individual virtnet device(s)
modify modify virtnet device
log set log level
version show virtio net controller version info
restart Do fast restart of controller without killing the service
validate validate configurations
update update controller
health controller health utility
debug For debug purpose, cmds can be changed without notice
stats stats of virtnet device
options:
-h, --help show this help message and exit
-v, --version show program's version number and exit
Virtnet 支持通过输入一个命令并按 Tab 键进行命令行自动补全。
要检查当前运行的控制器版本
# virtnet -v
热插拔
此命令热插拔一个暴露给主机端的 virtio-net PCIe PF 设备。
语法
virtnet hotplug -i IB_DEVICE -m MAC -t MTU -n MAX_QUEUES -s MAX_QUEUE_SIZE [-h] [-u SF_NUM] [-f FEATURES] [-l]
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| 字符串 | 是 | 物理端口上的 RDMA 设备 (例如, 选项
|
|
| 十六进制数字 | 否 | 要在十六进制格式中启用的功能位。请参阅“Virtio-net 功能位”页面。 注意
请注意,某些功能默认启用。查询设备以显示支持的位。 |
|
| 数字 | 是 | virtio-net 设备的 MAC 地址。 注意
控制器不验证 MAC 地址(长度除外)。用户必须确保 MAC 有效且唯一。 |
|
| 数字 | 是 | virtio-net 设备的最大传输单元 (MTU) 大小。它必须小于上行链路 rep MTU 大小。 |
|
| 数字 | 是 | 与 可以为 virtio-net 设备创建的最大虚拟队列数。TX、RX、ctrl 队列分别计数(例如,3 具有 1 个 TX VQ、1 个 RX VQ、1 个 Ctrl VQ)。 注意
此选项将在未来被弃用。 |
|
| 数字 | 是 | 与 数据 VQ 对的数量。一个 VQ 对有一个 TX 队列和一个 RX 队列。它不计算控制或管理 VQ。从主机端来看,它在 |
|
| 数字 | 是 | virt 队列中缓冲区的最大数量,介于 0x4 和 0x8000 之间。必须是 2 的幂。 |
|
| 数字 | 否 | 用于此热插拔设备的 SF 编号,必须介于 2000 和 2999 之间。 |
|
| N/A | 否 | 创建传统(过渡)热插拔设备 |
输出
条目 | 类型 | 描述 |
| 字符串 | 主机枚举的 PCIe BDF(总线:设备:功能)编号。用户应该从主机端看到此 PCIe 设备。 |
| 字符串 | 唯一的设备 SN。它可以作为索引来查询/修改/拔出此设备。 |
| 编号 | 唯一的设备 ID。它可以作为索引来查询/修改/拔出此设备。 |
| 编号 | 当前设备是否为过渡热插拔设备。
|
| 字符串 | SF representor 名称代表 virtio-net 设备。应将其添加到 OVS 网桥中。 |
| 字符串 | 热插拔 virtio-net 设备的 MAC 地址 |
| 编号 | 热插拔失败时的错误号。
|
| 字符串 | 错误号的解释 |
示例
以下示例演示如何热插拔一个 MAC 地址为 0C:C4:7A:FF:22:93
、MTU 为 1500、以及 1 对虚拟队列 (QP) 对,深度为 1024 个条目的设备。该设备在 mlx5_0
的物理端口上创建。
# virtnet hotplug -i mlx5_0 -m 0C:C4:7A:FF:22:93 -t 1500 -qp 1 -s 1024
{
"bdf": "15:00.0",
"vuid": "MT2151X03152VNETS1D0F0",
"id": 0,
"transitional": 0,
"sf_rep_net_device": "en3f0pf0sf2000",
"mac": "0C:C4:7A:FF:22:93",
"errno": 0,
"errstr": "Success"
}
拔出
此命令拔出 virtio-net PCIe PF 设备。
语法
virtnet unplug [-h] [-p PF | -u VUID]
只需要 --pf
和 --vuid
中的一个来拔出设备。
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| 数字 | 是 | 热插拔时返回的唯一设备 ID。可以使用 |
|
| 字符串 | 是 | 热插拔时返回的唯一设备 SN。可以使用 |
输出
条目 | 类型 | 描述 |
| 编号 | 操作失败时的错误号
|
| 字符串 | 错误号的解释 |
示例
使用 PF ID 拔出热插拔设备
# virtnet unplug -p 0
{'id': '0x1'}
{
"errno": 0,
"errstr": "Success"
}
列表
此命令列出所有现有的 virtio-net 设备,包括全局信息和每个设备的单独信息。
语法
virtnet list [-h]
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
输出
输出分为两个主要部分。第一个部分由 controller
包裹,是全局配置和功能。
条目 | 类型 | 描述 |
| 字符串 | 此部分下的条目是控制器的全局信息 |
| 字符串 | 用于管理内部资源的 RDMA 设备管理器。应为默认的 |
| 字符串 | 可以热插拔的最大设备数量 |
| 字符串 | 设备仿真管理器管理的仿真设备总数 |
| 字符串 | 每个设备支持的最大 virt 队列数 |
| 字符串 | 设备在单个隧道请求中可以发送的最大描述符数 |
| 字符串 | 设备支持的功能总列表 |
| 字符串 | 当前支持的 virt 队列类型:Packed 和 Split |
| 字符串 | 当前支持的事件模式: |
每个设备在 devices
下都有自己的部分。
条目 | 类型 | 描述 |
| 字符串 | 此部分下的条目是每个设备的信息 |
| 数字 | 物理功能 ID |
| 字符串 | 功能类型:静态 PF、热插拔 PF、VF |
| 数字 | 当前设备是否为过渡热插拔设备
|
| 字符串 | 唯一的设备 SN,它可以作为索引来查询/修改/拔出设备 |
| 字符串 | 描述 virtio-net PCIe 设备的 总线:设备:功能 |
| 数字 | 通用 virtio-net 设备的虚拟 HCA 标识符。仅用于调试目的。 |
| 数字 | 可以为此 PF 创建的最大 virtio-net VF 数量。仅对 PF 有效。 |
| 数字 | 当前为此 PF 启用的 virtio-net VF 数量 |
| 数字 | 此 PF 上 VF 可用的空闲动态 MSIX 数量 |
| 数字 | 可以为 virtio-net VF 设置的动态 MSI-X 的最小数量 |
| 数字 | 可以为 virtio-net VF 设置的动态 MSI-X 的最大数量 |
| 数字 | 可以为 virtio-net VF 设置的动态数据 VQ 对(即,每对有一个 TX 和 1 个 RX 队列)的最小数量 |
| 数字 | 可以为 virtio-net VF 设置的动态数据 VQ 对(即,每对有一个 TX 和 1 个 RX 队列)的最小数量 |
| 数字 | 此 PF 上 VF 可用的空闲动态数据 VQ 对(即,每对有一个 TX 和 1 个 RX 队列)的数量 |
| 数字 | 此设备可用的最大 MSI-X 数量 |
| 数字 | 可以为此设备创建的最大虚拟队列数,驱动程序可以选择创建更少的队列 |
| 数字 | 驱动程序当前启用的虚拟队列数 |
| 数字 | 可以为每个 VQ 创建的最大虚拟队列深度(以字节为单位),驱动程序可以使用更小的深度 |
| 字符串 | 驱动程序用于 virtio 配置空间的 MSI-X 向量号。0xFFFF 表示未请求向量。 |
| 字符串 | virtio-net 设备的永久 MAC 地址,只能从控制器端通过 modify 命令更改 |
| 数字 | virtio-net 设备在驱动程序端的链路状态
|
| 数字 | 数据 VQ 对的数量。一个 VQ 对有一个 TX 队列和一个 RX 队列。不计算控制或管理 VQ。从主机端来看,它在 |
| 数字 | virtio-net 设备的 MTU。默认为 1500。 |
| 数字 | virtio-net 设备的链路速度,单位为 Mb/s |
| 数字 | RSS 密钥的最大支持长度。仅当启用 |
| 数字 | 此设备支持的哈希类型,以十六进制表示。仅当启用
|
| 字符串 | 驱动程序配置的管理 MAC 地址。不会随驱动程序重新加载或主机重启而持久存在。 |
| 数字 | 驱动程序配置的队列对/通道数。从主机端来看,它在 |
| 数字 | 用于此 virtio-net 设备的可扩展功能编号 |
| 字符串 | 用于创建 SF 的 RDMA 设备 |
| 字符串 | 用于创建 SF 的 PCIe 设备地址(总线:设备:功能) |
| 字符串 | 代表 virtio-net 设备 |
| 数字 | SF representor 网络接口索引 |
| 字符串 | SF RDMA 设备接口名称 |
| 数字 | 为 SF 创建的跨设备 MKEY。仅用于调试目的。 |
| 数字 | SF 的虚拟 HCA 标识符。仅用于调试目的。 |
| 数字 | 用于此 virtio-net 设备的 RQ 表 ID。仅用于调试目的。 |
| 字符串 | 是否启用或禁用加速接收流转向配置 |
| 字符串 | 是否启用或禁用动态中断节制 (DIM) |
示例
以下是列出 1 个已创建的静态 PF 的示例
# virtnet list
{
"controller": {
"emulation_manager": "mlx5_0",
"max_hotplug_devices": "0",
"max_virt_net_devices": "1",
"max_virt_queues": "256",
"max_tunnel_descriptors": "6",
"supported_features": {
"value": "0x8b00037700ef982f",
" 0": "VIRTIO_NET_F_CSUM",
" 1": "VIRTIO_NET_F_GUEST_CSUM",
" 2": "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS",
" 3": "VIRTIO_NET_F_MTU",
" 5": "VIRTIO_NET_F_MAC",
" 11": "VIRTIO_NET_F_HOST_TSO4",
" 12": "VIRTIO_NET_F_HOST_TSO6",
" 15": "VIRTIO_F_MRG_RX_BUFFER",
" 16": "VIRTIO_NET_F_STATUS",
" 17": "VIRTIO_NET_F_CTRL_VQ",
" 18": "VIRTIO_NET_F_CTRL_RX",
" 19": "VIRTIO_NET_F_CTRL_VLAN",
" 21": "VIRTIO_NET_F_GUEST_ANNOUNCE",
" 22": "VIRTIO_NET_F_MQ",
" 23": "VIRTIO_NET_F_CTRL_MAC_ADDR",
" 32": "VIRTIO_F_VERSION_1",
" 33": "VIRTIO_F_IOMMU_PLATFORM",
" 34": "VIRTIO_F_RING_PACKED",
" 36": "VIRTIO_F_ORDER_PLATFORM",
" 37": "VIRTIO_F_SR_IOV",
" 38": "VIRTIO_F_NOTIFICATION_DATA",
" 40": "VIRTIO_F_RING_RESET",
" 41": "VIRTIO_F_ADMIN_VQ",
" 56": "VIRTIO_NET_F_HOST_USO",
" 57": "VIRTIO_NET_F_HASH_REPORT",
" 59": "VIRTIO_NET_F_GUEST_HDRLEN",
" 63": "VIRTIO_NET_F_SPEED_DUPLEX"
},
"supported_virt_queue_types": {
"value": "0x1",
" 0": "SPLIT"
},
"supported_event_modes": {
"value": "0x5",
" 0": "NO_MSIX_MODE",
" 2": "MSIX_MODE"
}
},
"devices": [
{
"pf_id": 0,
"function_type": "static PF",
"transitional": 0,
"vuid": "MT2306XZ00BNVNETS0D0F2",
"pci_bdf": "e2:00.2",
"pci_vhca_id": "0x2",
"pci_max_vfs": "0",
"enabled_vfs": "0",
"msix_num_pool_size": 0,
"min_msix_num": 0,
"max_msix_num": 256,
"min_num_of_qp": 0,
"max_num_of_qp": 127,
"qp_pool_size": 0,
"num_msix": "256",
"num_queues": "255",
"enabled_queues": "0",
"max_queue_size": "256",
"msix_config_vector": "0xFFFF",
"mac": "16:B0:E0:41:B8:0D",
"link_status": "1",
"max_queue_pairs": "127",
"mtu": "1500",
"speed": "100000",
"rss_max_key_size": "0",
"supported_hash_types": "0x0",
"ctrl_mac": "00:00:00:00:00:00",
"ctrl_mq": "0",
"sf_num": 1000,
"sf_parent_device": "mlx5_0",
"sf_parent_device_pci_addr": "0000:03:00.0",
"sf_rep_net_device": "en3f0pf0sf1000",
"sf_rep_net_ifindex": 10,
"sf_rdma_device": "mlx5_3",
"sf_cross_mkey": "0x12642",
"sf_vhca_id": "0x124",
"sf_rqt_num": "0x0",
"aarfs": "disabled",
"dim": "disabled"
}
]
}
查询
此命令查询给定设备的详细信息,包括所有已创建的 VQ 信息。
语法
virtnet query [-h] {[-a] | [-p PF] [-v VF] | [-u VUID]} [--dbg_stats] [-b] [--latency_stats] [-q QUEUE_ID] [--stats_clear]
选项 --pf
、--vf
、--vuid
和 --all
是互斥的(除了 --pf
和 --vf
可以一起使用),但必须应用其中一个。
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| N/A | 否 | 查询所有可用设备的所有详细信息。如果可用设备数量很多,则可能很耗时。 |
|
| 数字 | 否 | PF 的唯一设备 ID。可以使用 |
|
| 数字 | 否 | VF 的唯一设备 ID。可以使用 |
|
| 字符串 | 否 | 设备(PF/VF)的唯一设备 SN。可以使用 |
|
| 数字 | 否 | 设备 VQ 的队列索引 |
|
| N/A | 否 | 查询设备的简要信息(不打印 VQ 信息) |
| N/A | N/A | 否 | 打印调试计数器和信息 注意
此选项将在未来被弃用。 |
| N/A | N/A | 否 | 清除所有调试计数器统计信息 注意
此选项将在未来被弃用。 |
输出
输出分为两个主要部分。
第一个部分由
devices
包裹,是设备级别的配置和功能,其中大部分与list
命令相同。此部分仅涵盖两者之间的差异。条目
类型
描述
devices
字符串
此部分下的条目是每个设备的信息
pci_dev_id
字符串
Virtio-net PCIe 设备 ID。默认值:0x1041。
注意此选项将在未来被弃用。
pci_vendor_id
字符串
Virtio-net PCIe 供应商 ID。默认值:0x1af4。
注意此选项将在未来被弃用。
pci_class_code
字符串
Virtio-net PCIe 设备类代码。默认值:0x20000。
注意此选项将在未来被弃用。
pci_subsys_id
字符串
Virtio-net PCIe 供应商 ID。默认值:0x1041。
注意此选项将在未来被弃用。
pci_subsys_vendor_id
字符串
Virtio-net PCIe 子系统供应商 ID。默认值:0x1af4。
注意此选项将在未来被弃用。
pci_revision_id
字符串
Virtio-net PCIe 修订 ID。默认值:1。
注意此选项将在未来被弃用。
device_features
字符串
根据 virtio 规范启用的设备功能位。请参阅“功能位”部分。
driver_features
字符串
根据 virtio 规范启用的驱动程序功能位。仅当驱动程序探测设备时有效。请参阅“功能位”。
status
字符串
根据 virtio 规范的设备状态字段位掩码
ACKNOWLEDGE(位 0)
DRIVER(位 1)
DRIVER_OK(位 2)
FEATURES_OK(位 3)
DEVICE_NEEDS_RESET(位 6)
FAILED(位 7)
reset
数字
显示当前 virtio-net 设备是否正在重置
0 – 未正在重置
1 – 正在重置
enabled
数字
显示当前 virtio-net 设备是否已启用
0 – 已禁用,可能发生了 FLR
1 – 已启用
第二个部分由
enabled-queues-info
包裹,提供每个 VQ 的信息条目
类型
描述
index
数字
VQ 索引,从 0 开始到
enabled_queues
size
数字
驱动程序 VQ 深度(以字节为单位)。它受设备
max_queues_size
限制。msix_vector
数字
用于此 VQ 的 MSI-X 向量号
enable
数字
当前 VQ 是否已启用
0 – 已禁用
1 – 已启用
notify_offset
数字
驱动程序读取此值以计算从通知结构起始位置到此 virtqueue 位置的偏移量
descriptor_address
数字
描述符区域的物理地址
driver_address
数字
驱动程序区域的物理地址
device_address
数字
设备区域的物理地址
received_desc
数字
设备在此 VQ 上接收到的描述符总数
注意此选项将在未来被弃用。
completed_desc
数字
设备在此 VQ 上完成的描述符总数
注意此选项将在未来被弃用。
bad_desc_errors
数字
在此 VQ 上接收到的错误描述符总数
注意此选项将在未来被弃用。
error_cqes
数字
此 VQ 上的错误 CQ 条目总数
注意此选项将在未来被弃用。
exceed_max_chain
数字
接收到的链式描述符总数,超过设备允许的最大链式数量
注意此选项将在未来被弃用。
invalid_buffer
数字
设备尝试读取或写入未注册到设备的缓冲区的总次数
注意此选项将在未来被弃用。
batch_number
数字
上次接收的数据包的 RX 描述符数。仅与 BlueField-3 相关。
注意此选项将在未来被弃用。
dma_q_used_number
数字
用于此 VQ 的 DMA q 索引。仅与 BlueField-3 相关。
注意此选项将在未来被弃用。
handler_schd_number
数字
此 VQ 的调度器编号。仅与 BlueField-3 相关。
注意此选项将在未来被弃用。
aux_handler_schd_number
数字
此 VQ 的辅助调度器编号。仅与 BlueField-3 相关。
注意此选项将在未来被弃用。
max_post_desc_number
数字
此 VQ 上发布的最大描述符数。与 DPA 相关。
注意此选项将在未来被弃用。
total_bytes
数字
此 VQ 处理的字节总数。仅与 BlueField-3 相关
注意此选项将在未来被弃用。
rq_cq_max_count
数字
队列的事件生成节制计数器。与 RQ 相关。
注意此选项将在未来被弃用。
rq_cq_period
数字
队列的事件生成节制计时器,单位为 1 微秒粒度。与 RQ 相关。
注意此选项将在未来被弃用。
rq_cq_period_mode
数字
RQ 的当前周期模式
0x0 –
default_mode
– 使用设备最佳默认值0x1 –
upon_event
–queue_period
计时器在事件生成时重新启动0x2 –
upon_cqe
–queue_period
计时器在完成生成时重新启动
注意此选项将在未来被弃用。
示例
以下是查询第一个 PF 信息的示例
# virtnet query -p 0
{
"devices": [
{
"pf_id": 0,
"function_type": "static PF",
"transitional": 0,
"vuid": "MT2349X00018VNETS0D0F1",
"pci_bdf": "23:00.1",
"pci_vhca_id": "0x1",
"pci_max_vfs": "0",
"enabled_vfs": "0",
"pci_dev_id": "0x1041",
"pci_vendor_id": "0x1af4",
"pci_class_code": "0x20000",
"pci_subsys_id": "0x1041",
"pci_subsys_vendor_id": "0x1af4",
"pci_revision_id": "1",
"device_feature": {
"value": "0x8930032300ef182f",
" 0": "VIRTIO_NET_F_CSUM",
" 1": "VIRTIO_NET_F_GUEST_CSUM",
" 2": "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS",
" 3": "VIRTIO_NET_F_MTU",
" 5": "VIRTIO_NET_F_MAC",
" 11": "VIRTIO_NET_F_HOST_TSO4",
" 12": "VIRTIO_NET_F_HOST_TSO6",
" 16": "VIRTIO_NET_F_STATUS",
" 17": "VIRTIO_NET_F_CTRL_VQ",
" 18": "VIRTIO_NET_F_CTRL_RX",
" 19": "VIRTIO_NET_F_CTRL_VLAN",
" 21": "VIRTIO_NET_F_GUEST_ANNOUNCE",
" 22": "VIRTIO_NET_F_MQ",
" 23": "VIRTIO_NET_F_CTRL_MAC_ADDR",
" 32": "VIRTIO_F_VERSION_1",
" 33": "VIRTIO_F_IOMMU_PLATFORM",
" 37": "VIRTIO_F_SR_IOV",
" 40": "VIRTIO_F_RING_RESET",
" 41": "VIRTIO_F_ADMIN_VQ",
" 52": "VIRTIO_NET_F_VQ_NOTF_COAL",
" 53": "VIRTIO_NET_F_NOTF_COAL",
" 56": "VIRTIO_NET_F_HOST_USO",
" 59": "VIRTIO_NET_F_GUEST_HDRLEN",
" 63": "VIRTIO_NET_F_SPEED_DUPLEX"
},
"driver_feature": {
"value": "0x8000002300ef182f",
" 0": "VIRTIO_NET_F_CSUM",
" 1": "VIRTIO_NET_F_GUEST_CSUM",
" 2": "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS",
" 3": "VIRTIO_NET_F_MTU",
" 5": "VIRTIO_NET_F_MAC",
" 11": "VIRTIO_NET_F_HOST_TSO4",
" 12": "VIRTIO_NET_F_HOST_TSO6",
" 16": "VIRTIO_NET_F_STATUS",
" 17": "VIRTIO_NET_F_CTRL_VQ",
" 18": "VIRTIO_NET_F_CTRL_RX",
" 19": "VIRTIO_NET_F_CTRL_VLAN",
" 21": "VIRTIO_NET_F_GUEST_ANNOUNCE",
" 22": "VIRTIO_NET_F_MQ",
" 23": "VIRTIO_NET_F_CTRL_MAC_ADDR",
" 32": "VIRTIO_F_VERSION_1",
" 33": "VIRTIO_F_IOMMU_PLATFORM",
" 37": "VIRTIO_F_SR_IOV",
" 63": "VIRTIO_NET_F_SPEED_DUPLEX"
},
"status": {
"value": "0xf",
" 0": "ACK",
" 1": "DRIVER",
" 2": "DRIVER_OK",
" 3": "FEATURES_OK"
},
"reset": "0",
"enabled": "1",
"num_msix": "64",
"num_queues": "63",
"enabled_queues": "63",
"max_queue_size": "256",
"msix_config_vector": "0x0",
"mac": "4E:6A:E1:41:D8:BE",
"link_status": "1",
"max_queue_pairs": "31",
"mtu": "1500",
"speed": "200000",
"rss_max_key_size": "0",
"supported_hash_types": "0x0",
"ctrl_mac": "4E:6A:E1:41:D8:BE",
"ctrl_mq": "31",
"sf_num": 1000,
"sf_parent_device": "mlx5_0",
"sf_parent_device_pci_addr": "0000:03:00.0",
"sf_rep_net_device": "en3f0pf0sf1000",
"sf_rep_net_ifindex": 12,
"sf_rdma_device": "mlx5_2",
"sf_cross_mkey": "0xC042",
"sf_vhca_id": "0x7E8",
"sf_rqt_num": "0x0",
"aarfs": "disabled",
"dim": "disabled",
"enabled-queues-info": [
{
"index": "0",
"size": "256",
"msix_vector": "0x1",
"enable": "1",
"notify_offset": "0",
"descriptor_address": "0x10cece000",
"driver_address": "0x10cecf000",
"device_address": "0x10cecf240",
"received_desc": "256",
"completed_desc": "0",
"bad_desc_errors": "0",
"error_cqes": "0",
"exceed_max_chain": "0",
"invalid_buffer": "0",
"batch_number": "64",
"dma_q_used_number": "6",
"handler_schd_number": "4",
"aux_handler_schd_number": "3",
"max_post_desc_number": "0",
"total_bytes": "0",
"rq_cq_max_count": "0",
"rq_cq_period": "0",
"rq_cq_period_mode": "1"
},
......
}
]
}
]
}
统计信息
建议使用此命令获取所有数据包计数器信息。使用 virtnet list
和 virtnet query
命令可用的现有数据包计数器信息将在未来被弃用。
此命令检索指定设备的数据包计数器,包括所有 Rx 和 Tx virtqueues (VQ) 的详细信息。
要启用/禁用每个 Rx 队列的按字节数据包计数器,请使用以下命令
virtnet modify {[-p PF] [-v VF]} device -pkt_cnt {enable,disable}
启用后,按字节数据包计数器将初始化为零。
禁用后,将保留先前的值以用于调试目的。该命令仍将返回这些旧的、禁用的计数器值。
数据包计数器附加到 RQ。因此,必须首先创建 RQ。这意味着 virtio-net 设备应在主机操作系统上被驱动程序探测,然后再运行上述命令。
语法
virtnet stats [-h] {[-p PF] [-v VF] | [-u VUID]} [-q QUEUE_ID]
选项 --pf
、--vf
和 --vuid
是互斥的(除了 --pf
和 --vf
可以一起使用),但必须应用其中一个。
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| 数字 | 否 | PF 的唯一设备 ID。可以使用 |
|
| 数字 | 否 | VF 的唯一设备 ID。可以使用 |
|
| 字符串 | 否 | 设备(PF/VF)的唯一设备 SN。可以使用 |
|
| 数字 | 否 | 设备 RQ 或 SQ 的队列索引 |
输出
输出分为两个部分。
第一个部分由
device
包裹,是设备详细信息以及数据包计数器统计信息启用状态。条目
类型
描述
device
字符串
此部分下的条目是每个设备的信息
pf_id
字符串
物理功能 ID
packet_counters
字符串
指示是否启用或禁用数据包计数器功能
第二个部分由 queues-stats 包裹,是每个接收 VQ 的信息。
条目
类型
描述
VQ 索引
数字
VQ 索引从 0(第一个 RQ)开始,一直到最后一个 SQ
rx_64_or_less_octet_packets
数字
接收到的数据包数量,大小为 0 到 64 字节。与 BlueField-3 RQ 相关。
rx_65_to_127_octet_packets
数字
接收到的数据包数量,大小为 65 到 127 字节。与 BlueField-3 RQ 相关。
rx_128_to_255_octet_packets
数字
接收到的数据包数量,大小为 128 到 255 字节。与 BlueField-3 RQ 相关。
rx_256_to_511_octet_packets
数字
接收到的数据包数量,大小为 256 到 511 字节。与 BlueField-3 RQ 相关。
rx_512_to_1023_octet_packets
数字
接收到的数据包数量,大小为 512 到 1023 字节。与 BlueField-3 RQ 相关。
rx_1024_to_1522_octet_packets
数字
接收到的数据包数量,大小为 1024 到 1522 字节。与 BlueField-3 RQ 相关。
rx_1523_to_2047_octet_packets
数字
接收到的数据包数量,大小为 1523 到 2047 字节。与 BlueField-3 RQ 相关。
rx_2048_to_4095_octet_packets
数字
接收到的数据包数量,大小为 2048 到 4095 字节。与 BlueField-3 RQ 相关。
rx_4096_to_8191_octet_packets
数字
接收到的数据包数量,大小为 4096 到 8191 字节。与 BlueField-3 RQ 相关。
rx_8192_to_9022_octet_packets
数字
接收到的数据包数量,大小为 8192 到 9022 字节。与 BlueField-3 RQ 相关。
received_desc
数字
设备在此 VQ 上接收到的描述符总数
completed_desc
数字
设备在此 VQ 上完成的描述符总数
bad_desc_errors
数字
在此 VQ 上接收到的错误描述符总数
error_cqes
数字
此 VQ 上的错误 CQ 条目总数
exceed_max_chain
数字
接收到的链式描述符总数,超过设备允许的最大链式数量
invalid_buffer
数字
设备尝试读取或写入未注册到设备的缓冲区的总次数
batch_number
数字
上次接收的数据包的 RX 描述符数。与 BlueField-3 相关。
dma_q_used_number
数字
用于此 VQ 的 DMA q 索引。与 BlueField-3 相关。
handler_schd_number
数字
此 VQ 的调度器编号。与 BlueField-3 相关。
aux_handler_schd_number
数字
Aux 调度器编号。与 BlueField-3 相关。
max_post_desc_number
数字
此 VQ 上发布的最大描述符数。与 DPA 相关。
total_bytes
数字
此 VQ 处理的字节总数。与 BlueField-3 相关。
rq_cq_max_count
数字
队列的事件生成节制计数器。与 RQ 相关。
rq_cq_period
数字
队列的事件生成节制计时器,单位为 1 微秒粒度。与 RQ 相关。
rq_cq_period_mode
数字
RQ 的当前周期模式
0x0 –
default_mode
– 使用设备最佳默认值0x1 –
upon_event
–queue_period
计时器在事件生成时重新启动0x2 –
upon_cqe
–queue_period
计时器在完成生成时重新启动
示例
以下是查询 PF 0 和 VQ 0(即 RQ)的数据包统计信息的示例
# virtnet stats -p 0 -q 0
{'pf': '0x0', 'queue_id': '0x0'}
{
"device": {
"pf_id": 0,
"packet_counters": "Enabled",
"queues-stats": [
{
"VQ Index": 0,
"rx_64_or_less_octet_packets": 0,
"rx_65_to_127_octet_packets": 259,
"rx_128_to_255_octet_packets": 0,
"rx_256_to_511_octet_packets": 0,
"rx_512_to_1023_octet_packets": 0,
"rx_1024_to_1522_octet_packets": 0,
"rx_1523_to_2047_octet_packets": 0,
"rx_2048_to_4095_octet_packets": 199,
"rx_4096_to_8191_octet_packets": 0,
"rx_8192_to_9022_octet_packets": 0,
"received_desc": "4096",
"completed_desc": "0",
"bad_desc_errors": "0",
"error_cqes": "0",
"exceed_max_chain": "0",
"invalid_buffer": "0",
"batch_number": "64",
"dma_q_used_number": "0",
"handler_schd_number": "44",
"aux_handler_schd_number": "43",
"max_post_desc_number": "0",
"total_bytes": "0",
"err_handler_schd_num": "0",
"rq_cq_max_count": "0",
"rq_cq_period": "0",
"rq_cq_period_mode": "1"
}
]
}
}
修改设备
此命令修改给定设备的属性。
语法
virtnet modify [-h] [-p PF] [-v VF] [-u VUID] [-a] {device,queue} ...
选项 --pf
、--vf
、--vuid
和 --all
是互斥的(除了 --pf
和 --vf
可以一起使用),但必须应用其中一个。
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| N/A | 否 | 根据 |
|
| 数字 | 否 | PF 的唯一设备 ID。可以使用 |
|
| 数字 | 否 | VF 的唯一设备 ID。可以使用 |
|
| 字符串 | 否 | 设备(PF/VF)的唯一设备 SN。可以使用 |
| N/A | 数字 | 否 | 修改设备特定选项 |
| N/A | N/A | 否 | 修改队列特定选项 |
设备选项
virtnet modify device [-h] [-m MAC] [-t MTU] [-e SPEED] [-l LINK]
[-s STATE] [-f FEATURES]
[-o SUPPORTED_HASH_TYPES] [-k RSS_MAX_KEY_SIZE]
[-r RX_MODE] [-n MSIX_NUM] [-q MAX_QUEUE_SIZE]
[-d DST_PORT] [-b RX_DMA_Q_NUM]
[-dc {enable,disable}] [-pkt_cnt {enable,disable}]
[-aarfs {enable,disable}] [-qp MAX_QUEUE_PAIRS] [-dim {enable,disable}]
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| 字符串 | 否 | 显示帮助信息并退出 |
|
| 数字 | 否 | virtio-net 设备的 MAC 地址 |
|
| 数字 | 否 | virtio-net 设备的 MTU |
|
| 数字 | 否 | virtio-net 设备的链路速度,单位为 Mb/s |
|
| 数字 | 否 | virtio-net 设备的链路状态
|
|
| 数字 | 否 | 根据 virtio 规范的 virtio-net 设备状态字段位掩码
|
|
| 十六进制数字 | 否 | 根据 virtio 规范的 virtio-net 设备功能位 |
|
| 十六进制数字 | 否 | 此设备支持的哈希类型,以十六进制表示。仅当启用
|
|
| 数字 | 否 | RSS 密钥的最大支持长度。仅当启用 |
|
| 十六进制数字 | 否 | 暴露给驱动程序的 RX 模式
|
|
| 数字 | 否 | VQ 的最大数量(数据 VQ 和 ctrl/admin VQ)。它受控制器级别 |
|
| 数字 | 否 | VQ 中缓冲区的最大数量。队列大小值始终是 2 的幂。最大队列大小值为 32768。 |
|
| 数字 | 否 | 数据 VQ 对的数量。一个 VQ 对有一个 TX 队列和一个 RX 队列。不计算控制或管理 VQ。从主机端来看,它在 |
|
| 十六进制数字 | 否 | 修改 IPv4 注意
将在未来被弃用。 |
|
| 数字 | 否 | 修改最大 RX DMA 队列号 |
|
| 字符串 | 否 | 启用/禁用 virtio-net 丢包计数器 |
|
| 字符串 | 否 | 启用/禁用 virtio-net 设备数据包计数器统计信息 |
|
| 字符串 | 否 | 启用/禁用自动 AARFS。仅适用于 PF 设备(静态 PF 和热插拔 PF)。 |
|
| 字符串 | 否 | 启用/禁用动态中断节制 (DIM) |
以下 modify
选项需要在 guest OS 中取消绑定 virtio 设备与 virtio-net 驱动程序
mac
mtu
features
msix_num
max_queue_size
max_queue_pairs
例如
在 guest OS 上
[host]# echo "bdf of virtio-dev" > /sys/bus/pci/drivers/virtio-pci/unbind
在 DPU 端
修改设备的最大队列大小
[dpu]# virtnet modify -p 0 -v 0 device -q 2048
修改 VF 设备的 MSI-X 数量
[dpu]# virtnet modify -p 0 -v 0 device -n 8
修改 virtio 物理设备 ID 0 的 MAC 地址(或使用其“VUID 字符串”,可以通过 virtnet list/query 获取)
[dpu]# virtnet modify -p 0 device -m 0C:C4:7A:FF:22:93
修改 VF 设备的最大队列对数
[dpu]# virtnet modify -p 0 -v 0 device -qp 2
在 guest OS 上
[host]# echo "bdf of virtio-dev" > /sys/bus/pci/drivers/virtio-pci/bind
队列选项
virtnet modify queue [-h] -e {event,cqe} -n PERIOD -c MAX_COUNT
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| 字符串 | 否 | 显示帮助信息并退出 |
|
| 字符串 | 否 | RQ 周期模式: |
|
| 数字 | 否 | 队列的事件生成节制计时器,单位为 1 微秒粒度 |
|
| 数字 | 否 | 队列的最大事件生成节制计数器 |
输出
条目 | 类型 | 描述 |
| 数字 | 错误号
|
| 字符串 | 错误号的解释 |
示例
将第一个 PF 上的第一个 VF 的链路状态修改为 down
# virtnet modify -p 0 device -l 0
{'pf': '0x0', 'all': '0x0', 'subcmd': '0x0', 'link': '0x0'}
{
"errno": 0,
"errstr": "Success"
}
日志
此命令管理 virtio-net-controller 的日志级别。
语法
virtnet log [-h] -l {info,err,debug}
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| 字符串 | 是 | 从日志更改 |
输出
条目 | 类型 | 描述 |
| 字符串 | 成功或失败,并显示消息 |
示例
将日志级别更改为 info
# virtnet log -l info
{'level': 'info'}
"Success"
监视控制器服务的当前日志输出,并打印最新的 100 行
$ journalctl -u virtio-net-controller -f -n 100
验证
此命令验证 virtio-net-controller 的配置。
语法
virtnet validate [-h] -f PATH_TO_FILE
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| 字符串 | 否 | 验证 |
输出
条目 | 类型 | 描述 |
| 字符串 | 成功或失败,并显示消息 |
示例
检查 virtnet.conf
是否为有效的 JSON 文件
# virtnet validate -f /opt/mellanox/mlnx_virtnet/virtnet.conf
/opt/mellanox/mlnx_virtnet/virtnet.conf is valid
版本
此命令打印 virtio-net-controller 的当前版本和更新版本。
语法
virtnet version [-h]
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
输出
条目 | 类型 | 描述 |
| 字符串 | 原始控制器版本 |
| 字符串 | 要更新的控制器版本 |
示例
检查当前和下一个可用的控制器版本
# virtnet version
[
{
"Original Controller": "v24.10.17"
},
{
"Destination Controller": "v24.10.19"
}
]
更新
此命令执行在线更新到操作系统上安装的另一个版本。此过程更新到新版本,停机时间最短,而不是完全关闭并重新创建所有现有设备。
语法
virtnet update [-h] [-s | -t]
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| N/A | 否 | 启动在线更新 virtio-net-controller |
|
| N/A | 否 | 检查在线更新状态 |
输出
条目 | 类型 | 描述 |
| 字符串 | 如果更新成功启动 |
示例
要启动在线更新过程,请运行
# virtnet update -s
{'start': '0x1'}
"Update started, use 'virtnet update -t' or check logs for status"
要在更新过程中检查更新状态,请运行
# virtnet update -t
{'status': '0x1'}
{
"status": "inactive",
"last live update status": "success",
"time_used (s)": 0.604152
}
重启
此命令执行 virtio-net-controller 服务的快速重启。与常规重启(使用 systemctl restart virtio-net-controller
)相比,此命令每个设备的停机时间更短。
语法
virtnet restart [-h]
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
输出
条目 | 类型 | 描述 |
| 字符串 | 如果快速重启成功完成
|
示例
要启动在线更新过程,请运行
# virtnet restart
SUCCESS
健康状况
此命令显示给定设备的健康状况信息。
必须加载 virtio-net 驱动程序,此命令才能显示有效信息。
语法
virtnet health [-h] {[-a] | [-p PF] [-v VF] | [-u VUID]} [show]
选项 --pf
、--vf
、--vuid
和 --all
是互斥的(除了 --pf
和 --vf
可以一起使用),但必须应用其中一个。
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| N/A | 否 | 查询所有可用设备的所有详细信息。如果可用设备数量很多,则可能很耗时。 |
|
| 数字 | 否 | PF 的唯一设备 ID。可以使用 |
|
| 数字 | 否 | VF 的唯一设备 ID。可以使用 |
|
| 字符串 | 否 | 设备(PF/VF)的唯一设备 SN。可以使用 |
子命令 | 必需 | 描述 |
| 是 | 显示给定设备的健康状况信息 |
输出
条目 | 类型 | 描述 |
| 数字 | 物理功能 ID |
| 字符串 | 功能类型:静态 PF、热插拔 PF、VF |
| 字符串 | 唯一的设备 SN,它可以作为索引来查询/修改/拔出设备 |
| 字符串 | 根据 virtio 规范的设备状态字段位掩码
|
| 字符串 |
|
| 数字 | 已执行的恢复次数 |
| 字典 | 包含两种类型的健康状况信息: 其中
并且
每个错误的详细描述可以在 健康状况统计信息 中找到。 |
示例
以下是显示第一个 PF 信息的示例
# virtnet health -p 0 show
{'pf': '0x0', 'all': '0x0', 'subcmd': '0x0'}
{
"pf_id": 0,
"type": "static PF",
"vuid": "MT2306XZ00BPVNETS0D0F1",
"dev_status": {
"value": "0xf",
" 0": "ACK",
" 1": "DRIVER",
" 2": "DRIVER_OK",
" 3": "FEATURES_OK"
},
"health_status": "Good",
"health_recover_counter": 0,
"dev_health_details": {
"control_plane_errors": {
"sf_rqt_update_err": 0,
"sf_drop_create_err": 0,
"sf_tir_create_err": 0,
"steer_rx_domain_err": 0,
"steer_rx_table_err": 0,
"sf_flows_apply_err": 0,
"aarfs_flow_init_err": 0,
"vlan_flow_init_err": 0,
"drop_cnt_config_err": 0
},
"data_plane_errors": {
"sq_stall": 0,
"dma_q_stall": 0,
"spurious_db_invoke": 0,
"aux_not_invoked": 0,
"dma_q_errors": 0,
"host_read_errors": 0
}
}
}
错误代码
CLI 命令在失败时将返回非 0 错误代码。所有错误号均为负数。当日志中发生错误时,也可能返回错误号。
如果错误号大于 -1000
,则是标准错误。请参阅 Linux 错误代码:errno
如果错误号小于或等于 -1000
,请参阅下表了解解释。
Errno | 错误名称 | 错误描述 |
|
| 未能验证设备功能 |
|
| 未能找到设备 |
|
| 失败 - 设备未热插拔 |
|
| 失败 - 设备未启动 |
|
| 失败 - 不应加载 Virtio 驱动程序 |
|
| 未能添加 epoll |
|
| 失败 - ID 输入超出最大范围 |
|
| 失败 - VUID 无效 |
|
| 失败 - MAC 无效 |
|
| 失败 - MSIX 无效 |
|
| 失败 - MTU 无效 |
|
| 未能找到端口上下文 |
|
| 未能从恢复文件加载配置 |
|
| 未能将配置保存到恢复文件 |
|
| 未能创建恢复文件 |
|
| 未能删除恢复文件中的 MAC |
|
| 未能从恢复文件加载 MAC |
|
| 未能将 MAC 保存到恢复文件 |
|
| 未能将 MQ 保存到恢复文件 |
|
| 未能从恢复文件加载 PF 编号 |
|
| 未能将 RX 模式保存到恢复文件 |
|
| 未能将 PF 和 SF 编号保存到恢复文件 |
|
| 未能从恢复文件加载 SF 编号 |
|
| 未能通过 SF 应用 MAC 流 |
|
| 未能通过 SF 更新 MQ |
|
| 未能通过 SF 设置 RX 模式 |
|
| 未能打开 SNAP 设备控制 |
|
| 未能创建 SNAP 跨 mkey |
|
| 未能创建 SNAP DMA Q |
|
| 未能查询 SNAP 设备 |
|
| 未能修改 SNAP 设备 |
|
| 未能热插拔 SNAP PF |
|
| 未能更新 VQ 周期 |
|
| 失败 - 队列大小无效 |
|
| 未能添加 SF 端口 |
|
| 未能分配工作队列 |
|
| 未能分配 eth VQS 操作 |
|
| 未能完成 eth VQS 操作 |
|
| 失败 - JSON 对象不存在 |
|
| 未能准备设备加载 |
|
| 未能软件迁移设备 |
|
| 失败 - 设备正在迁移 |
|
| 错误 - 队列大小必须大于 2 且为 2 的幂 |
|
| 警告 - 此设备将无法运行,请勿尝试使用 virtio 驱动程序探测 |
|
| SF 池正在创建,请稍后重试 |
|
| 未能设置 dst 端口规则 |
|
| 不支持该选项 |
|
| 未能创建 SF |
|
| 热插拔设备的 SF 编号应介于 2000 和 2999 之间 |
|
| SF 编号已被使用 |
|
| 队列索引无效 |
|
| 速度无效,请查看帮助菜单以获取支持的链路速度 |
|
| 哈希类型无效,请查看帮助菜单以获取支持的哈希类型 |
|
| rss 最大密钥大小无效,支持的密钥大小为 40 |
|
| 未能将 OFFLOADS 保存到恢复文件 |
|
| Failed to update OFFLOADS by SF |
|
| Failed to readlink |
|
| Error - Path format is invalid |
|
| Failed to alloc q counter |
|
| Failed to save dirty log |
|
| Failed to delete dirty log |
|
| Failed to save LM status |
|
| Failed to found LM status record |
|
| Failed to save dev mode |
|
| Failed to found dev mode record |
|
| Error - Device is not ready to be unplugged please check host and retry |
|
| Failed to delete MAC table in recovery file |
|
| Failed to load MAC table from recovery file |
|
| Failed to save MAC table into recovery file |
|
| Failed to delete hash cfg in recovery file |
|
| Failed to load hash cfg from recovery file |
|
| Failed to save hash cfg into recovery file |
|
| Failed to get VF device |
|
| Failed - QUEUES is invalid |
|
| Failed to save into debugfs file |
|
| Failed to delete from debugfs file |
计数器
数据包统计信息
要查询数据包计数器,请使用 stats
命令。
[dpu]# virtnet stats [-h] {[-p PF] [-v VF] | [-u VUID]} [-q QUEUE_ID]
选项 --pf
、 --vf
和 --vuid
是互斥的,但必须应用其中一个。
选项 | 缩写 | 参数类型 | 必需 | 描述 |
|
| N/A | 否 | 显示帮助信息并退出 |
|
| 数字 | 否 | PF 的唯一设备 ID。可以使用 |
|
| 数字 | 否 | VF 的唯一设备 ID。可以使用 |
|
| 字符串 | 否 | 设备(PF/VF)的唯一设备 SN。可以使用 |
|
| 数字 | 否 | 设备 RQ 或 SQ 的队列索引 |
建议使用此命令获取所有数据包计数器信息。通过 virtnet list
和 virtnet query
命令提供的现有数据包计数器信息将在未来版本中弃用。
以下命令查询 PF 0 和 VQ 0(即 RQ)
[dpu]# virtnet stats -p 0
-q 0
输出
# virtnet stats -p 0
-q 0
{'pf'
: '0x0'
, 'queue_id'
: '0x0'
}
{
"device"
: {
"pf_id"
: 0
,
"packet_counters"
: "Enabled"
,
"queues-stats"
: [
{
"VQ Index"
: 0
,
"rx_64_or_less_octet_packets"
: 0
,
"rx_65_to_127_octet_packets"
: 259
,
"rx_128_to_255_octet_packets"
: 0
,
"rx_256_to_511_octet_packets"
: 0
,
"rx_512_to_1023_octet_packets"
: 0
,
"rx_1024_to_1522_octet_packets"
: 0
,
"rx_1523_to_2047_octet_packets"
: 0
,
"rx_2048_to_4095_octet_packets"
: 199
,
"rx_4096_to_8191_octet_packets"
: 0
,
"rx_8192_to_9022_octet_packets"
: 0
,
"received_desc"
: "4096"
,
"completed_desc"
: "0"
,
"bad_desc_errors"
: "0"
,
"error_cqes"
: "0"
,
"exceed_max_chain"
: "0"
,
"invalid_buffer"
: "0"
,
"batch_number"
: "64"
,
"dma_q_used_number"
: "0"
,
"handler_schd_number"
: "44"
,
"aux_handler_schd_number"
: "43"
,
"max_post_desc_number"
: "0"
,
"total_bytes"
: "0"
,
"err_handler_schd_num"
: "0"
,
"rq_cq_max_count"
: "0"
,
"rq_cq_period"
: "0"
,
"rq_cq_period_mode"
: "1"
}
]
}
}
输出分为两个部分。
第一个部分,用
device
包裹,是设备详细信息以及数据包计数器静态启用状态。条目
类型
描述
device
字符串
此部分下的条目是每个设备的信息
pf_id
字符串
物理功能 ID
packet_counters
字符串
数据包计数器功能:已启用/已禁用
第二个部分,用
queues-stats
包裹,是每个接收 VQ 的信息。条目
类型
描述
VQ 索引
数字
VQ 索引从 0(第一个 RQ)开始,一直到最后一个 SQ
rx_64_or_less_octet_packets
数字
接收到的数据包大小为 0 到 64 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_65_to_127_octet_packets
数字
接收到的数据包大小为 65 到 127 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_128_to_255_octet_packets
数字
接收到的数据包大小为 128 到 255 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_256_to_511_octet_packets
数字
接收到的数据包大小为 256 到 511 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_512_to_1023_octet_packets
数字
接收到的数据包大小为 512 到 1023 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_1024_to_1522_octet_packets
数字
接收到的数据包大小为 1024 到 1522 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_1523_to_2047_octet_packets
数字
接收到的数据包大小为 1523 到 2047 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_2048_to_4095_octet_packets
数字
接收到的数据包大小为 2048 到 4095 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_4096_to_8191_octet_packets
数字
接收到的数据包大小为 4096 到 8191 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
rx_8192_to_9022_octet_packets
数字
接收到的数据包大小为 8192 到 9022 字节的数据包数量。当 数据包计数器 启用时,与 BlueField-3 RQ 相关。
received_desc
数字
设备在此 VQ 上接收到的描述符总数
completed_desc
数字
设备在此 VQ 上完成的描述符总数
bad_desc_errors
数字
在此 VQ 上接收到的错误描述符总数
error_cqes
数字
此 VQ 上错误 CQ 条目的总数
exceed_max_chain
数字
接收到的链式描述符总数,超过设备允许的最大链长度
invalid_buffer
数字
设备尝试读取或写入未注册到设备的缓冲区的总次数
batch_number
数字
上次接收的数据包的 RX 描述符数。与 BlueField-3 相关。
dma_q_used_number
数字
用于此 VQ 的 DMA q 索引。与 BlueField-3 相关。
handler_schd_number
数字
此 VQ 的调度器编号。与 BlueField-3 相关。
aux_handler_schd_number
数字
Aux 调度器编号。与 BlueField-3 相关。
max_post_desc_number
数字
此 VQ 上发布的最大描述符数。与 DPA 相关。
total_bytes
数字
此 VQ 处理的字节总数。与 BlueField-3 相关。
rq_cq_max_count
数字
队列的事件生成节制计数器。与 RQ 相关。
rq_cq_period
数字
队列的事件生成节制计时器,单位为 1 微秒粒度。与 RQ 相关。
rq_cq_period_mode
数字
RQ 的当前周期模式
0x0 –
default_mode
– 使用设备最佳默认值0x1 –
upon_event
–queue_period
计时器在事件生成时重新启动0x2 –
upon_cqe
–queue_period
计时器在完成生成时重新启动
用 queues-stats 包裹的第二个部分是每个接收 VQ 的信息。
VQ 统计信息
要查询 Rx VQ 统计信息,请使用相应的 VQ 索引。例如,如果配置了 3 个队列,则查询 Rx 使用队列 0,Tx VQ 使用队列 1,Ctrl VQ 使用队列 2。
以下是查询 PF 0、VF 0 和 VQ 0(即 Rx)的命令。
[dpu]# virtnet query -p 0
-v 0
-q 0
输出
"enabled-queues-info"
: [
{
"index"
: "0"
,
"size"
: "256"
,
"msix_vector"
: "0x1"
,
"enable"
: "1"
,
"notify_offset"
: "0"
,
"descriptor_address"
: "0xffffe000"
,
"driver_address"
: "0xfffff000"
,
"device_address"
: "0xfffff240"
,
"received_desc"
: "256"
,
"completed_desc"
: "19"
,
"bad_desc_errors"
: "0"
,
"error_cqes"
: "0"
,
"exceed_max_chain"
: "0"
,
"invalid_buffer"
: "0"
,
"batch_number"
: "64"
,
"dma_q_used_number"
: "0"
,
"handler_schd_number"
: "4"
,
"aux_handler_schd_number"
: "3"
,
"max_post_desc_number"
: "0"
,
"total_bytes"
: "6460"
,
"rq_cq_max_count"
: "0"
,
"rq_cq_period"
: "0"
,
"rq_cq_period_mode"
: "1"
}
以下是一些重要的 VQ 计数器
计数器名称 | 描述 |
| 接收的字节数 |
| 设备接收到的可用描述符数量 |
| 设备完成的可用描述符数量 |
| 队列上接收到的错误 CQE 数量 |
| 接收到的错误描述符数量 |
| 接收到的链式描述符数量,超过设备允许的最大链长度 |
| 设备尝试读取或写入未注册到设备的缓冲区的次数 |
RQ 丢包计数器
当 DPA 是数据路径提供程序时,每个 RQ 都有其对应的丢包计数器,用于计算 DPA virtio RQ 内部丢弃的数据包数量。
丢包也可能来自上行链路或 SF。
丢包计数器仅递增(初始值为 0),并且在禁用时其值重置为 0。
RQ 丢包计数器可以按如下方式启用和禁用(在 PF 0 上使用 VF 0)
[dpu]# virtnet modify -p 0
-v 0
device -dc enable
[dpu]# virtnet modify -p 0
-v 0
device -dc disable
丢包计数器附加到 RQ,因此必须首先创建 RQ。这意味着 virtio-net 设备应在主机操作系统上由驱动程序探测,然后再运行上述命令。
要查询丢包计数器值,请运行
[dpu]# virtnet query -p 0
-v 0
| grep num_desc_drop_pkts
如果一个设备有多个 RQ,则丢包计数是所有 RQ 值的总和。
数据包计数器
仅与 BlueField-3 相关。
数据包计数器功能帮助用户查询每个 Rx 队列的按字节数据包计数器。
默认情况下,按字节数据包计数器被禁用,因为这会对性能产生负面影响。当用户对调试感兴趣时,请使用以下命令启用数据包计数器功能
数据包计数器可以按如下方式启用和禁用(在 PF 0 上使用 VF 0)
[dpu]# virtnet modify -p 0
-v 0
device -pkt_cnt enable
[dpu]# virtnet modify -p 0
-v 0
device -pkt_cnt disable
启用后,按字节数据包计数器将初始化为零。
禁用后,将保留先前的值以用于调试目的。该命令仍将返回这些旧的、禁用的计数器值。
数据包计数器附加到 RQ。因此,必须首先创建 RQ。这意味着 virtio-net 设备应在主机操作系统上被驱动程序探测,然后再运行上述命令。
健康统计信息
仅与 BlueField-3 相关。
健康统计信息用于显示特定设备的实时健康信息。
输出示例(在 PF 0 上使用 VF 0)
[dpu]# virtnet health -p 0
-v 0
show
{
"pf_id"
: 0
,
"vf_id"
: 0
,
"type"
: "VF"
,
"vuid"
: "MT2306XZ00BPVNETS0D0F2"
,
"dev_status"
: {
"value"
: "0xf"
,
" 0"
: "ACK"
,
" 1"
: "DRIVER"
,
" 2"
: "DRIVER_OK"
,
" 3"
: "FEATURES_OK"
},
"health_status"
: "Good"
,
"health_recover_counter"
: 0
,
"dev_health_details"
: {
"control_plane_errors"
: {
"sf_rqt_update_err"
: 0
,
"sf_drop_create_err"
: 0
,
"sf_tir_create_err"
: 0
,
"steer_rx_domain_err"
: 0
,
"steer_rx_table_err"
: 0
,
"sf_flows_apply_err"
: 0
,
"aarfs_flow_init_err"
: 0
,
"vlan_flow_init_err"
: 0
,
"drop_cnt_config_err"
: 0
},
"data_plane_errors"
: {
"sq_stall"
: 0
,
"dma_q_stall"
: 0
,
"spurious_db_invoke"
: 0
,
"aux_not_invoked"
: 0
,
"dma_q_errors"
: 0
,
"host_read_errors"
: 0
}
}
其中
health_status
表示设备的总体状态(Good
或Fatal
)dev_health_details
有两个部分,control_plane_errors
和data_plane_errors
,如下表所述计数器名称
描述
控制平面错误
sf_rqt_update_err
计数接收队列表更新失败的次数
sf_drop_create_err
计数丢弃 RQ 创建失败的次数
sf_tir_create_err
计数 TIR 创建失败的次数
steer_rx_domain_err
计数 RX 转向规则创建失败的次数
steer_rx_table_err
计数 RX 表创建失败的次数
sf_flows_apply_err
计数数据包流规则创建失败的次数
aarfs_flow_init_err
计数数据包流初始化失败的次数
vlan_flow_init_err
计数 VLAN 流规则初始化失败的次数
drop_cnt_config_err
计数丢包计数器配置失败的次数
数据平面错误
sq_stall
一个或多个网络发送队列停滞,没有收到完成信号。这会导致流经此 VQ 的数据包停滞。
dma_q_stall
与自身配对的 QP 向 DPA 发出从主机读取可用索引或描述符表的读取请求。此请求不会产生完成信号,并陷入循环等待响应。
spurious_db_invoke
Doorbell 处理程序被重复调用,但 DPA 发现没有新的数据要读取和发布。这可能是由于驱动程序故障或 DPA 侧的问题。
aux_not_invoked
为了加速描述符处理,如果可用,则使用辅助执行 (EU) 单元。主线程调用此 EU 并等待预期线程在辅助执行单元上运行。如果未调用此 EU,则主线程挂起。
dma_q_errors
与自身配对的 QP 向 DPA 发出从主机读取可用索引或描述符表的读取请求。此请求导致错误,并且 QP 变得不可用。内部机制检测到此错误 QP,并在稍后阶段回收以供使用。
动态中断节制
动态中断节制 (DIM) 调整中断节制设置以优化数据包处理。对于版本低于 6.8 的 guest OS 内核,DIM 将此功能卸载到 DPU,从而降低来自 guest OS 的中断率。
通过降低高带宽流量场景中的中断率,DIM 提高了 hypervisor 和 guest VM 的 CPU 利用率,同时保持几乎相同的带宽。
DIM 仅在 BlueField-3 上受支持。
例如,下表显示了使用 DIM 的好处
Tx 中断率 (K irq/s) | Rx 中断率 (K irq/s) | Tx 吞吐量 (Gb/s) | Rx 吞吐量 (Gb/s) | |
DIM 已启用 | 7.3 | 7.5 | 171 | 181 |
DIM 已禁用 | 7.5 | 23.7 | 175 | 181 |
以下测试参数
Guest OS 内核版本 – 5.11.0
virtio-net 设备数量 – 1
QP 数量 – 31
队列深度 – 1024
MTU – 1500
基准测试 – 具有 31 个流的 iPerf
配置 DIM
DIM 是每个设备的配置。要启用或禁用它,请使用此命令
[dpu]# virtnet modify -p <pf> [-v <vf>] device -dim {enable | disable}
配置示例
从 guest-OS 端卸载驱动程序
[host]# modprobe -rv virtio_net && modprobe -rv virtio_pci
启用 DIM
[dpu]# virtnet modify -p 0 device -dim enable {'pf': '0x0', 'all': '0x0', 'subcmd': '0x0', 'dim_config': 'enable'} { "errno": 0, "errstr": "Success" }
信息使用
disable
禁用 DIM。加载驱动程序
[host]# modprobe -v virtio_pci && modprobe -v virtio_net
查询设备以验证
dim
是否已启用[dpu]# virtnet query -p 0 -b | grep -i dim "dim": "enabled"
高可用性
高可用性 (HA) 在网络基础设施中至关重要,以确保即使在发生故障时也能保持持续性能和最短的停机时间。
为了支持 HA,virtio-net-controller
进程创建辅助进程 virtio-net-emu
和 virtio-net-ha
。virtio-net-emu
进程处理主控制器功能,而 virtio-net-ha
管理 HA。virtio-net-ha
保存并监督来自 virtio-net-emu
的关键资源,并在发生故障时将其恢复到工作状态。这两个进程通过 IPC 消息进行通信。

高可用性仅在 BlueField-3 及更高版本上受支持。
下表提供了可能的预期行为
巨型 MTU
巨型 MTU 对于提高以太网和网络处理效率至关重要,它通过减少协议开销(标头和有效负载大小的比率)来实现。
要启用对巨型 MTU 的支持,请运行以下 virtnet 命令
[dpu]# virtnet modify -p 0 -v 0 device -t 9216
该示例将 PF 0 上 VF 0 的 MTU 设置为 9126。
巨型 MTU 仅从以下版本开始受支持
版本 | |
上游 | VM kernel: 4.18.0-193.el8.x86_64 (VM Linux 版本在 4.11 之后支持大型 MTU) |
Ubuntu | DOCA_2.5.0_BSP_4.5.0_Ubuntu_22.04 |
Virtnet 控制器 | v1.7 或 v1.6.26 |
要配置巨型 MTU(例如,在 PF 0 上使用 VF 0)
从 BlueField 更改上行链路和 SF 表示的 MTU
[dpu]# ifconfig p0 mtu 9216 [dpu]# ifconfig en3f0pf0sf3000 mtu 9216
如果配置了 bond,则更改 bond 的 MTU,而不是
p0
[dpu]# ifconfig bond0 mtu
9216
[dpu]# ifconfig en3f0pf0sf3000 mtu9216
从 BlueField 重启 virtio-net-controller
[dpu]# systemctl restart virtio-net-controller
从主机操作系统卸载 virtio 驱动程序
[host]# modprobe -rv virtio-net
在 BlueField 上更改相应的设备 MTU
[dpu]# virtnet modify -p 0 -v 0 device -t 9216
从主机操作系统重新加载 virtio 驱动程序
[host]# modprobe -v virtio-net
检查 virtqueue MTU 配置在 BlueField 上是否正确
[dpu]# virtnet query -p 0 -v 0 --dbg_stats | grep jumbo_mtu "jumbo_mtu": 1 "jumbo_mtu": 1
从主机操作系统更改 virtio-net 接口的 MTU
[host]# ifconfig <vnet> mtu 9216
链路聚合
通常使用链路聚合 (LAG) 或 bond 接口来提高网络设备的可靠性、可用性或带宽。Virtio-net 设备通过 DPU 侧 LAG 配置支持此模式。
要在 LAG 模式下配置 virtio-net-controller,必须遵循特定的步骤,因为这依赖于 mlx5 RDMA 设备
停止 virtio-net-controller 以避免资源泄漏(这将由 LAG 销毁现有 mlx5 RDMA 设备并创建新的 bond RDMA 设备引起)。
[dpu]# systemctl stop virtio-net-controller.service
为 DPU 侧的两个上行链路接口配置 LAG 接口。有关详细步骤,请参阅“链路聚合”页面。
注意virtio-net-controller 服务默认启动。如果在 LAG 配置期间 DPU 重新启动,则必须在从 DPU 侧创建 bond 接口之前停止控制器。
更新控制器配置文件以使用 bond 接口。
[dpu]# cat /opt/mellanox/mlnx_virtnet/virtnet.conf { "ib_dev_lag": "mlx5_bond_0", "ib_dev_for_static_pf": "mlx5_bond_0", "is_lag": 1, }
信息有关详细信息,请参阅“配置文件”页面。
启动控制器以使新配置生效。
[dpu]# systemctl start virtio-net-controller.service
实时迁移
使用 vHost 加速软件堆栈进行实时迁移
Virtio VF PCIe 设备可以使用 vhost 加速软件堆栈连接到 guest VM。这使得可以执行 guest VM 的实时迁移。

本节提供了使用 virtio VF PCIe 设备和 vhost 加速软件启用 VM 实时迁移的步骤。

先决条件
最低 hypervisor 内核版本 – Linux kernel 5.15(用于 VFIO SR-IOV 支持)
要使用高可用性(附加的
vfe-vhostd-ha
服务,可以在vfe-vhostd
崩溃时持久化数据路径),必须应用 此 内核补丁。
安装 vHost 加速软件堆栈
vHost 加速软件堆栈使用开源 BSD 许可的 DPDK 构建。
要安装 vhost 加速软件
克隆软件源代码
[host]# git clone https://github.com/Mellanox/dpdk-vhost-vfe
信息最新的发布标签是
vfe-24.10.0-rc2
。构建软件
[host]# apt-get install libev-dev -y [host]# apt-get install libev-libevent-dev -y [host]# apt-get install uuid-dev -y [host]# apt-get install libnuma-dev -y [host]# meson build --debug -Denable_drivers=vdpa/virtio,common/virtio,common/virtio_mi,common/virtio_ha [host]# ninja -C build install
要安装 QEMU
信息可以使用 8.1 以上的上游 QEMU 或以下 NVIDIA QEMU。
克隆 NVIDIA QEMU 源代码。
[host]# git clone git@github.com:Mellanox/qemu.git -b stable-8.1-presetup [host]# git checkout 24aaba9255
信息最新的稳定提交是
24aaba9255
。构建 NVIDIA QEMU。
[host]# mkdir bin [host]# cd bin [host]# ../configure --target-list=x86_64-softmmu --enable-kvm [host]# make -j24
在 Hypervisor 上配置 vHost
配置 1G 巨页
[host]# mkdir /dev/hugepages1G [host]# mount -t hugetlbfs -o pagesize=1G none /dev/hugepages1G [host]# echo 16 > /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages [host]# echo 16 > /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages
通过添加
xmlns:qemu
选项在 VM XML 中启用qemu:commandline
<
domain
type
='kvm'
xmlns:qemu
='http://libvirt.org/schemas/domain/qemu/1.0'
>在 VM XML 中分配内存量并使用 1GB 页面大小作为巨页
<
memory
unit
='GiB'
>4</memory
> <currentMemory
unit
='GiB'
>4</currentMemory
> <memoryBacking
> <hugepages
> <page
size
='1'
unit
='GiB'
/> </hugepages
> </memoryBacking
>将 CPU 的内存访问设置为共享
<
cpu
mode
='custom'
match
='exact'
check
='partial'
> <model
fallback
='allow'
>Skylake-Server-IBRS</model
> <numa
> <cell
id
='0'
cpus
='0-1'
memory
='4'
unit
='GiB'
memAccess
='shared'
/> </numa
> </cpu
>在 VM XML 中添加 virtio-net 接口
<
qemu
:commandline> <qemu
:argvalue
='-chardev'
/> <qemu
:argvalue
='socket,id=char0,path=/tmp/vhost-net0,server=on'
/> <qemu
:argvalue
='-netdev'
/> <qemu
:argvalue
='type=vhost-user,id=vhost1,chardev=char0,queues=4'
/> <qemu
:argvalue
='-device'
/> <qemu
:argvalue
='virtio-net-pci,netdev=vhost1,mac=00:00:00:00:33:00,vectors=10,page-per-vq=on,rx_queue_size=1024,tx_queue_size=1024,mq=on,disable-legacy=on,disable-modern=off'
/> </qemu
:commandline>
运行 vHost 加速服务
将 virtio PF 设备绑定到
vfio-pci
驱动程序[host]# modprobe vfio vfio_pci [host]# echo 1 > /sys/module/vfio_pci/parameters/enable_sriov [host]# echo 0x1af4 0x1041 > /sys/bus/pci/drivers/vfio-pci/new_id [host]# echo 0x1af4 0x1042 > /sys/bus/pci/drivers/vfio-pci/new_id [host]# echo <pf_bdf> > /sys/bus/pci/drivers/virtio-pci/unbind [host]# echo <vf_bdf> > /sys/bus/pci/drivers/virtio-pci/unbind [host]# echo <pf_bdf> > /sys/bus/pci/drivers/vfio-pci/bind [host]# echo <vf_bdf> > /sys/bus/pci/drivers/vfio-pci/bind [host]# lspci -vvv -s <pf_bdf> | grep "Kernel driver" Kernel driver in use: vfio-pci [host]# lspci -vvv -s <vf_bdf> | grep "Kernel driver" Kernel driver in use: vfio-pci
信息<pf_bdf>
或<vf_bdf>
格式示例:0000:af:00.3
通过启动
vfe-vhostd
服务来运行 vhost 加速软件服务[host]# systemctl start vfe-vhostd
信息可以通过运行以下命令查看服务日志
[host]# journalctl -u vfe-vhostd
配置 virtio-net PF
[host]# /usr/local/bin/vfe-vhost-cli mgmtpf -a <pf_bdf>
等待 virtio-net-controller 完成处理 PF FLR。
启用 SR-IOV 并创建一个 VF(或更多)
[host]# echo 1 > /sys/bus/pci/devices/<pf_bdf>/sriov_numvfs [host]# lspci | grep Virtio 0000:af:00.1 Ethernet controller: Red Hat, Inc. Virtio network device 0000:af:00.3 Ethernet controller: Red Hat, Inc. Virtio network device
将 VF 表示添加到 BlueField 上的 OVS 桥接器
[dpu]# virtnet query -p 0 -v 0 | grep sf_rep_net_device "sf_rep_net_device": "en3f0pf0sf3000", [dpu]# ovs-vsctl add-port ovsbr1 en3f0pf0sf3000
配置 virtio-net VF
在 BlueField 上,更改 VF MAC 地址或其他设备选项
[dpu]# virtnet modify -p
0
-v0
device -m00
:00
:00
:00
:33
:00
将 VF 添加到 vfe-dpdk
[host]# /usr/local/bin/vfe-vhost-cli vf -a <vf_bdf> -v /tmp/vhost-net0
注意如果 SR-IOV 被禁用并重新启用,则用户必须重新配置 VF。
00:00:00:00:33:00
是 VM XML 中使用的虚拟 MAC 地址。
启动 VM
[host]# virsh start <vm_name>
HA 服务
运行 vfe-vhostd-ha
服务允许在 vfe-vhostd
崩溃时持久化数据路径
[host]# systemctl start vfe-vhostd-ha
简单实时迁移
准备两台相同的主机,并在两台主机上执行 virtio 设备到 DPDK 的配置。
在一台服务器上启动 VM
[host]# virsh migrate --verbose --live --persistent <vm_name> qemu+ssh://<dest_node_ip_addr>/system --unsafe
移除设备
完成 virtio 设备后,使用以下命令从 DPDK 中移除它们
[host]# /usr/local/bin/vfe-vhost-cli vf -r <vf_bdf>
[host]# /usr/local/bin/vfe-vhost-cli mgmtpf -r <pf_bdf>
在线更新
在线更新通过执行 virtio-net 控制器的在线升级来最大限度地减少网络接口停机时间,而无需完全重启。
要求
要执行在线更新,用户必须安装较新版本的控制器,可以使用 rpm
或 deb
包(取决于所使用的 OS 发行版)。运行
对于 Ubuntu/Debian |
|
对于 CentOS/RedHat |
|
检查版本
在开始在线更新之前,可以使用以下命令检查原始控制器和目标控制器的版本
[dpu]# virtnet version
{
"Original Controller": "v24.10.13"
},
{
"Destination Controller": "v24.10.16"
}
开始更新
如果未发生错误,请发出以下命令以启动在线更新过程
[dpu]# virtnet update -s
如果错误指示 update
命令不受支持,则表示您尝试安装的控制器版本已过时。重新安装正确的版本可以解决此问题。
检查状态
在更新过程中,可以使用以下命令检查更新状态
[dpu]# virtnet update -t
输出示例
{
"status": "inactive", # updating status, whether live update is finished or ongoing
"last live update status": "success", # last live update status
"time_used (s)": 1.655439 # time cost for last live update
}
在更新期间,建议不要发出任何 virtnet CLI 命令。
当更新过程成功完成时,命令 virtnet update status
将相应地反映状态
如果设备正在主动迁移,则对于该特定设备,现有的 virtnet
命令显示为“migrating”,以便用户可以稍后重试。
当在线更新正在进行时,不支持热插拔/拔出和 VF 创建/删除。
可合并 Rx 缓冲区
在与驱动程序协商时,可合并缓冲区是一种模式,其中发布多个描述符以适应来自线路的单个巨型大小的数据包。这是一个仅接收侧的功能,有助于提高大型 MTU(例如,9K)情况下的性能。
启用和使用可合并缓冲区需要更新配置文件,并从控制器侧通告功能位,如下面的小节所述。
启用/禁用可合并缓冲区
要启用或禁用可合并 Rx 缓冲区功能,请将 virtnet.conf
配置文件中的 mrg_rxbuf
属性设置为 1
或 0
。
例如,要启用可合并 Rx 缓冲区
[dpu]# cat /opt/mellanox/mlnx_virtnet/virtnet.conf
{
...
"mrg_rxbuf": 1
...
}
更新配置文件需要重启 virtio-net-controller。
有关更多信息,请参阅“配置文件”页面。
配置设备
可合并缓冲区是每个设备的功能。
用户必须查询设备以检查
VIRTIO_F_MRG_RX_BUFFER
是否可用。例如,以下 PF 0 不支持可合并缓冲区[dpu]# virtnet query -p 0 -b {'all': '0x0', 'pf': '0x0', 'dbg_stats': '0x0', 'brief': '0x1', 'latency_stats': '0x0', 'stats_clear': '0x0'} { "devices": [ { "pf_id": 0, "transitional": 0, "vuid": "MT2251X00020VNETS1D0F0", "pci_bdf": "86:00.0", "pci_dev_id": "0x1041", "pci_vendor_id": "0x1af4", "pci_class_code": "0x20000", "pci_subsys_id": "0x1", "pci_subsys_vendor_id": "0x1af4", "pci_revision_id": "1", "pci_max_vfs": "0", "enabled_vfs": "0", "device_feature": { "value": "0x8900010300e7182f", " 0": "VIRTIO_NET_F_CSUM", " 1": "VIRTIO_NET_F_GUEST_CSUM", " 2": "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS", " 3": "VIRTIO_NET_F_MTU", " 5": "VIRTIO_NET_F_MAC", " 11": "VIRTIO_NET_F_HOST_TSO4", " 12": "VIRTIO_NET_F_HOST_TSO6", " 16": "VIRTIO_NET_F_STATUS", " 17": "VIRTIO_NET_F_CTRL_VQ", " 18": "VIRTIO_NET_F_CTRL_RX", " 21": "VIRTIO_NET_F_GUEST_ANNOUNCE", " 22": "VIRTIO_NET_F_MQ", " 23": "VIRTIO_NET_F_CTRL_MAC_ADDR", " 32": "VIRTIO_F_VERSION_1", " 33": "VIRTIO_F_IOMMU_PLATFORM", " 40": "VIRTIO_F_RING_RESET", " 56": "VIRTIO_NET_F_HOST_USO", " 59": "VIRTIO_NET_F_GUEST_HDRLEN", " 63": "VIRTIO_NET_F_SPEED_DUPLEX" }, ... }
要启用该功能
确保 guest-OS 端未加载任何驱动程序
[host]# modprobe -rv virtio_net && modprobe -rv virtio_pci
将功能位中的第 15 位设置为
1
,并修改设备[dpu]# virtnet modify -p 0 device -f 0x8900010300e7982f {'pf': '0x0', 'all': '0x0', 'subcmd': '0x0', 'features': '0x8900010300e7982f'} { "errno": 0, "errstr": "Success" }
从主机加载驱动程序
[host]# modprobe -v virtio_pci && modprobe -v virtio_net
再次查询设备,检查
VIRTIO_F_MRG_RX_BUFFER
是否可用。以下查询显示device_feature
和driver_feature
下的VIRTIO_F_MRG_RX_BUFFER
。现在,PF 0 上已启用可合并缓冲区。[dpu]# virtnet query -p 0 -b {'all': '0x0', 'pf': '0x0', 'dbg_stats': '0x0', 'brief': '0x1', 'latency_stats': '0x0', 'stats_clear': '0x0'} { "devices": [ { "pf_id": 0, "transitional": 0, "vuid": "MT2251X00020VNETS0D0F1", "pci_bdf": "85:00.1", "pci_dev_id": "0x1041", "pci_vendor_id": "0x1af4", "pci_class_code": "0x20000", "pci_subsys_id": "0x1041", "pci_subsys_vendor_id": "0x1af4", "pci_revision_id": "1", "pci_max_vfs": "0", "enabled_vfs": "0", "device_feature": { "value": "0x8900032300e7982f", " 0": "VIRTIO_NET_F_CSUM", " 1": "VIRTIO_NET_F_GUEST_CSUM", " 2": "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS", " 3": "VIRTIO_NET_F_MTU", " 5": "VIRTIO_NET_F_MAC", " 11": "VIRTIO_NET_F_HOST_TSO4", " 12": "VIRTIO_NET_F_HOST_TSO6", " 15": "VIRTIO_F_MRG_RX_BUFFER", " 16": "VIRTIO_NET_F_STATUS", " 17": "VIRTIO_NET_F_CTRL_VQ", " 18": "VIRTIO_NET_F_CTRL_RX", " 21": "VIRTIO_NET_F_GUEST_ANNOUNCE", " 22": "VIRTIO_NET_F_MQ", " 23": "VIRTIO_NET_F_CTRL_MAC_ADDR", " 32": "VIRTIO_F_VERSION_1", " 33": "VIRTIO_F_IOMMU_PLATFORM", " 37": "VIRTIO_F_SR_IOV", " 40": "VIRTIO_F_RING_RESET", " 41": "VIRTIO_F_ADMIN_VQ", " 56": "VIRTIO_NET_F_HOST_USO", " 59": "VIRTIO_NET_F_GUEST_HDRLEN", " 63": "VIRTIO_NET_F_SPEED_DUPLEX" }, "driver_feature": { "value": "0x8000002300e7982f", " 0": "VIRTIO_NET_F_CSUM", " 1": "VIRTIO_NET_F_GUEST_CSUM", " 2": "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS", " 3": "VIRTIO_NET_F_MTU", " 5": "VIRTIO_NET_F_MAC", " 11": "VIRTIO_NET_F_HOST_TSO4", " 12": "VIRTIO_NET_F_HOST_TSO6", " 15": "VIRTIO_F_MRG_RX_BUFFER", " 16": "VIRTIO_NET_F_STATUS", " 17": "VIRTIO_NET_F_CTRL_VQ", " 18": "VIRTIO_NET_F_CTRL_RX", " 21": "VIRTIO_NET_F_GUEST_ANNOUNCE", " 22": "VIRTIO_NET_F_MQ", " 23": "VIRTIO_NET_F_CTRL_MAC_ADDR", " 32": "VIRTIO_F_VERSION_1", " 33": "VIRTIO_F_IOMMU_PLATFORM", " 37": "VIRTIO_F_SR_IOV", " 63": "VIRTIO_NET_F_SPEED_DUPLEX" }, ... }
限制
每个工作队列条目的描述符数量取决于 MTU 大小。为了获得最佳性能,如果 MTU 设置为默认值 (1500),建议不要启用此功能。
当从线路接收小尺寸数据包(例如,64 字节)时,预计此功能的性能会下降。
可合并缓冲区不适用于 packed VQ 功能。
NetDIM
NetDIM 仅在 BlueField-3 上受支持
网络动态中断节制 (netDIM) 调整中断节制设置以优化数据包处理。此功能将 DIM 卸载到 virtio PCIe 设备,从而为 guest 内核中缺少 netDIM 支持的 virtio-net 设备启用 DPU 上的中断节制。
通过降低高带宽流量期间的中断率,DIM 提高了 hypervisor 和 guest VM 的 CPU 利用率,同时保持几乎相同的带宽。
启用/禁用 NetDIM
要启用或禁用 netDIM,请使用以下 virtnet 命令
[dpu]# virtnet modify -p <> -v <> device -netdim {enable,disable}
启用或禁用 netDIM 需要驱动程序未加载。
配置 NetDIM
NetDIM 是按设备启用的。
要启用 netDIM
确保 guest-OS 端未加载任何驱动程序
[host]# modprobe -rv virtio_net && modprobe -rv virtio_pci
通过在相应设备上使用 virtnet 命令来启用 netDIM
[dpu]# virtnet modify -p 0 device -netdim enable {'pf': '0x0', 'all': '0x0', 'subcmd': '0x0', 'net_dim_config': 'enable'} { "errno": 0, "errstr": "Success" }
加载驱动程序
[host]# modprobe -v virtio_pci && modprobe -v virtio_net
查询设备以检查是否启用了
netdim
[dpu]# virtnet query -p 0 -b {'all': '0x0', 'pf': '0x0', 'dbg_stats': '0x0', 'brief': '0x1', 'latency_stats': '0x0', 'stats_clear': '0x0'} { "devices": [ { "pf_id": 0, "function_type": "static PF", "transitional": 0, ... ... "aarfs": "disabled", "netdim": "enabled" } ] }
性能调优
队列数量和 MSIX
驱动程序配置
virtio-net 驱动程序可以通过 ethtool 配置组合通道的数量。这决定了 netdev 可以使用多少 virtqueue (VQ)。通常,当多线程时(例如,具有多个流的 iPerf),更多的 VQ 会产生更好的总体吞吐量。
[host]# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX: n/a
TX: n/a
Other: n/a
Combined: 31
Current hardware settings:
RX: n/a
TX: n/a
Other: n/a
Combined: 15
因此,通常使用以下命令选择较大的通道数量(小于预设的最大值)。
通常,将组合通道的数量配置为与 guest OS 上可用的 CPU 数量相同将产生良好的性能。
[host]# ethtool -L eth0 combined 31
[host]# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX: n/a
TX: n/a
Other: n/a
Combined: 31
Current hardware settings:
RX: n/a
TX: n/a
Other: n/a
Combined: 31
设备配置
为了达到最佳性能,需要确保每个 tx/rx 队列都分配了 MSIX。检查特定设备的信息,并确保 num_queues
小于 num_msix
。
[dpu]# virtnet query -p 0 -b | grep -i num_
"num_msix": "64",
"num_queues": "8",
如果 num_queues
大于 num_msix
,则需要更改 mlxconfig 以保留比队列更多的 MSIX。这由 VIRTIO_NET_EMULATION_NUM_VF_MSIX
和 VIRTIO_NET_EMULATION_NUM_MSIX
决定。请参阅“Virtio-net 部署”页面以获取更多信息。
队列深度
默认情况下,队列深度设置为 256。通常使用更大的队列深度(例如,1024)。这不能从驱动程序侧请求,但必须从设备侧完成。
请参阅“Virtnet CLI 命令”页面,了解如何修改设备 max_queue_size
。
MTU
为了提高性能,用户可以使用巨型 MTU。有关 MTU 配置的信息,请参阅“巨型 MTU”页面。
恢复
恢复对于控制器重启、在线更新或实时迁移等情况下的状态恢复(控制平面和数据平面)至关重要。
恢复过程依赖于存储在 /opt/mellanox/mlnx_virtnet/recovery
中的 JSON 文件,其中每个设备(PF 或 VF)都有一个以其唯一 VUID 命名的对应文件。
以下条目将保存到恢复文件并在必要时恢复
条目 | 类型 | 描述 |
| 字符串 | 在其上创建 virtio-net 设备的 RDMA 设备名称 |
| 数字 | pf_id |
| 数字 | vf_id |
| 字符串 | VF 的 ID,仅对 VF 有效 |
| 数字 | PF 或 VF |
| 字符串 | Virtio-net 设备 bus:device:function,uint16 类型 |
| 字符串 | device_type |
| 数字 | mac |
| 数字 | 设备的 MAC 地址 |
| 数字 | PCIe 功能号 |
sf_num
{
"port_ib_dev": "mlx5_0",
"pf_id": 0,
"function_type": "pf",
"bdf_raw": 57611,
"device_type": "hotplug",
"mac": "0c:c4:7a:ff:22:93",
"pf_num": 0,
"sf_num": 2000,
"mq": 3
}
用例
用于此 virtio-net 设备的 SF 编号
mq | 为此 virtio-net 设备创建的多队列数量 | |||||||
热插拔 PF 设备的恢复文件示例 | 实时更新 | 根据 BlueField 或主机的操作,可能会或可能不会执行恢复。请参阅下表以了解个别场景 | DPU 操作 | 主机操作 | 重启控制器 | 热拔出 | 实时迁移 | |
| 销毁 VF | 销毁 VF | N/A | N/A | 销毁 VF | 卸载驱动程序 | 销毁 VF | 销毁 VF |
| 销毁 VF | 销毁 VF | 卸载驱动程序 | N/A | 销毁 VF | 卸载驱动程序 | 销毁 VF | 销毁 VF |
| 销毁 VF | 销毁 VF | N/A | 主机和 DPU 断电重启 | 温重启 | 卸载驱动程序 | 卸载驱动程序 | 销毁 VF |
恢复
不恢复
恢复文件已删除
不恢复
这些恢复文件是控制器的内部文件,不应修改。
默认情况下启用控制器恢复,无需用户配置或干预。当控制器使用的 mlxconfig
设置生效时,新启动的控制器服务会自动删除所有恢复文件。
过渡设备
过渡设备是一种 virtio 设备,它支持符合 virtio 规范 1.x
的驱动程序和在 virtio 规范 0.95
(即,传统模式)下运行的旧驱动程序,因此具有旧 Linux 内核的服务器仍然可以使用基于 virtio 的技术。
过渡 Virtio-net VF 设备
当前,仅支持过渡 VF 设备。
主机内核版本必须高于 v6.9。
[dpu]# cat /opt/mellanox/mlnx_virtnet/virtnet.conf { ... "lm_prov": "kernel", ... }
使用此功能时,将无法再使用 vfe-vdpa-dpdk 解决方案,包括 vfe-vdpa-dpdk 实时迁移。
[dpu]# systemctl restart virtio-net-controller.service
Libvirt 不支持
virtio_vfio_pci
内核驱动程序。请改用 QEMU 命令行启动 VM。[host]# modprobe -v virtio_pci [host]# modprobe -v virtio_net [host]# echo <vf_num> > /sys/bus/pci/devices/<pf_bdf>/sriov_numvfs
配置 virtio-net SR-IOV。有关详细信息,请参阅“Virtio-net 部署”。
[host]# echo <vf_bdf> > /sys/bus/pci/devices/<vf_bdf>/driver/unbind [host]# echo 0x1af4 0x1041 > /sys/bus/pci/drivers/virtio_vfio_pci/new_id [host]# modprobe -v virtio_vfio_pci [host]# lspci -s <vf_bdf> -vvv | grep -i virtio_vfio_pci Kernel driver in use: virtio_vfio_pci
修改配置文件以添加
"lm_prov": "kernel"
选项。-device vfio-pci,host=<vf_bdf>,id=hostdev0,bus=pci.<#BUS_IN_VM>,addr=<#FUNC_IN_VM>
重启 virtio-net 控制器以使配置生效
[vm]# modprobe -v virtio_pci force_legacy=1 [vm]# modprobe -v virtio_net [vm]# lspci -s <vf_bdf_in_vm> -n 00:0a.0 0200: 1af4:1000
在主机上创建 virtio-net VF 设备
[dpu]# virtnet query -p <pf_id> -v <vf_id> | grep transitional "transitional": 1,
将 VF 设备与 virtio_vfio_pci
内核驱动程序绑定
将以下选项添加到 QEMU 命令行,以将 VF 设备透传到 VM
在 VM 内部以传统模式加载 virtio-net 驱动程序
验证 VF 是否为过渡设备

固件配置
VF 动态 MSIX
在 virtio-net 控制器中,每个 VF 获得相同数量的 MSIX 和 virtqueue (VQ),以便每个数据 VQ 都分配有一个 MSIX。这意味着更改 MSIX 的数量会更新 VQ 的数量。
默认情况下,每个 VF 都分配有相同数量的 MSIX,默认数量由
NUM_VF_MSIX
和VIRTIO_NET_EMULATION_NUM_MSIX
的最小值决定。使用动态 VF MSIX,可以为 VF 分配比其默认值更多的 MSIX/队列。所有 VF 设备的 MSIX 硬件资源都由 PF 通过共享 MSIX 池进行管理。用户可以减少一个 VF 的 MSIX,从而将其 MSIX 资源释放到共享池。另一方面,可以为另一个 VF 分配比其默认值更多的 MSIX,以获得更高的性能。
[dpu]# mlxconfig -y -d 03:00.0 s VIRTIO_NET_EMULATION_NUM_ MSIX=32 VIRTIO_NET_EMULATION_NUM_VF_MSIX=32
模拟 VF 设备使用
VIRTIO_NET_EMULATION_NUM_VF_MSIX
设置 MSIX 数量。
VIRTIO_NET_EMULATION_NUM_VF_MSIX
可用于设置模拟 VF 设备的 MSIX 数量。对于模拟 VF 设备,请使用新的配置 VIRTIO_NET_EMULATION_NUM_VF_MSIX 而不是旧的配置 NUM_VF_MSIX。
[dpu]# mlxconfig -y -d 03:00.0 s VIRTIO_NET_EMULATION_NUM_MSIX=32 NUM_VF_MSIX=32
如果 VIRTIO_NET_EMULATION_NUM_VF_MSIX
!=0,则 VIRTIO_NET_EMULATION_NUM_MSIX
仅用于 PF,而 VF 使用 VIRTIO_NET_EMULATION_NUM_VF_MSIX
。
MSIX
例如,要将 VF 的默认 MSIX 数量配置为 32
如果 VIRTIO_NET_EMULATION_NUM_VF_MSIX
==0,则 VIRTIO_NET_EMULATION_NUM_MSIX
用于 PF 和 VF。
[dpu]# virtnet list | grep -i '"pf_id": 0' -A 8 | grep -i msix_num_pool_size
每个 VF 的默认 MSIX 数量由 minimum(NUM_VF_MSIX, VIRTIO_NET_EMULATION_NUM_MSIX)
决定。例如,要将 VF 的默认 MSIX 数量配置为 32
重启 BlueField 和主机,使 mlxconfig
生效。
[dpu]# virtnet list | grep -i '"pf_id": 0' -A 10 | grep -i max_msix_num
[dpu]# virtnet list | grep -i '"pf_id": 0' -A 10 | grep -i min_msix_num
MSIX 能力
[dpu]# virtnet query -p 0 -v 0 | grep num_msix
VF 的 MSIX 池由其 PF 管理。要检查共享池大小,请运行以下命令(以 PF 0 为例)
默认情况下,共享池大小为空 (0),因为所有 MSIX 资源都已均匀分配给 VF。一旦减少一个或多个 VF 的 MSIX,减少的 MSIX 将释放回池中。
但是,可以分配给给定 VF 的 MSIX 数量也受能力的限制。要检查这些上限,请运行以下命令
以下示例显示了将 MSIX 从 VF1 重新分配到 VF0 的步骤,假设每个 VF 默认有 32
个 MSIX 可用
从主机驱动程序中解绑两个 VF 设备。
[host]# echo <vf0_bdf> > /sys/bus/pci/drivers/virtio-pci/unbind [host]# echo <vf1_bdf> > /sys/bus/pci/drivers/virtio-pci/unbind
减少 VF1 的 MSIX 数量。
[dpu]# virtnet modify -p 0 -v 1 device -n 4
检查 PF0 的池大小。
[dpu]# virtnet list | grep -i '"pf_id": 0' -A 8 | grep -i msix_num_pool_size
确认减少的 MSIX 已添加到共享池。
增加 VF0 的 MSIX 数量。
[dpu]# virtnet modify -p 0 -v 0 device -n 48
检查 VF0 的 MSIX 数量。
[dpu]# virtnet query -p 0 -v 0 | grep -i num_msix
将两个 VF 设备绑定到主机驱动程序。
[host]# echo <vf0_bdf> > /sys/bus/pci/drivers/virtio-pci/bind [host]# echo <vf1_bdf> > /sys/bus/pci/drivers/virtio-pci/bind
注意MSIX 的数量必须是大于 4 的偶数。
MSIX 限制
MSIX 和 QP 配置是互斥的(即,一次只能配置其中一个)。例如,以下
modify
命令应导致失败[dpu]# virtnet modify -p 0 -v 1 device -qp 2 -n 6
要使用 VF,请确保分配有效的 MSIX 数量
[dpu]# virtnet modify -p 0 -v 1 device -n 10
如果协商了
VIRTIO_NET_F_CTRL_VQ
,则 VF 加载主机驱动程序所需的最小 MSIX 资源数为 4;如果未协商,则为 2。VF 的 MSIX 资源可以减少到 0,但这样做会阻止 VF 正常运行。
[dpu]# virtnet modify -p 0 -v 1 device -n 0
队列对
队列对 (QP) 是数据 virtio 队列 (VQ) 对的数量。每个 VQ 对都有一个发送 (TX) 队列和一个接收 (RX) 队列。这些队列对专用于处理数据流量,不包括控制或管理 VQ。
QP 功能
VF 的 QP 池由其 PF 管理。
要检查共享池大小,请运行以下命令(以 PF 0 为例)
[dpu]# virtnet list | grep -i '"pf_id": 0' -A 13 | grep -i qp_pool_size
默认情况下,共享池大小为空 (0),因为所有 QP 资源都已平均分配给 VF。减少一个或多个 VF 的 QP 后,减少的 QP 将释放回池中。
但是,可分配给 VF 的 QP 数量取决于其支持的功能。要验证这些功能,请运行以下命令
[dpu]# virtnet list | grep -i '"pf_id": 0' -A 12 | grep -i max_num_of_qp
[dpu]# virtnet list | grep -i '"pf_id": 0' -A 12 | grep -i min_num_of_qp
要检查当前分配的 QP 数量,请运行以下命令
[dpu]# virtnet query -p 0 -v 0 | grep max_queue_pairs
如果 max_queue_pairs
小于 max_num_of_qp
cap,则可以为 VF 分配更多 QP。
重新分配 VF QP
要为一个 VF 分配更多 QP,共享池中应有可用的 QP,如上一节所述。
以下示例说明了将 QP 从 VF1 重新分配到 VF0 的过程,假设每个 VF 最初默认有 32 个 QP 可用
从主机驱动程序中解绑两个 VF 设备
[host]# echo <vf0_bdf> > /sys/bus/pci/drivers/virtio-pci/unbind [host]# echo <vf1_bdf> > /sys/bus/pci/drivers/virtio-pci/unbind
减少 VF1 拥有的 QP 数量
[dpu]# virtnet modify -p 0 -v 1 device -qp 1
检查 PF0 的池大小,并确认减少的 QP 数量已添加到共享池
[dpu]# virtnet list | grep -i '"pf_id": 0' -A 13 | grep -i qp_pool_size
增加 VF0 拥有的 QP 数量
[dpu]# virtnet modify -p 0 -v 0 device -qp 23
检查 VF0 拥有的 QP 数量
[dpu]# virtnet query -p 0 -v 0 | grep -i max_queue_pairs
将两个 VF 设备绑定到主机驱动程序
[host]# echo <vf0_bdf> > /sys/bus/pci/drivers/virtio-pci/bind [host]# echo <vf1_bdf> > /sys/bus/pci/drivers/virtio-pci/bind
注意QP 的数量必须大于 0。
QP 限制
QP 和 MSIX 配置是互斥的(即,一次只能配置其中一个)。例如,以下
modify
命令应导致失败[dpu]# virtnet modify -p 0 -v 1 device -qp 2 -n 6
要使用 VF,请为其分配有效的 QP 数量
[dpu]# virtnet modify -p 0 -v 1 device -n 4
允许 VF 加载主机驱动程序的最小 QP 资源数为 1。
VF 的 QP 资源可以减少到 0。但是,在这种情况下,VF 将无法正常工作。
[dpu]# virtnet modify -p 0 -v 1 device -qp 0
Virt 队列类型
Virt 队列 (VQ) 是 virtio 设备上批量数据传输的机制。每个设备可以有零个或多个 VQ。
VQ 可以处于以下模式之一
分离式
打包式
更改支持的 VQ 类型时,请确保首先卸载访客驱动程序,以便设备可以修改支持的功能位。
分离 VQ
当前为默认 VQ 类型。分离式 VQ 格式是 virtio 规范 1.0 版本唯一支持的格式。
在分离式 VQ 模式下,每个 VQ 分为三个部分
描述符表 – 占用描述符区域
可用环 – 占用驱动程序区域
已用环 – 占用设备区域
这些部分中的每一个在访客内存中都是物理连续的。分离式 VQ 的设计非常简单,但其稀疏的内存使用会给 CPU 缓存利用率带来压力,并且每个描述符都需要多次 PCIe 事务。
配置
以下显示了仅在启用分离式 VQ 模式时 virtnet list
命令的输出外观
"supported_virt_queue_types": {
"value": "0x1",
" 0": "SPLIT"
},
打包 VQ
打包式 VQ 通过将三个环合并到虚拟环境访客内存中的一个位置,解决了分离式 VQ 的限制。此模式允许更少的 PCIe 事务和更好的 CPU 缓存利用率(每次描述符访问)。
从内核 5.0 开始,访客操作系统通过 virtio-support-packed-ring 提交支持打包式 VQ。
配置
可以通过在以下路径 /opt/mellanox/mlnx_virtnet/virtnet.conf
的配置文件中定义 packed_vq
来启用打包式 VQ 模式。
以下是在配置文件中启用 packed_vq
的示例
{
"single_port": 1,
"packed_vq": 1,
"sf_pool_percent": 0,
"sf_pool_force_destroy": 0,
"vf": {
"mac_base": "CC:48:15:FF:00:00",
"vfs_per_pf": 126
}
}
修改配置文件后,必须重新启动控制器才能使更改生效。确保卸载主机上的 virtio-net/virtio-pcie 驱动程序并运行
[dpu]# systemctl restart virtio-net-controller.service
要检查配置是否已生效且控制器是否支持打包式 VQ 模式,请运行
[dpu]# virtnet list
检查 supported_virt_queue_types
中是否有 PACKED
"supported_virt_queue_types": {
"value": "0x3",
" 0": "SPLIT",
" 1": "PACKED"
},
此时可以加载 Virtio-net/virtio-pci 驱动程序以在打包模式下创建 VQ。驱动程序加载完成后,要验证设备是否已启用打包式 VQ 模式,请运行以下命令
[dpu]# virtnet query -p <PFID> -v <VFID>
检查驱动程序功能中是否有 VIRTNET_F_RING_PACKED
"driver_feature": {
"value": "0x8930012700e7182f",
" 0": "VIRTIO_NET_F_CSUM",
" 1": "VIRTIO_NET_F_GUEST_CSUM",
" 2": "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS",
" 3": "VIRTIO_NET_F_MTU",
" 5": "VIRTIO_NET_F_MAC",
" 11": "VIRTIO_NET_F_HOST_TSO4",
" 12": "VIRTIO_NET_F_HOST_TSO6",
" 16": "VIRTIO_NET_F_STATUS",
" 17": "VIRTIO_NET_F_CTRL_VQ",
" 18": "VIRTIO_NET_F_CTRL_RX",
" 21": "VIRTIO_NET_F_GUEST_ANNOUNCE",
" 22": "VIRTIO_NET_F_MQ",
" 23": "VIRTIO_NET_F_CTRL_MAC_ADDR",
" 32": "VIRTIO_F_VERSION_1",
" 33": "VIRTIO_F_IOMMU_PLATFORM",
" 34": "VIRTIO_F_RING_PACKED",
" 37": "VIRTIO_F_SR_IOV",
" 40": "VIRTIO_F_RING_RESET",
" 52": "VIRTIO_NET_F_VQ_NOTF_COAL",
" 53": "VIRTIO_NET_F_NOTF_COAL",
" 56": "VIRTIO_NET_F_HOST_USO",
" 59": "VIRTIO_NET_F_GUEST_HDRLEN",
" 63": "VIRTIO_NET_F_SPEED_DUPLEX"
},
如果 VF 映射到多个 VM,则某些设备可能会在打包模式下创建 VQ,而某些设备可能会在分离模式下创建 VQ,具体取决于操作系统版本以及驱动程序是否支持该功能。
已知限制
启用打包式 VQ 后,当前不支持以下功能
可合并缓冲区
巨型 MTU
UDP 分段卸载和 RSS 哈希报告
Virtio-net 功能位
根据 virtio 规范,当驱动程序探测设备时,virtio 设备会与 virtio 驱动程序协商支持的功能。最终协商的功能是设备支持的功能的子集。
从控制器的角度来看,设备可以支持的所有功能位都由 virtnet list
填充。每个 virtio-net 设备都能够选择自身支持的功能位。
以下是控制器当前支持的功能位列表
VIRTIO_NET_F_CSUM
VIRTIO_NET_F_GUEST_CSUM
VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
VIRTIO_NET_F_MTU
VIRTIO_NET_F_MAC
VIRTIO_NET_F_HOST_TSO4
VIRTIO_NET_F_HOST_TSO6
VIRTIO_NET_F_MRG_RXBUF
VIRTIO_NET_F_STATUS
VIRTIO_NET_F_CTRL_VQ
VIRTIO_NET_F_CTRL_RX
VIRTIO_NET_F_CTRL_VLAN
VIRTIO_NET_F_GUEST_ANNOUNCE
VIRTIO_NET_F_MQ
VIRTIO_NET_F_CTRL_MAC_ADDR
VIRTIO_F_VERSION_1
VIRTIO_F_IOMMU_PLATFORM
VIRTIO_F_RING_PACKED
VIRTIO_F_ORDER_PLATFORM
VIRTIO_F_SR_IOV
VIRTIO_F_NOTIFICATION_DATA
VIRTIO_F_RING_RESET
VIRTIO_F_ADMIN_VQ
VIRTIO_NET_F_HOST_USO
VIRTIO_NET_F_HASH_REPORT
VIRTIO_NET_F_GUEST_HDRLEN
VIRTIO_NET_F_SPEED_DUPLEX
有关这些位的更多信息,请参阅 VIRTIO 1.2 版本规范。