一、故障背景
某运营商数据中心部署了一套基于DPDK开发的100G高性能交换机。
交换机承担:
VXLAN网关
L2交换
L3转发
ACL过滤
系统采用:
Intel 100G网卡
双路Xeon服务器
每端口8个RX Queue
每Queue绑定一个PMD线程
上线半年后:
业务规模扩大。
监控发现:
PPS下降约12%
P99时延增加
CPU仍然100%
网卡Error为0
RX Queue正常
所有常见指标全部正常。
二、第一轮排查
查看DPDK统计:
rte_eth_stats_get();得到:
imissed=0 ierrors=0 rx_nombuf=0继续查看:
ethtool -S结果:
CRC Error:0
RX Miss:0
DMA Error:0
排除:
网卡故障。
核心知识点一
Descriptor并不是数据包。
Descriptor只是:
网卡与CPU之间共享的一段元数据。
真正的数据:
仍然存放在DMA写入的Buffer中。
三、第二轮排查
继续分析:
nb_rx=rte_eth_rx_burst(...);发现:
收包数量:
具有明显波动。
例如:
32 31 30 0 64 32 28平均:没有问题。
但是:出现短暂:"空轮询"
随后:大量Packet一起返回。
为什么?
四、Descriptor到底发生了什么?
Intel网卡:DMA完成以后。
不会立即更新Descriptor状态。
而是采用:Write-Back机制。
即:多个Descriptor统一回写。
这样可以:减少PCIe事务。提高总吞吐。
五、Descriptor Write-Back
正常流程:
DMA完成 ↓ Descriptor Ready ↓ Write Back ↓ CPU读取DD位 ↓ PMD收包注意:Descriptor已经完成。
并不代表:CPU已经知道。
CPU看到的是:Write-Back之后的状态。
核心知识点二
DMA完成 ≠ Descriptor已经更新
Descriptor更新 ≠ PMD已经看到
中间:存在:PCIe Write-Back。
六、为什么Intel这样设计?
如果:每完成一个Packet。
立即:PCIe写一次Descriptor。
PCIe事务数量:巨大。
因此:Intel采用:Batch Write-Back。
例如:连续完成:16个Packet。统一:更新Descriptor。
减少PCIe带宽消耗。
这是:典型:吞吐优先设计。
七、问题开始出现
业务扩容以后:Packet到达:
开始:不连续。
例如:
12 15 17 14无法快速凑满:Write-Back Batch。
于是:CPU:不断轮询:DD位。
但是:Descriptor:迟迟没有更新。
PMD:认为:没有Packet。继续轮询。
随后:一次:收到:几十个Packet。
于是:延迟:突然增加。
八、为什么没有丢包?
因为:Packet:已经DMA完成。
只是:CPU不知道。
因此:NIC:没有Error。
DPDK:没有Error。
系统:没有Error。
真正增加的是:等待时间。
核心知识点三
PMD轮询的:不是Packet。
而是:Descriptor状态。
Descriptor没有Write-Back。
PMD就认为:没有Packet。
九、Perf分析
使用:
perf stat发现:
CPU:Instructions变化很小。
Cycles:略增加。
Backend Stall:增加。
说明:
CPU:一直读取:Descriptor。
却:不断失败。
形成:空轮询。
十、深入PCIe事务
Write-Back:本质:PCIe Memory Write。
多个Descriptor:会:合并:Posted Write。
减少:Transaction Layer Packet。
因此:吞吐:更高。
但是:实时性:下降。
十一、为什么只有业务扩容后才出现?
因为:Write-Back:依赖:Packet到达节奏。
高负载:连续流。Write-Back:很快完成。
中等负载:Packet:断断续续。Write-Back:等待时间:增加。
于是:Latency:开始:抖动。
十二、优化方案
第一:
调整:RX Free Threshold。
减少:Write-Back等待。
第二:
优化:Burst Size。
第三:
增加:Prefetch距离。
第四:
降低:Descriptor Cache Miss。
第五:
根据:业务模型。调整:Queue深度。
核心知识点四
Descriptor Ring:不是:越大越好。
Ring越大。Write-Back:等待:可能越长。
需要:根据:业务:调整。
十三、优化结果
调整:
Descriptor参数后:
| 指标 | 优化前 | 优化后 |
|---|---|---|
| PPS | 下降12% | 恢复 |
| P99 | 16μs | 7μs |
| 空轮询比例 | 18% | 3% |
CPU:仍然100%。
但是:Packet:更加均匀。
核心知识点总结
知识点一
Descriptor只是DMA元数据,不是数据包本身。
知识点二
DMA完成并不意味着PMD立即能够收包。
知识点三
Intel网卡采用Batch Write-Back降低PCIe事务数量。
知识点四
PMD轮询的是Descriptor状态,而不是直接轮询网卡数据。
知识点五
Write-Back策略是一种吞吐优先设计,会牺牲部分实时性。
知识点六
中等负载比满负载更容易暴露Write-Back引起的时延抖动。
知识点七
Descriptor Ring大小、Burst Size和RX Free Threshold需要联合调优。
总结
DPDK性能优化通常聚焦于CPU、NUMA、RSS等热点,但在高速交换机场景中,更底层的Descriptor Write-Back机制同样可能成为性能瓶颈。由于DMA完成、Descriptor回写和PMD感知之间存在时间差,当业务流量呈现突发且不连续的特征时,CPU可能长时间进行无效轮询,而真正的数据包已经到达内存却尚未对软件“可见”。理解这一机制,有助于解释许多“CPU正常、网卡正常、系统无错误但时延抖动”的复杂现网问题,也为Descriptor参数调优提供了更加扎实的理论基础。