You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DPDK应用持续出现rx_phy_discard_packets问题求助

问题:ConnectX-6网卡在70-85Gbps区间出现rx_phy_discard_packets增长

背景信息

我正在使用DPDK从Mellanox ConnectX-6网卡端口获取并处理数据包,目标流量为100Gbps。用于打印网卡统计信息的线程代码如下:

static void lcore_main_display_stats(void)
{
    struct rte_eth_xstat_name xstat_names[MAX_XSTATS];
    int retval;
    int num_xstats = 0;
    struct rte_eth_stats stats;
    struct rte_eth_xstat xstats[MAX_XSTATS];
    uint64_t prev_reading = 0;
    uint64_t current_diff = 0;


    while (MAIN_KEEP_RUNNING == main_keep_running)
    {
        fflush(stdout);
        if (PORT_ACTIVE == downlink1_port.port_status)
        {
            // Get standard statistics
            retval = rte_eth_stats_get(downlink1_port.port_id, &stats);

            // Get extended statistics names
            num_xstats = rte_eth_xstats_get_names(downlink1_port.port_id, xstat_names, MAX_XSTATS);

            // Get extended statistics
            retval = rte_eth_xstats_get(downlink1_port.port_id, xstats, num_xstats);

            current_diff = stats.ibytes - prev_reading;
            Gbps = (current_diff / 1024.0 / 1024.0 / 1024.0) * 8;
            prev_reading = stats.ibytes;
            
            // Get standard statistics
            retval = rte_eth_stats_get(downlink1_port.port_id, &stats);
            if (retval != 0)
            {
                fprintf(stderr, "Failed to get standard stats for port %u: %s\n", downlink1_port.port_id, rte_strerror(-retval));
                return;
            }

            printf("\n--- Standard Statistics ---\n");
            printf("Packets received: %" PRIu64 "\n", stats.ipackets);
            printf("Packets transmitted: %" PRIu64 "\n", stats.opackets);
            printf("Bytes received: %" PRIu64 "\n", stats.ibytes);
            printf("Giga bytes received: %f\n", ((double)stats.ibytes / 1024.0 / 1024.0 / 1024.0));
            printf("Bytes transmitted: %" PRIu64 "\n", stats.obytes);
            printf("RX errors: %" PRIu64 "\n", stats.ierrors);
            printf("TX errors: %" PRIu64 "\n", stats.oerrors);
            printf("Missed packets: %" PRIu64 "\n", stats.imissed);
            printf("Missed packets%%: %f\n", ((double)stats.imissed/stats.ipackets)*100);
            for (int i = 0; i < num_xstats; i++)
            {
                if (!strcmp("rx_phy_discard_packets", xstat_names[i].name))
                {
                    printf("%s: %" PRIu64 "\n", xstat_names[i].name, xstats[i].value);
                    printf("Discarded packet percentage: %f%%\n", ((double)xstats[i].value / stats.ipackets) * 100);
                }
            }
            printf("RX no mbuf errors: %" PRIu64 "\n", stats.rx_nombuf);
            printf("Gbps: %f \n", Gbps);
        }

        sleep(ONE_SECOND_SLEEP_TIME);
        fflush(stdout);
    }
}

异常现象

  • rx_phy_discard_packets(物理层接收丢弃包)在吞吐量处于70-85Gbps区间时持续增长,当吞吐量达到90Gbps后停止增长
  • imissed(错过的数据包)数值保持初始值无增长
  • 已尝试将MTU调整至9600,问题仍未解决

统计输出示例:

Packets received: 6113919634
Packets transmitted: 0
Bytes received: 6369429122446
Giga bytes received: 5931.993129
Bytes transmitted: 0
RX errors: 0
TX errors: 0
Missed packets: 148596
Missed packets%: 0.002430
rx_phy_discard_packets: 12258048
Discarded packet percentage: 0.200494%
RX no mbuf errors: 0
Gbps: 78.914868 

原因分析

  • 物理层流量适配瓶颈:ConnectX-6的PHY层在中等速率区间(70-85Gbps)可能无法高效处理突发流量,当速率提升到90Gbps时,流量模式可能更稳定(如大包占比升高),PHY层缓冲压力降低,丢弃停止
  • RX队列配置不匹配:DPDK的RX队列描述符数量不足,或者队列与CPU核绑定不合理,导致PHY层无法及时将数据包递送到DPDK的mbuf,触发物理层丢弃
  • 硬件缓冲调度策略:ConnectX系列的硬件缓冲(Packet Buffer)在中等速率下可能预留部分资源给其他功能(如RDMA),导致RX侧缓冲不足;高速率时调度策略切换为优先保障转发,缓冲资源向RX倾斜
  • 流量特征影响:70-85Gbps区间可能小包占比更高,小包会增加PHY层的帧处理开销,更容易触发丢弃;而90Gbps时大包占比提升,单帧处理效率更高,减少了PHY层的压力

排查建议

  • 检查网卡硬件缓冲配置:使用mlxconfig工具查看LOG_BAR、RX_BUFFER_SIZE等参数,确认RX路径分配的缓冲是否充足
  • 调整DPDK RX队列参数:尝试增加RX队列描述符数量(建议设置为2048或4096),同时确保每个RX队列绑定到独立的CPU核,避免核资源竞争
  • 分析流量特征:用rte_pdump抓取流量,统计小包(<64字节)和大包的占比,确认是否在70-85Gbps区间小包占比偏高
  • 查看更多扩展统计:除rx_phy_discard_packets外,检查rx_phy_errors、rx_buffer_overflows等指标,定位具体丢弃原因
  • 验证驱动版本:确认DPDK版本与MLNX_OFED驱动版本匹配,建议升级到DPDK 22.11+、MLNX_OFED 5.8+等稳定版本

解决方案

  • 优化RX队列配置:将RX描述符数量调整为4096,根据CPU核数配置足够的RX队列,每个队列绑定到独占CPU核(通过rte_eth_dev_configure和rte_eth_rx_queue_setup实现)
  • 调整硬件缓冲:使用mlxconfig增大RX_BUFFER_SIZE(如设置为4096KB),关闭不需要的功能(如RDMA)以释放更多缓冲给RX路径
  • 优化流量模式:若小包占比高是诱因,可在发送端合并小包,或在网卡侧开启LRO(Large Receive Offload)功能(需DPDK驱动支持)
  • 调整内存配置:增大mbuf池的大小,确保RX队列有足够的mbuf可用(尽管当前rx_nombuf为0,适当增大rte_pktmbuf_pool_create的参数可预留冗余)
  • 升级驱动与固件:更新ConnectX-6的网卡固件到最新版本,同时升级DPDK和MLNX_OFED驱动至匹配的稳定版本

内容的提问来源于stack exchange,提问作者Alsayed Alsisi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:37:34