二层转发防止DPDK丢包

Preventing DPDK packet loss in L2 forwarding

您好,我已经为 DPDK 实现了 pingpong。 客户端发送数据包,服务器接收数据包然后返回。

server部分的实现与DPDK官网的L2转发示例类似。

在进行 L2 转发时,我注意到在将数据包从接收方队列转发到传输队列时出现数据包丢失。

我的问题是...有没有办法让丢包为零?

由于DPDK网站上的示例应用程序都有丢包,我找不到解决办法。

丢包由下面的回调函数统计

rte_eth_tx_buffer_set_err_callback(tx_buffer[portid], rte_eth_tx_buffer_count_callback, &port_statistics[portid].dropped);

这是我L2转发的结果

Port statistics ====================================
Statistics for port 0 ------------------------------
Packets sent:                   384126              
Packets received:               379889              
Packets dropped:                  4237              
Aggregate statistics ===============================
Total packets sent:             384126              
Total packets received:         379889              
Total packets dropped:            4237              
====================================================

因为我的实现只是 pingpong 并且实现非常简单,所以我认为在我的情况下不应该有任何数据包丢失。

当函数 rte_eth_tx_burst() 无法将数据包传输到目标端口时,

Packets dropped 计数器在 rte_eth_tx_buffer_flush() 中增加。

rte_eth_tx_burst() 函数只是调用您的 tx_pkt_burst() PMD 回调,因此如果没有关于您的底层 PMD 的信息,很难说它失败的原因。所以下面的部分是相当多的猜测......

所以一般来说,rte_eth_tx_burst() 失败是因为 TX 队列已满。 TX 队列已满,因为底层设备无法以您提供的速率发送数据包。

可能发生的情况很少:

  1. 您的 RX 端口速度大于您的 TX 端口速度(很可能不是您的情况)。

  2. 您的 RX 和 TX 端口具有相同的速度,但是您在应用程序中添加了一些额外的数据包,因此它们不再适合(可能是您的情况)。

  3. 由于流量控制,您的 NIC 正在暂停传输,所以您有这些丢弃(很可能是您的情况)。

因此,如果我的猜测是正确的,只需使用 ethtool:

在您的客户端禁用以太网流量控制
ethtool -A eth0 tx off rx off

如果我的猜测不正确,那么在您的服务器端使用 rte_eth_stats_get()rte_eth_xstats_get() 深入了解 PMD 计数器,看看发生了什么。