跳转到内容
Lnblxj's Blog
返回

Intel I219-V + e1000e 断网排障记录:从运行中失联到冷启动链路抖动

Edit this page

记录一次 Ubuntu Server + KVM + Docker 环境下的网络故障排查。板载 Intel I219-V 在 e1000e 驱动下遇到高负载/虚拟化网络场景时发生 TX Hang;关闭 EEE 和部分 offload 后解决了运行中断网,但需要延迟应用 ethtool 设置,避免冷启动时链路反复协商。

环境

服务器环境大致如下:

桥接结构简化如下:

eno1
  └── br0
        ├── host
        └── KVM VM / vnet

初始故障现象

最早的问题是服务器运行一段时间后突然失联:

一开始看起来像是 Docker、KVM bridge、路由器或者 DHCP 的问题。但从故障影响范围看,宿主机和所有虚拟机同时失联,更像是物理出口 eno1 本身出了问题。

关键日志

查看上一次启动的内核日志:

journalctl -k -b -1 --no-pager | grep -iE 'e1000e|eno1|hardware unit hang'

发现大量重复日志:

e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang

而且是每 2 秒左右刷一次,持续到机器被手动重启。

这基本说明问题不在上层网络配置,而在物理网卡/驱动路径。Hardware Unit Hang 通常意味着网卡发送队列或硬件单元卡住了。由于 eno1br0 的底层物理接口,所以它一挂,宿主机、KVM 虚拟机、Docker 对外通信都会一起失联。

第一次处理:关闭 EEE

EEE,即 Energy Efficient Ethernet,是一种以节能为目标的以太网省电机制。对一些 Intel 板载网卡来说,在高负载、虚拟化、桥接网络场景下,它可能会参与触发链路异常。

先查看状态:

sudo ethtool --show-eee eno1

关闭 EEE:

sudo ethtool --set-eee eno1 eee off

为了持久化,创建 systemd 服务:

sudo tee /etc/systemd/system/disable-eee-eno1.service >/dev/null <<'EOF'
[Unit]
Description=Disable EEE on eno1
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ethtool --set-eee eno1 eee off
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now disable-eee-eno1.service

验证:

sudo ethtool --show-eee eno1

期望看到:

EEE status: disabled

不过这一步之后,故障仍然复现。说明 EEE 不是唯一原因。

第二次触发:虚拟机高 CPU 负载

后来又出现一次断网,这次触发条件:在 KVM 虚拟机里跑了高 CPU 占用程序。

虚拟机 CPU 高,为什么宿主机网卡会挂?

但虚拟机并不是另一台物理机器。它实际上是宿主机上的 qemu-system-x86_64 进程,虚拟网卡走的是 virtio-nettapvhost-net、Linux bridge,再到物理网卡 eno1

高 CPU 负载可能改变这些路径的时序:

高负载改变了驱动、网卡、中断、桥接网络之间的时序,触发了本来就不稳定的边界条件。

第二阶段处理:关闭 offload

继续查看 offload 状态:

ethtool -k eno1 | grep -E 'tcp-segmentation-offload|generic-segmentation-offload|generic-receive-offload|scatter-gather|tx-checksumming|rx-checksumming'

关闭关键 offload:

sudo ethtool -K eno1 tso off gso off gro off sg off tx off rx off

验证结果:

rx-checksumming: off
tx-checksumming: off
scatter-gather: off
tcp-segmentation-offload: off
generic-segmentation-offload: off
generic-receive-offload: off

运行中随机断网的问题明显改善,没有再复现。

代价是宿主 CPU 需要承担更多网络包处理工作。

新问题:冷启动后不自动联网

关闭 offload 后,又出现了新问题:

查看本次启动日志:

journalctl -b --no-pager | grep -iE 'eno1|br0|e1000e|networkd|disable-eee|disable-eno1-offload|carrier|link is'

发现启动早期 eno1 本来已经协商成功:

eno1: NIC Link is Up 1000 Mbps Full Duplex
br0: Gained carrier

但两个 ethtool 持久化服务同一时间执行后,链路开始反复抖动:

eno1: Lost carrier
eno1: Gained carrier
eno1: Lost carrier
eno1: Gained carrier

这说明:offload 设置本身有用,但在冷启动太早执行时,可能触发 e1000e 重置或重新协商,导致链路不稳定。

最终 workaround:延迟应用 ethtool 设置

解决办法是不要在网络刚起来时立即改网卡参数,而是等系统进入多用户状态后延迟一段时间,再统一应用 EEE/offload 设置。

先禁用之前两个服务:

sudo systemctl disable --now disable-eee-eno1.service disable-eno1-offload.service

创建新的延迟服务:

sudo tee /etc/systemd/system/fix-eno1-ethtool.service >/dev/null <<'EOF'
[Unit]
Description=Apply stable ethtool settings for eno1
After=multi-user.target systemd-networkd.service
Wants=systemd-networkd.service

[Service]
Type=oneshot
ExecStartPre=/usr/bin/sleep 60
ExecStart=/usr/sbin/ethtool --set-eee eno1 eee off
ExecStart=/usr/sbin/ethtool -K eno1 tso off gso off gro off sg off tx off rx off
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now fix-eno1-ethtool.service

验证服务状态:

systemctl status fix-eno1-ethtool.service --no-pager

验证 EEE:

ethtool --show-eee eno1

验证 offload:

ethtool -k eno1 | grep -E 'tcp-segmentation-offload|generic-segmentation-offload|generic-receive-offload|scatter-gather|tx-checksumming|rx-checksumming'

如果冷启动后仍然链路抖动,可以把:

ExecStartPre=/usr/bin/sleep 60

改成:

ExecStartPre=/usr/bin/sleep 120

然后执行:

sudo systemctl daemon-reload
sudo systemctl restart fix-eno1-ethtool.service

额外观察

排查过程中还看到:

如果上述 workaround 后仍然复现,可以继续尝试:

sudo ethtool --set-priv-flags eno1 s0ix-enabled off
sudo ethtool --set-priv-flags eno1 disable-k1 on

但这些属于更深一层的省电路径调整,建议先观察 EEE + offload + 延迟应用是否足够稳定。

最终结论

Intel I219-V + e1000e 在高负载/虚拟化网络场景下发生 Hardware Unit Hang
  1. 关闭 EEE
  2. 关闭关键 offload:TSO/GSO/GRO/SG/TX/RX checksum
  3. 不要开机立刻执行 ethtool 修改,延迟 60 到 120 秒执行

绕开大部分 e1000e TX Hang 场景。


Edit this page
Share this post on: