为什么网卡停止收包?——Intel网卡RX Buffer Replenishment机制深度解析(下)

接上文:为什么网卡停止收包?——Intel网卡RX Buffer Replenishment机制深度解析(上)-CSDN博客

八、rte_eth_rx_burst()真正做了什么?

很多开发者认为:

rte_eth_rx_burst()

只是从网卡取Packet。

实际上对于Intel PMD来说RX Burst通常包含四个阶段:

检查DD Bit

        ↓

取出mbuf

        ↓

补充新的RX Buffer

        ↓

更新RDT

真正保证RX能够持续运行的。

不是DD。

而是后两步。

如果没有新的Buffer。

整个RX Ring最终都会被消费完。


核心知识点四

RX Descriptor是可以重复使用的。

真正需要不断重新分配的是:Descriptor关联的mbuf Buffer。

Descriptor只是重新写入新的DMA地址。


九、PMD为什么不停申请新的mbuf?

来看Intel PMD的大致流程。

逻辑可以抽象为:

mbuf = rte_pktmbuf_alloc(rxq->mb_pool);

rxdp->pkt_addr = rte_mbuf_data_iova(mbuf);

rxdp->hdr_addr = 0;

这里并没有重新创建Descriptor。

而是把新的mbuf地址重新写入Descriptor。

于是NIC:下一次收到Packet。

便可以继续DMA。

如果这里没有成功申请mbuf。

意味着Descriptor没有新的DMA目标。

NIC最终就会没有Buffer可以使用。


十、为什么不会每处理一个Packet就更新RDT?

继续阅读PMD源码。

会发现:更新RDT通常不是每个Packet执行。

而是满足一定条件。

例如:

rx_free_thresh

达到以后。

一次补充一批Descriptor。

最后统一更新RDT。

为什么?

如果每处理一个Packet。

就写一次RDT。

意味着:CPU需要不断访问NIC寄存器。

对于PCIe设备来说。

寄存器属于MMIO。

一次MMIO远远比普通Cache访问昂贵。

因此。

Intel PMD采用批量更新。

大幅减少Doorbell。

提升吞吐。


核心知识点五

RDT更新属于MMIO操作。

它的成本远高于普通内存写。

因此:PMD一定采用批量更新。


十一、RDT到底是什么?

Intel网卡维护两个重要指针。

RDH

Receive Descriptor Head

NIC维护


RDT

Receive Descriptor Tail

Driver维护

可以理解为:

RDH ------------->

Descriptor Ring

<------------- RDT

其中:

RDH表示NIC已经消费到哪里。

RDT表示驱动已经准备好多少新的Buffer。

NIC只能在RDH和RDT之间继续DMA。

如果RDH追上RDT。

说明已经没有新的Buffer。

即使链路仍然收到Packet。

NIC也只能停止接收。

直到Driver再次推进RDT。


核心知识点六

真正决定NIC还能继续DMA。

不是DD。

而是:RDT后面是否还有可用Buffer。


十二、为什么现场会出现"停止几十毫秒"?

继续分析现场日志。

最终发现。

某版本为了减少mbuf申请次数。

修改了补充策略。

导致:

rx_free_thresh

设置过大。

结果:

CPU一直忙于业务处理。

长时间没有进入补Buffer流程。

NIC不断消耗Descriptor。

最终:

RDH追上RDT。

RX短暂停止。

随后:

CPU终于完成一次批量补充。

更新RDT。

NIC立即恢复DMA。

整个过程:持续几十毫秒。

与现场现象:完全一致。


十三、为什么DPDK一定使用Mempool?

有人会问既然不断申请mbuf。

为什么不用malloc()?

原因就在于RX路径必须极快。

Mempool能够提供固定大小对象。

Lockless。

Cache友好。

NUMA感知。

批量分配。

如果改成系统malloc。

不仅延迟增加。碎片也会越来越严重。

最终:RXBuffer补充速度下降。影响整个RX流水线。

因此高速数据平面几乎都会使用对象池。而不会动态申请内存。


核心知识点七

RX Buffer Replenishment:本质上不是内存管理问题。

而是:高速DMA流水线的一部分。


十四、RX完整生命周期

理解整个RX路径最好的方式就是记住下面这条完整生命周期。

Packet

        │
        ▼

NIC收到Packet

        │
        ▼

DMA写入mbuf

        │
        ▼

Descriptor DD=1

        │
        ▼

CPU读取Descriptor

        │
        ▼

CPU处理Packet

        │
        ▼

旧mbuf交付协议栈

        │
        ▼

申请新的mbuf

        │
        ▼

重新填写Descriptor

        │
        ▼

更新RDT

        │
        ▼

NIC继续DMA

真正:高性能RX路径实际上是一个不断循环补充Buffer的过程。


十五、全文总结

很多DPDK开发者把注意力集中在DD Bit,因为DD代表一个Descriptor已经可以被CPU处理。

然而,对于网卡来说,DD只是一次DMA完成的标志,并不意味着RX生命周期结束。

真正保证RX持续运行的是:

  • CPU及时回收Descriptor;
  • 分配新的mbuf;
  • 重写Descriptor中的DMA地址;
  • 批量更新RDT,让NIC获得新的可用Buffer。

只有这一整套Buffer Replenishment机制持续运行,RX流水线才能始终保持满速。

因此,从工程角度看,DD Bit回答的是"这个包好了没有",而RDT回答的是"下一个包还有没有地方可放"。

理解两者的区别,比单独理解DD Bit更重要。


全文核心知识点

  1. Descriptor保存的是DMA目标地址,而不是Packet数据。
  2. 每个RX Buffer通常只能完成一次Packet DMA,需要不断补充新的mbuf。
  3. rte_eth_rx_burst()不仅负责收包,还负责Buffer Replenishment。
  4. PMD采用批量补充Descriptor和批量更新RDT,以减少MMIO开销。
  5. RDT决定NIC还能否继续接收新的Packet,而DD仅表示当前Descriptor已经完成DMA。
  6. rx_free_thresh直接影响Buffer补充时机,配置不合理可能导致RX停顿。
  7. Mempool不仅是内存池,更是高速RX流水线的重要组成部分。
  8. 理解"Packet→DMA→DD→CPU→补Buffer→更新RDT→继续DMA"这一完整生命周期,是理解Intel网卡RX机制的关键。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.HeBoYan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值