【问题标题】:rte_eth_tx_burst suddenly stops sending packetsrte_eth_tx_burst 突然停止发送数据包
【发布时间】:2022-06-21 08:28:32
【问题描述】:

我正在为我的应用程序使用 DPDK 21.11。一段时间后,API rte_eth_tx_burst 停止发送任何数据包。

用于 10GbE SFP+ 1572 的以太网控制器 X710 drv=vfio-pci

MAX_RETRY_COUNT_RTE_ETH_TX_BURST 3


 do
            {
                num_sent_pkt = rte_eth_tx_burst(eth_port_id, queue_id, &mbuf[mbuf_idx], pkt_count);
                pkt_count -= num_sent_pkt;
                retry_count++;
            } while(pkt_count && (retry_count != MAX_RETRY_COUNT_RTE_ETH_TX_BURST));

为了调试,我尝试使用遥测来打印出 xstats。但是,我没有看到任何错误。

--> /ethdev/xstats,1
{"/ethdev/xstats": {"rx_good_packets": 97727, "tx_good_packets": 157902622, "rx_good_bytes": 6459916, "tx_good_bytes": 229590348448, "rx_missed_errors": 0, "rx_errors": 0, "tx_errors": 0, "rx_mbuf_allocation_errors": 0, "rx_unicast_packets": 95827, "rx_multicast_packets": 1901, "rx_broadcast_packets": 0, "rx_dropped_packets": 0, "rx_unknown_protocol_packets": 97728, "rx_size_error_packets": 0, "tx_unicast_packets": 157902621, "tx_multicast_packets": 0, "tx_broadcast_packets": 1, "tx_dropped_packets": 0, "tx_link_down_dropped": 0, "rx_crc_errors": 0, "rx_illegal_byte_errors": 0, "rx_error_bytes": 0, "mac_local_errors": 0, "mac_remote_errors": 0, "rx_length_errors": 0, "tx_xon_packets": 0, "rx_xon_packets": 0, "tx_xoff_packets": 0, "rx_xoff_packets": 0, "rx_size_64_packets": 967, "rx_size_65_to_127_packets": 96697, "rx_size_128_to_255_packets": 0, "rx_size_256_to_511_packets": 64, "rx_size_512_to_1023_packets": 0, "rx_size_1024_to_1522_packets": 0, "rx_size_1523_to_max_packets": 0, "rx_undersized_errors": 0, "rx_oversize_errors": 0, "rx_mac_short_dropped": 0, "rx_fragmented_errors": 0, "rx_jabber_errors": 0, "tx_size_64_packets": 0, "tx_size_65_to_127_packets": 46, "tx_size_128_to_255_packets": 0, "tx_size_256_to_511_packets": 0, "tx_size_512_to_1023_packets": 0, "tx_size_1024_to_1522_packets": 157902576, "tx_size_1523_to_max_packets": 0, "rx_flow_director_atr_match_packets": 0, "rx_flow_director_sb_match_packets": 13, "tx_low_power_idle_status": 0, "rx_low_power_idle_status": 0, "tx_low_power_idle_count": 0, "rx_low_power_idle_count": 0, "rx_priority0_xon_packets": 0, "rx_priority1_xon_packets": 0, "rx_priority2_xon_packets": 0, "rx_priority3_xon_packets": 0, "rx_priority4_xon_packets": 0, "rx_priority5_xon_packets": 0, "rx_priority6_xon_packets": 0, "rx_priority7_xon_packets": 0, "rx_priority0_xoff_packets": 0, "rx_priority1_xoff_packets": 0, "rx_priority2_xoff_packets": 0, "rx_priority3_xoff_packets": 0, "rx_priority4_xoff_packets": 0, "rx_priority5_xoff_packets": 0, "rx_priority6_xoff_packets": 0, "rx_priority7_xoff_packets": 0, "tx_priority0_xon_packets": 0, "tx_priority1_xon_packets": 0, "tx_priority2_xon_packets": 0, "tx_priority3_xon_packets": 0, "tx_priority4_xon_packets": 0, "tx_priority5_xon_packets": 0, "tx_priority6_xon_packets": 0, "tx_priority7_xon_packets": 0, "tx_priority0_xoff_packets": 0, "tx_priority1_xoff_packets": 0, "tx_priority2_xoff_packets": 0, "tx_priority3_xoff_packets": 0, "tx_priority4_xoff_packets": 0, "tx_priority5_xoff_packets": 0, "tx_priority6_xoff_packets": 0, "tx_priority7_xoff_packets": 0, "tx_priority0_xon_to_xoff_packets": 0, "tx_priority1_xon_to_xoff_packets": 0, "tx_priority2_xon_to_xoff_packets": 0, "tx_priority3_xon_to_xoff_packets": 0, "tx_priority4_xon_to_xoff_packets": 0, "tx_priority5_xon_to_xoff_packets": 0, "tx_priority6_xon_to_xoff_packets": 0, "tx_priority7_xon_to_xoff_packets": 0}}

我已配置 RX-DESC = 128 和 TX-DESC = 512。

我假设有一些 desc 泄漏,有没有办法知道下降是否是由于没有 desc 存在?我应该检查哪个计数器?

[更多信息] 调试 refcnt 会导致死胡同。 按照代码,似乎网卡没有在描述符上设置 DONE 状态。 当调用rte_eth_tx_burst时,next func内部调用i40e_xmit_pkts -> i40e_xmit_cleanup

出现该问题时,以下情况失败导致网卡无法发送数据包。

    if ((txd[desc_to_clean_to].cmd_type_offset_bsz &
            rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) !=
            rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE)) {
        PMD_TX_LOG(DEBUG, "TX descriptor %4u is not done "
               "(port=%d queue=%d)", desc_to_clean_to,
               txq->port_id, txq->queue_id);
        return -1;
    }

如果我注释掉“return -1”(当然不是修复).. 我可以看到流量是稳定的。 我跟踪了从流量开始到问题出现的所有 mbuf,至少在 mbuf 中没有看到我可以看到的问题。

I40E_TX_DESC_DTYPE_DESC_DONE 将在 h/w 中为描述符设置。有什么办法可以看到该代码吗?它是 x710 驱动程序代码的一部分吗?

我认为是我的代码导致了这种情况,因为我更换了 NIC 没有任何影响。 任何建议都会很有帮助。

【问题讨论】:

    标签: c++ dpdk dpdk-pmd


    【解决方案1】:

    如果代码的意图是在 MAX_RETRY_COUNT_RTE_ETH_TX_BURST 内尝试所有 pkt_count 数据包,则当前代码 sn-p 需要一些更正。让我解释一下

    1. mbuf 是要发送的有效数据包数组
    2. mbuf_idx 表示当前要发送给 TX 的索引
    3. pkt_count 表示当前尝试发出的数据包数。
    4. num_sent_pkt 表示为 DMA 复制到 NIC(物理)而发送的实际数据包。
    5. retry_count 是保持重试次数的局部变量。

    有 2 个特殊情况需要处理(当前 sn-p 中不共享)

    1. 如果超过了 MAX_RETRY_COUNT_RTE_ETH_TX_BURST 并且num_sent_pkt is not equal to actual TX,则需要在 while 循环结束时释放未传输的 MBUF。
    2. 如果有任何带有ref_cnt greater than 1 的 MBUF(尤其是多播、广播或数据包复制),也需要一种释放这些的机制。

    可能的代码 sn-p 可能是:

    MAX_RETRY_COUNT_RTE_ETH_TX_BURST 3
    retry_count = 0;
    mbuf_idx = 0;
    pkt_count = try_sent; /* try_sent intended send*/
    
    /* if there are any mbuf with ref_cnt > 1, we need separate logic to handle those */
    
    do {
      num_sent_pkt = rte_eth_tx_burst(eth_port_id, queue_id, &mbuf[mbuf_idx], pkt_count);
    
      pkt_count -= num_sent_pkt;
      mbuf_idx += num_sent_pkt;
      
      retry_count++;
    } while((pkt_count) && (retry_count < MAX_RETRY_COUNT_RTE_ETH_TX_BURST));
    
    /* to prevent the leak for unsent packet*/
    if (pkt_count) {
        rte_pktmbuf_free_bulk(&mbuf[mbuf_idx], pkt_count);
    }
    
    

    注意:识别 mbuf 泄漏的最简单方法是运行 DPDK 辅助进程 proc-info 以检查 mbuf 空闲计数。

    [EDIT-1]根据debug,发现refcnt确实大于1,这样的极端情况累积会导致mempool耗尽。

    日志:

    dump mbuf at 0x2b67803c0, iova=0x2b6780440, buf_len=9344
    pkt_len=1454, ol_flags=0x180, nb_segs=1, port=0, ptype=0x291
    segment at 0x2b67803c0, data=0x2b67804b8, len=1454, off=120, refcnt=3
    

    【讨论】:

    • 您好 Vipin,感谢您的回复。正如你提到的,我有免费的代码。我刚刚粘贴了代码的发送部分。我会检查 proc-info 的 mbuf 计数。
    • 问题:在线阅读,我读到如果没有空闲的Tx-desc,rte_eth_tx_burst会返回0。这和 Mbuf.. 不一样对吗?
    • @nmurshed 如果您询问 TX DMA 描述符,是的,从技术上讲,它对于物理 PMD 是正确的。但在虚拟 PMD 的情况下,这是不正确的。
    • `我有你提到的免费代码。我刚刚粘贴了发送的部分代码。`看起来您正在泄漏 mbuf,可以进行快速实时调试(如果有的话)
    • 您好 Vipin,我将尝试设置问题并 ping 您,我们可以检查。到那时,我会尝试检查 dpdk-procinfo 的输出
    猜你喜欢
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多