一、一次十分诡异的现网故障某数据中心部署了一套基于DPDK开发的100GbE高性能交换机。系统上线数月后。现场反馈业务偶尔出现2050ms流量中断。随后自动恢复。整个过程中CPU始终100%。Worker没有退出。PMD持续运行。监控如下指标状态PMD CPU100%RX Queue正常TX Queue正常Descriptor Error0DD Bit正常LinkUp继续抓取网卡统计。发现CRC Error0。Missed Packet0。RX No Buffer0。一切似乎都没有问题。但是交换机就是停止收包几十毫秒。随后又恢复正常。核心知识点一对于DPDK来说DD Bit正常并不意味着RX能够持续运行。真正决定NIC是否还能继续DMA。还有另外一个容易被忽略的条件。二、第一轮排查怀疑DD Bit由于收包停止。团队首先怀疑Descriptor。于是增加调试日志。持续打印Descriptor Status。例如status rxdp-wb.upper.status_error;观察发现DD始终能够正常置位。并不存在Descriptor没有回写的问题。因此排除Write Back异常。三、第二轮排查怀疑RX Ring继续查看RX Ring。发现RDH、RDT均处于合理范围。Descriptor没有耗尽。Ring也没有Overflow。很多开发者此时都会认为RX Ring没有问题。事实上这里恰恰隐藏着真正的陷阱。核心知识点二RX Ring里面保存的不是Packet。保存的是Buffer描述信息。四、很多人一直误解了RX Descriptor第一次阅读Intel网卡手册。很多人都会认为RX Descriptor就是Packet。实际上完全不是。例如Intel 82599Advanced RX Descriptor里面主要包含Packet Buffer Address Header Buffer Address Status Length RSS Hash VLAN Checksum注意。真正的数据并没有存放Descriptor。Descriptor只保存一个DMA目标地址。真正Packet存放在mbuf对应的数据缓冲区。也就是说Descriptor更像一张地址卡片。告诉NIC下一帧数据请DMA到这里。五、真正的数据流是什么收到一个Packet以后。NIC真正执行的是Packet ↓ MAC ↓ RX FIFO ↓ DMA到mbuf Data Buffer ↓ 更新Descriptor Status ↓ DD 1CPU随后读取Descriptor获得Packet Length、RSS、Checksum。然后取得对应mbuf。真正处理Packet。注意。这里CPU已经拿走了这个mbuf。那么问题来了。NIC下一次收到Packet。还能继续DMA到同一个Buffer吗答案不能。核心知识点三一个RX Buffer只能完成一次DMA。Packet被CPU接管以后。NIC必须重新获得一个新的Buffer。才能继续收包。六、真正容易被忽略的一半生命周期很多开发者理解的RX流程只有前半段。例如Packet ↓ DMA ↓ DD1 ↓ CPU收到mbuf于是认为整个RX流程结束。实际上真正完整的生命周期应该是Packet ↓ DMA到mbuf ↓ DD1 ↓ CPU处理Packet ↓ 释放旧Buffer ↓ 重新申请mbuf ↓ 重新填写RX Descriptor ↓ 通知NIC ↓ 下一次DMA也就是说。CPU处理完Packet以后。真正重要的工作才刚刚开始。如果没有新的Buffer。NIC即使收到Packet。也没有地方DMA。七、问题终于开始浮现继续阅读PMD源码。发现rte_eth_rx_burst()并不是收到Packet就结束。真正最后还有一段容易被忽略的代码。它负责分配新的mbuf重新填写RX Descriptor更新RX Tail。看到这里。真正的问题终于浮现。现场DD正常、Descriptor正常、CPU正常。但是NIC为什么还是停止收包真正值得怀疑的已经不是DD Bit。而是RX Buffer Replenishment接收缓冲补充机制。未完待续