软路由的收包环形缓冲调优:rx_fifo_errors 归零记录
背景
一台 J4125 四网口软路由(Intel i225/i226,2.5G),OpenWrt 6.12 内核,承担 PPPoE 拨号与透明代理。设备运行 98 天,业务上未出现明显故障,但网卡统计显示持续收包溢出。
现象
# ethtool -S eth0
rx_fifo_errors: 226372
rx_missed_errors: 48589
rx_no_buffer_count: 1225
# awk '{s+="0x" $2} END{print s}' /proc/net/softnet_stat
632963
三项分别对应网卡环形缓冲耗尽、网卡内部 FIFO 耗尽、内核软中断队列溢出。同期物理层统计为 rx_crc_errors = 0、rx_errors = 0、collisions = 0,排除线路与协商问题,指向处理侧取包速度不足。
# ethtool -g eth0
Pre-set maximums: RX: 4096 TX: 4096
Current hardware settings: RX: 256 TX: 256
硬件支持 4096 个描述符,实际配置为 256 个,即 OpenWrt 默认值。该值适用于千兆场景,在 2.5G 链路上不足以吸收突发流量。
影响
TCP 吞吐近似为 MSS/RTT × 1.22/√p。平均丢包率 0.007% 时影响可忽略,但丢包成簇时危害显著:丢失单个报文触发快速重传,丢失整个窗口则触发 RTO,连接在该时段内无有效吞吐,表现为下载停滞与速率锯齿。
本机为代理出口,数据路径为 WAN 入、LAN 出,同一份数据存在两次入队机会;PPPoE 的 MTU 1492 又使单位字节的报文数比 1500 高约 0.5%,丢包概率相应上升。
处置
ethtool -G eth0 rx 2048 tx 2048
ethtool -G eth1 rx 2048 tx 2048
ethtool -G eth3 rx 2048 tx 2048
内存代价约 11MB。注意 ethtool -G 会复位链路:对 WAN 口执行将触发一次 PPPoE 重拨,IP 保持不变,中断约 10 秒,应避开业务时段。
验证
路由器本机并发 8 路下载,持续 25 秒,实测 575 Mbps:
| 指标 | 处置前(累计) | 压测期间增量 |
|---|---|---|
eth3 rx_fifo_errors |
1,052,074 | 0 |
eth0 rx_fifo_errors |
226,372 | 0 |
| softnet 溢出 | 632,963 | 0 |
| TCP 重传率 | 0.615%(98 天) | 0.0068% |
| CPU | — | sys 1.6%,softirq 0.2%,idle 96.8% |
| 往返时延 | 8.7–9.9 ms | 8.7–9.9 ms |
单流带宽 169–292 Mbps,双流 206 Mbps,八流 575 Mbps,均受对端限速约束,转发侧未见瓶颈。
持久化与判读
ethtool 修改为运行时状态,重启后恢复默认。在 /etc/rc.local 的 exit 0 之前加入:
for p in eth0 eth1 eth3; do ethtool -G $p rx 2048 tx 2048; done
日常判读只看增量:
for p in eth0 eth3; do
echo "$p fifo=$(ethtool -S $p | awk '/rx_fifo_errors:/{print $2}') carrier=$(cat /sys/class/net/$p/carrier_changes)"
done
- 满速时
fifo持续增长:继续提高至 4096,或启用硬件流卸载 fifo增量恒为零:累计值不会归零,无需处理
评论