正确的 DPDK 设备和传输端口初始化
Proper DPDK device and port initialization for transmission
在编写一个简单的 DPDK 数据包生成器时,我注意到一些额外的初始化步骤是可靠和成功的数据包传输所必需的:
- 在
rte_eth_dev_start()
之后调用 rte_eth_link_get()
或 rte_eth_timesync_enable()
- 在使用
rte_eth_tx_burst()
发送第一个数据包之前等待 2 秒
因此,当我将 ixgbe DPDK vfio 驱动程序与 Intel X553 NIC 一起使用时,这些步骤是必要的。
当我使用 AF_PACKET
DPDK 驱动程序时,无需这些额外步骤即可工作。
- 这是错误还是功能?
- 有没有比第一次发送前等待 2 秒更好的方法?
- 为什么 ixgbe 驱动程序需要等待?这是该 NIC 或所涉及的交换机(带有 Marvell 芯片组的 Mikrotik CRS326)的限制吗?
- 是否有比
rte_eth_link_get()
更惯用的函数来完成传输的设备初始化?
- 有什么方法可以保持 VFIO NIC 初始化(同时保持其 link 启动)以避免在通常的 edit/compile/test 周期中一遍又一遍地重新初始化它? (即加快该循环...)
附加信息:当我将 NIC 连接到镜像端口时(通过 Mikrotik 的 mirror-source/mirror-target 以太网交换机设置进行配置)和 sleep(2)
被删除然后我看到第一个数据包传输到镜像目标但没有传输到主要目标。因此,似乎有必要在 link 启动后(在 dpdk 程序启动后)给交换机一些时间,以完全初始化其转发 table 或类似的东西?
在第一次传输之前仅等待 1 秒可靠性较低,即数据包仅在奇数时间到达接收方。
我的 device/port 初始化程序实现了以下设置顺序:
rte_eth_dev_count_avail()
rte_eth_dev_is_valid_port()
rte_eth_dev_info_get()
rte_eth_dev_adjust_nb_rx_tx_desc()
rte_eth_dev_configure(port_id, 0 /* rxrings */, 1 /* txrings */, &port_conf)
rte_eth_tx_queue_setup()
rte_eth_dev_start()
rte_eth_macaddr_get()
rte_eth_link_get() // <-- REQUIRED!
rte_eth_dev_get_mtu()
如果没有 rte_eth_link_get()
(或 rte_eth_timesync_enable()
),第一个传输的数据包甚至不会出现在镜像端口上。
以上功能(和 rte_eth_tx_burst()
)成功完成 with/without rte_eth_link_get()
/sleep(2)
存在。特别是,读取 MAC 地址,MTU 具有预期值 (MTU -> 1500) 和 rte_eth_tx_burst()
returns 1
对于一个 UDP 数据包的突发。
返回的link状态为:Link up at 1 Gbps FDX Autoneg
rte_eth_link_get()
可以替换为 rte_eth_timesync_enable()
的事实可能可以通过后者调用 ixgbe_start_timecounters()
来解释,后者调用 rte_eth_linkstatus_get()
,rte_eth_linkstatus_get()
也被 [=11] 调用=].
我已经检查了 DPDK 示例,其中大多数在发送内容之前不会调用 rte_eth_link_get()
。设备初始化后也没有休眠。
我正在使用 DPDK 20.11.2。
更多信息 - 回答评论:
我在 Fedora 33 (5.13.12-100.fc33.x86_64
) 上 运行。
Ethtool 报告:firmware-version: 0x80000877
我调用了 rte_eth_timesync_enable()
以便使用传输时间戳。但是,在调试过程中,我删除了它以获得最小的复制器。那时我注意到删除它实际上会使情况变得更糟(即没有数据包通过镜像端口传输)。因此,我调查了该函数的哪一部分可能会有所不同,并发现 rte_eth_link_get()
具有类似的副作用。
切换到 AF_PACKET
时,我使用的是标准的 ixgbe 内核驱动程序,即 ixgbe
在由网络初始化的设备上使用默认设置(启用 dhcp)。
我的预期是,当 rte_eth_dev_start()
终止时,link 启动并且设备已准备好传输。
但是,我想,如果可以避免在程序重新启动后重置设备,那就太好了。不知道DPDK是否支持这个
关于延迟:我刚刚测试了以下内容:如果我将睡眠时间增加到 6 秒,则可以省略 rte_eth_link_get()
。而调用 rte_eth_link_get()
需要 3.3 秒。所以是的,由于额外的延迟,它可能只是有所帮助。
两种尝试方法的区别
为了使用af_packet
PMD,您首先要将有问题的设备绑定到内核驱动程序。此时,为该设备生成了一个内核网络接口。默认情况下,此接口通常有 link 活动。如果不是,您通常 运行 ip link set dev <interface> up
。当您启动 DPDK 应用程序时,af_packet
驱动程序不会(重新)配置 link。它只是无条件地报告 link 在设备启动时启动(参见 https://github.com/DPDK/dpdk/blob/main/drivers/net/af_packet/rte_eth_af_packet.c#L266) and vice versa when doing device stop. Link update operation is also no-op in this driver (see https://github.com/DPDK/dpdk/blob/main/drivers/net/af_packet/rte_eth_af_packet.c#L416)。
事实上,使用 af_packet
方法,link 在您启动应用程序时已经处于活动状态。因此无需等待 link.
使用 VFIO 方法,有问题的设备 link 关闭,相应的 PMD 负责激活它。因此需要在应用程序中测试 link 状态。
是否可以避免等待应用程序重启?
长话短说,是的。等待 link 状态并不是应用程序重启的唯一问题。当您重新启动时,您实际上将 EAL 作为一个整体重新初始化,而且该过程也非常耗时。为了解决这个问题,您可能应该查看 DPDK 中提供的 多进程支持 (参见 https://doc.dpdk.org/guides/prog_guide/multi_proc_support.html)。
这需要您重新实现您的应用程序,以便在一个进程(还有 主进程 )中具有其控制逻辑,在另一个进程中具有 Rx/Tx 数据路径逻辑(次要过程)。这样,您可以一直保持第一个 运行ning 并在需要更改 Rx/Tx 逻辑/重新编译时重新启动第二个。重新启动 辅助进程 将始终重新附加到现有的 EAL 实例。因此,不涉及 PMD 重启,也无需等待。
根据通过评论进行的互动,真正的问题是 总结,因为我只是问自己是否有可能在调用之间保持 link-向上一个 DPDK 程序(当使用 vfio 设备时)以避免在第一次传输通过之前处理相对较长的等待时间。 IOW,是否有可能在第二次启动程序时跳过设备重置?
对于重启之间的数据包生成器程序,简短的回答是 No
,因为任何使用 PCIe 配置的物理 NIC space PF(X533 的 IXGBE)和 VF(IXGBE_VF 对于 X553)与 uio_pci_generic|igb_uio|vfio-pci 绑定需要 PCIe 重置和配置 。但是,当使用 AF_PACKET(ixgbe 内核驱动程序)DPDK PMD 时,这是 不执行任何 PCIe 重置的虚拟设备 和在 eth_dev_start 函数中直接 dev->data->dev_link.link_status = ETH_LINK_UP;
。
对于第二部分是否预期第一个 TX 数据包的延迟?
[Answer] 不会,因为有几个因素会导致第一个数据包传输延迟
- 交换机软件和固件(仅限 PF)
- 切换端口自动否定或固定速度(仅限 PF)
- X533 软件和固件(PF 和 VF)
- Autoneg 启用或禁用(PF 和 VF)
- link 中型 SFP(光纤)或 DAC(直连铜线)或 RJ-45 (cat5|cat6) 连接(仅限 PF)
- NIC (X553 ixgbe) 的 PF 驱动程序版本(PF 和 VF)
- 根据英特尔驱动程序软件生成的第二层帧,如 IEEE 802.3x(link 流量控制)、IEEE 802.1Qbb(基于优先级的流量控制) ,以及其他此类(仅 VF)
注意:由于仅针对 VF 端口(而不是 PF 端口)提到了该问题,因此我的假设是
- TX包使用VF的SRCMAC地址来避免MAC对ASIC的欺骗检查
- 从 PF 上的管理界面为所有启用 SR-IOV 的端口配置 VLAN 标记,以避免流量泛滥到 VF
- PF 驱动程序已更新以避免旧驱动程序问题(VF 重置导致 PF link 重置)。这可以通过检查
dmesg
来识别
通过以下步骤隔离 NIC 问题的步骤:
- 检查(X533)PF DPDK是否有和VF DPDK一样的延迟(如果是PF或VF则隔离)问题。
- 在同一系统上交叉连接 2 个 NIC (X533)。然后比较Linux vs DPDK link up events(检查是网卡问题还是PCIe LNK问题)
- 禁用 DPDK X533 的自动否定并比较 DPDK 中的 PF 与 Vf
隔离问题的步骤是切换:
- 禁用 Switch 上的自动否定并设置
FD auto-neg-disable speed 1Gbps
并检查行为
[EDIT-1] 我同意@stackinside 使用 DPDK primary-secondary process 概念建议的变通解决方案。由于主要负责 Link 和端口启动。而次要用于实际的 RX 和 TX 突发。
在编写一个简单的 DPDK 数据包生成器时,我注意到一些额外的初始化步骤是可靠和成功的数据包传输所必需的:
- 在
rte_eth_dev_start()
之后调用 - 在使用
rte_eth_tx_burst()
发送第一个数据包之前等待 2 秒
rte_eth_link_get()
或 rte_eth_timesync_enable()
因此,当我将 ixgbe DPDK vfio 驱动程序与 Intel X553 NIC 一起使用时,这些步骤是必要的。
当我使用 AF_PACKET
DPDK 驱动程序时,无需这些额外步骤即可工作。
- 这是错误还是功能?
- 有没有比第一次发送前等待 2 秒更好的方法?
- 为什么 ixgbe 驱动程序需要等待?这是该 NIC 或所涉及的交换机(带有 Marvell 芯片组的 Mikrotik CRS326)的限制吗?
- 是否有比
rte_eth_link_get()
更惯用的函数来完成传输的设备初始化? - 有什么方法可以保持 VFIO NIC 初始化(同时保持其 link 启动)以避免在通常的 edit/compile/test 周期中一遍又一遍地重新初始化它? (即加快该循环...)
附加信息:当我将 NIC 连接到镜像端口时(通过 Mikrotik 的 mirror-source/mirror-target 以太网交换机设置进行配置)和 sleep(2)
被删除然后我看到第一个数据包传输到镜像目标但没有传输到主要目标。因此,似乎有必要在 link 启动后(在 dpdk 程序启动后)给交换机一些时间,以完全初始化其转发 table 或类似的东西?
在第一次传输之前仅等待 1 秒可靠性较低,即数据包仅在奇数时间到达接收方。
我的 device/port 初始化程序实现了以下设置顺序:
rte_eth_dev_count_avail()
rte_eth_dev_is_valid_port()
rte_eth_dev_info_get()
rte_eth_dev_adjust_nb_rx_tx_desc()
rte_eth_dev_configure(port_id, 0 /* rxrings */, 1 /* txrings */, &port_conf)
rte_eth_tx_queue_setup()
rte_eth_dev_start()
rte_eth_macaddr_get()
rte_eth_link_get() // <-- REQUIRED!
rte_eth_dev_get_mtu()
如果没有 rte_eth_link_get()
(或 rte_eth_timesync_enable()
),第一个传输的数据包甚至不会出现在镜像端口上。
以上功能(和 rte_eth_tx_burst()
)成功完成 with/without rte_eth_link_get()
/sleep(2)
存在。特别是,读取 MAC 地址,MTU 具有预期值 (MTU -> 1500) 和 rte_eth_tx_burst()
returns 1
对于一个 UDP 数据包的突发。
返回的link状态为:Link up at 1 Gbps FDX Autoneg
rte_eth_link_get()
可以替换为 rte_eth_timesync_enable()
的事实可能可以通过后者调用 ixgbe_start_timecounters()
来解释,后者调用 rte_eth_linkstatus_get()
,rte_eth_linkstatus_get()
也被 [=11] 调用=].
我已经检查了 DPDK 示例,其中大多数在发送内容之前不会调用 rte_eth_link_get()
。设备初始化后也没有休眠。
我正在使用 DPDK 20.11.2。
更多信息 - 回答评论:
我在 Fedora 33 (5.13.12-100.fc33.x86_64
) 上 运行。
Ethtool 报告:firmware-version: 0x80000877
我调用了 rte_eth_timesync_enable()
以便使用传输时间戳。但是,在调试过程中,我删除了它以获得最小的复制器。那时我注意到删除它实际上会使情况变得更糟(即没有数据包通过镜像端口传输)。因此,我调查了该函数的哪一部分可能会有所不同,并发现 rte_eth_link_get()
具有类似的副作用。
切换到 AF_PACKET
时,我使用的是标准的 ixgbe 内核驱动程序,即 ixgbe
在由网络初始化的设备上使用默认设置(启用 dhcp)。
我的预期是,当 rte_eth_dev_start()
终止时,link 启动并且设备已准备好传输。
但是,我想,如果可以避免在程序重新启动后重置设备,那就太好了。不知道DPDK是否支持这个
关于延迟:我刚刚测试了以下内容:如果我将睡眠时间增加到 6 秒,则可以省略 rte_eth_link_get()
。而调用 rte_eth_link_get()
需要 3.3 秒。所以是的,由于额外的延迟,它可能只是有所帮助。
两种尝试方法的区别
为了使用af_packet
PMD,您首先要将有问题的设备绑定到内核驱动程序。此时,为该设备生成了一个内核网络接口。默认情况下,此接口通常有 link 活动。如果不是,您通常 运行 ip link set dev <interface> up
。当您启动 DPDK 应用程序时,af_packet
驱动程序不会(重新)配置 link。它只是无条件地报告 link 在设备启动时启动(参见 https://github.com/DPDK/dpdk/blob/main/drivers/net/af_packet/rte_eth_af_packet.c#L266) and vice versa when doing device stop. Link update operation is also no-op in this driver (see https://github.com/DPDK/dpdk/blob/main/drivers/net/af_packet/rte_eth_af_packet.c#L416)。
事实上,使用 af_packet
方法,link 在您启动应用程序时已经处于活动状态。因此无需等待 link.
使用 VFIO 方法,有问题的设备 link 关闭,相应的 PMD 负责激活它。因此需要在应用程序中测试 link 状态。
是否可以避免等待应用程序重启?
长话短说,是的。等待 link 状态并不是应用程序重启的唯一问题。当您重新启动时,您实际上将 EAL 作为一个整体重新初始化,而且该过程也非常耗时。为了解决这个问题,您可能应该查看 DPDK 中提供的 多进程支持 (参见 https://doc.dpdk.org/guides/prog_guide/multi_proc_support.html)。
这需要您重新实现您的应用程序,以便在一个进程(还有 主进程 )中具有其控制逻辑,在另一个进程中具有 Rx/Tx 数据路径逻辑(次要过程)。这样,您可以一直保持第一个 运行ning 并在需要更改 Rx/Tx 逻辑/重新编译时重新启动第二个。重新启动 辅助进程 将始终重新附加到现有的 EAL 实例。因此,不涉及 PMD 重启,也无需等待。
根据通过评论进行的互动,真正的问题是 总结,因为我只是问自己是否有可能在调用之间保持 link-向上一个 DPDK 程序(当使用 vfio 设备时)以避免在第一次传输通过之前处理相对较长的等待时间。 IOW,是否有可能在第二次启动程序时跳过设备重置?
对于重启之间的数据包生成器程序,简短的回答是 No
,因为任何使用 PCIe 配置的物理 NIC space PF(X533 的 IXGBE)和 VF(IXGBE_VF 对于 X553)与 uio_pci_generic|igb_uio|vfio-pci 绑定需要 PCIe 重置和配置 。但是,当使用 AF_PACKET(ixgbe 内核驱动程序)DPDK PMD 时,这是 不执行任何 PCIe 重置的虚拟设备 和在 eth_dev_start 函数中直接 dev->data->dev_link.link_status = ETH_LINK_UP;
。
对于第二部分是否预期第一个 TX 数据包的延迟?
[Answer] 不会,因为有几个因素会导致第一个数据包传输延迟
- 交换机软件和固件(仅限 PF)
- 切换端口自动否定或固定速度(仅限 PF)
- X533 软件和固件(PF 和 VF)
- Autoneg 启用或禁用(PF 和 VF)
- link 中型 SFP(光纤)或 DAC(直连铜线)或 RJ-45 (cat5|cat6) 连接(仅限 PF)
- NIC (X553 ixgbe) 的 PF 驱动程序版本(PF 和 VF)
- 根据英特尔驱动程序软件生成的第二层帧,如 IEEE 802.3x(link 流量控制)、IEEE 802.1Qbb(基于优先级的流量控制) ,以及其他此类(仅 VF)
注意:由于仅针对 VF 端口(而不是 PF 端口)提到了该问题,因此我的假设是
- TX包使用VF的SRCMAC地址来避免MAC对ASIC的欺骗检查
- 从 PF 上的管理界面为所有启用 SR-IOV 的端口配置 VLAN 标记,以避免流量泛滥到 VF
- PF 驱动程序已更新以避免旧驱动程序问题(VF 重置导致 PF link 重置)。这可以通过检查
dmesg
来识别
通过以下步骤隔离 NIC 问题的步骤:
- 检查(X533)PF DPDK是否有和VF DPDK一样的延迟(如果是PF或VF则隔离)问题。
- 在同一系统上交叉连接 2 个 NIC (X533)。然后比较Linux vs DPDK link up events(检查是网卡问题还是PCIe LNK问题)
- 禁用 DPDK X533 的自动否定并比较 DPDK 中的 PF 与 Vf
隔离问题的步骤是切换:
- 禁用 Switch 上的自动否定并设置
FD auto-neg-disable speed 1Gbps
并检查行为
[EDIT-1] 我同意@stackinside 使用 DPDK primary-secondary process 概念建议的变通解决方案。由于主要负责 Link 和端口启动。而次要用于实际的 RX 和 TX 突发。