首页 > 解决方案 > 正确的 DPDK 设备和端口初始化以进行传输

问题描述

在编写一个简单的 DPDK 数据包生成器时,我注意到可靠和成功的数据包传输所需的一些额外的初始化步骤:

  1. 打电话rte_eth_link_get()rte_eth_timesync_enable()之后rte_eth_dev_start()
  2. 在发送第一个数据包之前等待 2 秒rte_eth_tx_burst()

因此,当我将 ixgbe DPDK vfio 驱动程序与 Intel X553 NIC 一起使用时,这些步骤是必要的。

当我使用AF_PACKETDPDK 驱动程序时,它无需那些额外的步骤即可工作。


附加信息:当我将 NIC 连接到镜像端口(通过 Mikrotik 的 mirror-source/mirror-target 以太网交换机设置配置)并被删除时,sleep(2)我看到第一个数据包传输到镜像目标但没有传输到主要目标. 因此,似乎有必要在链接启动后(在 dpdk 程序启动后)给开关一些时间以完全初始化其转发表或类似的东西?

在第一次传输之前仅等待 1 秒的可靠性较低,即数据包仅每隔奇数时间到达接收器。

我的设备/端口初始化过程实现了以下设置序列:

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())在有/没有rte_eth_link_get()/sleep(2)存在的情况下成功完成。尤其是读取的 MAC 地址,MTU 具有预期值(MTU -> 1500)并rte_eth_tx_burst()返回1一个 UDP 数据包的突发。

返回的链接状态为:Link up at 1 Gbps FDX Autoneg

rte_eth_link_get()可以用可能替换的事实可以rte_eth_timesync_enable()通过后一个调用来解释,后者调用ixgbe_start_timecounters()rte_eth_linkstatus_get()被调用rte_eth_link_get()

我检查了 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在由 networkd 初始化的设备上使用默认设置(启用 dhcp)。

我的期望是,当rte_eth_dev_start()终止时链接已启动并且设备已准备好传输。

但是,我想,如果可以避免在程序重新启动后重置设备,那就太好了。我不知道 DPDK 是否支持这个。

关于延迟:我刚刚测试了以下内容:rte_eth_link_get()如果我将睡眠时间增加到 6 秒,则可以省略。而调用rte_eth_link_get()需要 3.3 秒。所以,是的,由于额外的延迟,它可能只是有帮助。

标签: dpdk

解决方案


两种尝试方法之间的区别

为了使用af_packetPMD,您首先将相关设备绑定到内核驱动程序。此时,将为该设备生成一个内核网络接口。默认情况下,此接口通常具有活动链接。如果没有,您通常运行ip link set dev <interface> up. 当您启动 DPDK 应用程序时,af_packet驱动程序不会(重新)配置链接。它只是无条件地报告链接在设备启动时启动(请参阅https://github.com/DPDK/dpdk/blob/main/drivers/net/af_packet/rte_eth_af_packet.c#L266),反之亦然。此驱动程序中的链接更新操作也是无操作的(请参阅https://github.com/DPDK/dpdk/blob/main/drivers/net/af_packet/rte_eth_af_packet.c#L416)。

事实上,通过af_packet方法,该链接在您启动应用程序时已经处于活动状态。因此无需等待链接。

使用 VFIO 方法时,相关设备的链路断开,相应的 PMD 负责激活它。因此需要在应用程序中测试链接状态。

是否可以避免等待应用程序重新启动?

长话短说,是的。等待链接状态并不是应用程序重启的唯一问题。当您重新启动时,您有效地重新初始化了整个 EAL,而且该过程也非常耗时。为了解决这个问题,您可能应该查看DPDK 中提供的多进程支持(请参阅https://doc.dpdk.org/guides/prog_guide/multi_proc_support.html)。

这要求您重新实现您的应用程序,使其控制逻辑在一个进程(也是主要进程)中,而 Rx/Tx 数据路径逻辑在另一个进程(次要进程)中。这样,您可以一直保持第一个运行,并在需要更改 Rx/Tx 逻辑/重新编译时重新启动第二个。重新启动辅助进程将始终重新附加到现有的 EAL 实例。因此不涉及 PMD 重启,也无需等待。


推荐阅读