【实战记录】解决 Debian 13 (PVE内核) 下 Intel e1000e 网卡间歇性 “Hardware Unit Hang” 断网故障

作者: Penny 分类: linux 发布时间: 2025-12-05 20:22

关键词:Debian 13, Proxmox VE, e1000e, Hardware Unit Hang, TSO Offload

1. 故障现象

在一台运行 Debian 13 (Trixie) 的服务器上,使用 Proxmox VE 6.14.11-2-pve 内核。网卡型号为 Intel I219-V (使用 e1000e 驱动)。

  • 症状:服务器运行一段时间后网络突然中断,SSH 掉线。
  • 临时恢复:重启网卡服务往往无效,必须重启服务器 (Reboot) 才能恢复。
  • 环境信息
    • Driver: e1000e
    • Kernel: 6.14.11-2-pve
    • Bus-info: 0000:00:1f.6

2. 排查过程

通过 dmesgjournalctl -k 查看内核日志,在故障发生时间点捕捉到大量网卡挂起报错:

Bash

2025-12-05T08:48:15.799435+08:00 pod1 kernel: e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
2025-12-05T08:48:15.799450+08:00 pod1 kernel:   TDH                  <d>
2025-12-05T08:48:15.799450+08:00 pod1 kernel:   TDT                  <7a>
2025-12-05T08:48:15.799451+08:00 pod1 kernel:   next_to_use          <7a>
2025-12-05T08:48:15.799452+08:00 pod1 kernel:   next_to_clean        <c>
2025-12-05T08:48:15.799484+08:00 pod1 kernel: buffer_info[next_to_clean]:
2025-12-05T08:48:15.799485+08:00 pod1 kernel:   time_stamp           <15f13f909>
2025-12-05T08:48:15.799486+08:00 pod1 kernel:   next_to_watch        <d>
2025-12-05T08:48:15.799486+08:00 pod1 kernel:   jiffies              <15f142140>
2025-12-05T08:48:15.799487+08:00 pod1 kernel:   next_to_watch.status <0>
2025-12-05T08:48:15.799487+08:00 pod1 kernel: MAC Status             <40080043>
2025-12-05T08:48:15.799488+08:00 pod1 kernel: PHY Status             <796d>
2025-12-05T08:48:15.799490+08:00 pod1 kernel: PHY 1000BASE-T Status  <0>
2025-12-05T08:48:15.799491+08:00 pod1 kernel: PHY Extended Status    <3000>
2025-12-05T08:48:15.799491+08:00 pod1 kernel: PCI Status             <10>
...

3. 故障根因

这是 Linux 内核中 e1000e 驱动的一个经典 Bug,在较新的内核版本(尤其是 5.15+ 到 6.x)配合特定批次的 Intel I219 系列网卡时极易触发。

原因简述:

网卡的 TCP 分段卸载 (TSO, TCP Segmentation Offload) 和通用分段卸载 (GSO) 功能在处理高并发或特定数据包时,可能导致网卡的环形缓冲区 (Ring Buffer) 指针计算错误或死锁,导致网卡硬件挂起并尝试重置。

4. 解决方案

解决核心思路是关闭网卡的硬件卸载功能,将分段处理工作交还给 CPU(现代 CPU 处理这点开销均可忽略不计)。

步骤一:临时验证(立即生效)

在终端执行以下命令(假设网卡名为 eno1):

Bash

sudo ethtool -K eno1 tso off gso off gro off

执行后观察日志,若 Hardware Unit Hang 不再出现,则确定为该问题。

步骤二:持久化配置(重启生效)

Debian/PVE 环境推荐使用 /etc/network/interfaces 进行配置。

  1. 编辑网络配置文件:Bashsudo nano /etc/network/interfaces
  2. 找到对应网卡(如 eno1)的配置块,在 iface ... 下方添加 post-up 指令:Plaintextauto eno1 iface eno1 inet static address 192.168.1.100/24 gateway 192.168.1.1 # 添加以下这行,关闭 TSO/GSO/GRO post-up /usr/sbin/ethtool -K eno1 tso off gso off gro off
  3. 保存退出。

替代方案:Systemd 服务法

如果不使用 interfaces 文件管理网络,可以通过 systemd 实现开机自启:

创建文件 /etc/systemd/system/e1000e-fix.service

Ini, TOML

[Unit]
Description=Disable offloading for e1000e to prevent hang
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ethtool -K eno1 tso off gso off gro off

[Install]
WantedBy=multi-user.target

启用服务:

Bash

sudo systemctl enable --now e1000e-fix

5. 补充措施 (可选)

如果关闭 Offload 后仍偶发断网,可能是电源管理 (ASPM) 问题。可修改 GRUB 配置:

  1. 编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX_DEFAULT 中追加:pcie_aspm=off
  2. 更新 GRUB:update-grub

6. 验证

配置完成后重启服务器,使用以下命令确认 Offload 状态:

Bash

ethtool -k eno1 | grep -E "tcp-segmentation-offload|generic-segmentation-offload"

输出应显示为 off

Plaintext

tcp-segmentation-offload: off
generic-segmentation-offload: off

这个问题的根源在于 软硬件协同工作的“沟通失误”

您可以把网卡的工作机制理解为一条流水线。为了让您透彻理解为什么会出现 TDH <d>TDT <7a> 这种死锁,我用一个形象的机制模型来解释:

1. 核心机制:环形缓冲区 (Ring Buffer)

网卡和操作系统之间并不直接传数据,而是通过内存中的一个“环形队列”来交换指令。

  • TDT (Tail):由**操作系统(驱动)**控制。每当 CPU 准备好数据包,就会把数据塞进队列,并把 TDT 指针往后移一格(告诉网卡:“我有新活儿给你”)。
  • TDH (Head):由网卡硬件控制。网卡处理完一个数据包,就把 TDH 指针往后移一格(告诉 CPU:“这单干完了”)。

正常情况下:CPU 往后推 TDT,网卡拼命追 TDH,两者就像是在操场上跑圈,虽有距离但一直在动。

2. 故障复盘:发生了什么?

您的日志显示:

  • TDT (驱动已推送到) = 0x7a
  • TDH (硬件停留在) = 0xd
  • 差距:中间差了大量的任务。

这就好比:作为老板(CPU),您已经把单子发到了第 122 号(0x7a),但员工(网卡)却死死卡在第 13 号(0xd)不动了。老板不停地催(Watchdog Timer),发现员工还没动,于是报错 Detected Hardware Unit Hang(检测到硬件单元挂起)。

3. 罪魁祸首:TSO (TCP 分段卸载)

为什么网卡会卡在那个位置不动?绝大多数是因为 TSO (TCP Segmentation Offload) 技术。

  • 没有 TSO 时: CPU 把大文件切成 1500 字节的小包,一个个喂给网卡。网卡只需要做简单的“搬运工”,很轻松,不易出错。
  • 开启 TSO 时 (现在的默认状态): CPU 为了偷懒,把一个 64KB 的超级大包直接丢给网卡,说:“你自己切成小块发出去,别烦我。” Intel I219-V 这款网卡(常见于消费级主板或工作站)在处理由于高版本内核(PVE 6.x)发来的某种特定序列的 TSO 大包时,内部的硅片逻辑(Silicon Logic)会出现计算死锁或 DMA 传输卡顿。简单说:CPU 扔了一块“大骨头”给网卡,网卡吞不下去,噎死了(Hang)。

4. 为什么是 PVE / Debian 13?

  • 内核激进:新的 Linux 内核(5.15+ 到 6.x)对网络栈进行了大量优化,发包速度更快,聚合度更高,给硬件施加的压力更大。
  • 硬件缺陷:Intel I219-V 其实是 PHY(物理层芯片)配合 PCH(南桥)逻辑工作的“软网卡”变种,它没有像服务器级网卡(如 Intel I350, X540)那样拥有强大的独立处理核心和巨大的片上缓存。面对高压 TSO 请求,它很容易“算不过来”。

总结

之所以让您执行 ethtool -K eno1 tso off ...,就是不再让网卡切肉。 我们强行让 CPU 把数据切好(CPU 现在性能过剩,切这点包毫无压力),再喂给网卡。虽然 CPU 负载微乎其微地增加了一点点,但网卡回归到了最傻瓜、最稳定的“搬运工”模式,从而彻底规避了它内部逻辑的 Bug。