100G交换机最难定位的故障——DPDK Memory Ordering(内存序)深度解析(上)

📅 2026/7/3 18:30:16
100G交换机最难定位的故障——DPDK Memory Ordering(内存序)深度解析(上)
一、一个几乎无法复现的现网故障某运营商数据中心部署了一套基于DPDK开发的100G高性能交换机。系统采用每Queue绑定一个PMD Worker无锁数据平面Session采用DPDK Hash管理控制面负责动态下发转发表。系统已经稳定运行半年。累计转发数据包超过数千亿。就在所有人都认为系统已经足够稳定时。现场开始反馈极偶尔某些新建立的业务流第一个数据包会被错误丢弃。第二个包立即恢复正常。整个异常持续时间不到1毫秒。概率低到一天可能只发生一两次。查看所有监控。全部正常。指标状态PMD CPU100%RSS正常RX Queue正常TX Queue正常NIC Error0Session数量正常控制面日志显示Session已经创建成功。数据面日志却偶尔打印Session Not Found几百微秒以后再次查询Session又能够正常找到。整个现象像极了Session凭空消失。核心知识点一真正困难的故障往往不是100%复现。而是百万分之一概率。因为概率越低。越说明问题不是业务逻辑。而更可能来自底层硬件行为。二、第一轮排查怀疑Hash由于日志显示Session查询失败。团队第一反应Hash出了问题。于是增加统计。记录rte_hash_lookup_data()所有返回值。连续运行48小时。结果Hash没有任何异常。Bucket没有冲突。Hash Miss始终为0。说明Hash没有问题。三、第二轮排查怀疑RCU继续分析。控制面负责创建Session。数据面负责查询Session。因此又怀疑是不是RCU同步存在问题。继续检查版本API。Grace Period全部正常。RCU没有异常。核心知识点二当Hash RCU 锁。全部排除以后。真正应该怀疑的是数据什么时候真正对其它CPU可见注意这里讨论的已经不是数据有没有写。而是什么时候能够被另一个CPU看到。四、第三轮排查代码没有问题继续阅读控制面更新流程。代码非常简单。例如session-action action; session-counter counter; session-flags READY; publish(session);逻辑完全正确。没有空指针。没有竞争。没有锁。没有异常。但是数据面偶尔却看到flags READY action NULL这意味着CPU居然先看到了READY。却没有看到真正的数据。这几乎违背所有人的直觉。核心知识点三很多开发者默认认为代码按照书写顺序执行。实际上现代CPU并不保证这一点。五、重新认识CPU很多教材都会画出这样的执行过程Store A ↓ Store B ↓ Store C于是大家自然认为CPU一定也是这样执行。实际上现代CPU为了提高吞吐。采用Out-of-Order Execution乱序执行。真正发生的事情可能是Store B ↓ Store A ↓ Store C甚至CPU已经完成Store。另一个核心仍然看不到最新数据。六、为什么CPU要乱序如果CPU严格按照程序顺序执行。很多流水线都会空闲。例如Load ↓ 等待内存 ↓ 继续执行CPU大量时间浪费等待。于是现代处理器开始提前执行后面的无关指令。例如Store A Store B Load CCPU可能先完成Load C。再回来执行Store A。整个过程对于单线程结果完全正确。但是对于多核心另一个CPU观察到的顺序就可能发生变化。核心知识点四程序执行顺序 ≠ CPU执行顺序 ≠ 其它CPU观察到的顺序。这是理解Memory Ordering最重要的一句话。七、问题开始指向Memory Ordering继续检查Session发布流程。发现最后一步只是publish(session);整个过程没有任何Barrier。也没有Memory Fence。控制面认为数据已经全部写完。于是通知Worker可以开始使用。但是CPU真的保证其它核心一定已经看到这些写操作了吗真正的问题开始指向Memory Ordering……未完待续