HOOOS

直通网卡和核显后,OpenWrt热重启导致整机断电死锁的底层原因与终极解决办法

0 6 Homelab老司机 OpenWrt虚拟机直通Proxmox VE
Apple

在玩软路由或 “All-in-One” 架构的 Homelab 圈子里,这是一个非常经典但又极度让人抓狂的「硬件级死锁」现象。

表现为:虚拟机(通常是 PVE 或 ESXi)正常运行,一旦你点击 OpenWrt 的「重启」或在后台执行 reboot(热重启/软重启),伴随着物理主机“咔哒”一声或者风扇瞬间停转,整机彻底断电。此时,按机箱上的电源键毫无反应,必须拔掉 220V 电源线,静置 10-30 秒让主板电容放电后,重新插电才能开机。

这绝不是简单的系统崩溃,而是硬件触发了主板 EC(嵌入式控制器)或电源的保护性锁定(Latch-up)。以下是其底层的致命原因以及一步步排查解决的方案。


一、 为什么会“整机断电”且“必须拔插电源”?

这涉及 PCIe 设备的复位机制(Reset Mechanism)与主板的电源管理架构(ACPI/EC)

1. 核心祸首:PCIe FLR(Function Level Reset)失败

当虚拟机热重启时,宿主机(Hypervisor,如 PVE)必须对直通给该虚拟机的物理硬件(核显、网卡)进行复位,以便它们恢复到初始化状态,供下一次开机使用。
复位标准通常是 FLR(功能级复位)。然而:

  • 部分 Intel 2.5G 网卡(如 i225-V/i226-V) 以及 Intel 核心显卡(UHD 600/630/Alder Lake / Elkhart Lake 等) 的 PCIe 控制器对 FLR 的支持存在硬件级缺陷。
  • 当 OpenWrt 重启,发出复位指令时,这些硬件无法正常响应复位,导致 PCIe 总线死锁(Bus Lockup)。

2. 触发 CPU 灾难性错误(CATERR)

PCIe 总线死锁后,CPU 无法完成对该硬件的读写事务,硬件事务超时。这会直接触发 CPU 的 CATERR(Catastrophic Error,灾难性错误)IERR(Internal Error)
CPU 处于保护机制,会瞬间向主板主控芯片发送紧急停机信号。

3. 主板 EC 挂起与电源锁定

当 CATERR 触发后,主板的 EC(Embedded Controller) 判定系统出现严重硬件故障,会立刻切断 ATX 电源的主供电(12V、5V、3.3V),系统瞬间断电。
但是,此时 5VSB(5V 待机电源) 依然在供电。由于 EC 芯片或主板南桥本身也因为刚才的 PCIe 事务死锁卡死在了异常状态(未完成复位循环),它不会响应面板电源键的开机信号。
只有拔掉物理电源线,彻底切断 5VSB,让主板芯片组和 EC 完全失去供电、寄存器数据清零(复位),重新插电后,主板才能重新初始化并允许开机。


二、 黄金排查法:谁是害群之马?

通常情况下,网卡核显同时直通时,核显是罪魁祸首的概率高达 80%,部分走 PCIe 协议的廉价网卡占 20%。我们需要做二分法排查:

  1. 测试一: 在 OpenWrt 虚拟机中,移除核显直通,仅保留物理网卡直通。执行 reboot 热重启,观察是否还会断电。
  2. 测试二: 如果测试一正常,恢复核显,移除网卡直通(临时改用虚拟网卡 VirtIO)。执行 reboot 热重启。

通过这两步,你能100%锁定到底是核显不支持重置,还是网卡的 PCIe Reset Bug 导致的。


三、 终极解决方案

根据排查结果,对症下药:

方案 A:解决核显直通引起的死锁(最常见)

1. 拷问自己:OpenWrt 真的需要直通物理核显吗?

在绝大多数 All-in-One 架构中,OpenWrt 只是个路由系统,完全不需要任何图形算力

  • 如果你直通核显是为了给 NAS(黑群晖、Unraid、TrueNAS)或 Jellyfin/Plex 媒体服务器做硬件解码,那么你应该把核显直通给那个专门的 NAS/Debian 虚拟机,而不是 OpenWrt。
  • 不要盲目把所有物理硬件一股脑塞给 OpenWrt。

2. 无法避开核显直通时(例如:单系统单用,或给特定 Docker 使用)

如果必须给它,需要在宿主机(以 PVE 为例)中屏蔽核显的硬件重置机制,或强制使用特定的重置模式:

  • 更改虚拟机配置文件(/etc/pve/qemu-server/<VMID>.conf)。
  • 找到直通核显的那一行(例如 hostpci0: 00:02.0,pcie=1...),在末尾尝试添加 x-vga=on,或者尝试通过 uuid 等参数将其隔离。
  • 对于 Intel 11/12/13 代等核显,可以使用 SR-IOV(虚拟化出多个 vGPU) 替代物理直通(PCIe Passthrough)。SR-IOV 允许宿主机和多个虚拟机共享核显,由宿主机驱动控制,可以完美规避虚拟机重启时物理 PCIe 级重置带来的断电死锁。

方案 B:解决物理网卡直通引起的死锁

如果你使用的是 Intel i225/i226 系列 2.5G 网卡,或者某些 Realtek 网卡,热重启断电通常是因为它们和主板主控的 PCIe 链路状态不兼容。

1. 开启主板 PCIe ACS 强制拆分

有些主板把网卡和主板上的其他关键设备(甚至是 CPU 供电控制、南桥通信)划分在同一个 IOMMU Group 里。直通并复位网卡时,导致整个 Group 内的系统设备跟着一起复位,引发崩盘。
在宿主机(PVE)中,编辑 /etc/default/grub

# 找到 GRUB_CMDLINE_LINUX_DEFAULT,在末尾添加 pcie_acs_override=downstream,multifunction
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction"

保存后执行 update-grub 并重启宿主机。这会强制把每个 PCIe 设备剥离到独立的 IOMMU 组中,防止复位信号波及无辜硬件。

2. 在 BIOS 中关闭 PCIe ASPM(活动状态电源管理)

ASPM 允许 PCIe 设备在空闲时进入低功耗状态(L1/L2)。当虚拟机热重启时,低功耗状态下的网卡在接收到复位信号时极易发生状态机混乱,进而锁死 PCIe 链路。

  • 进 BIOS,找到 PEG ASM / ASPMPCI Express Link Speed 等设置。
  • ASPM 设为 Disabled(禁用)。
  • 将对应的 PCIe 插槽协议从 Auto 或 Gen4 降级锁定为 Gen3Gen2(如果是网卡,Gen3 的带宽已经严重过剩,降低协议代际能极大增加信号冗余度与稳定性)。

3. 开启 BIOS 中的 Above 4G Decoding 与 SR-IOV 支持

确保 BIOS 里的 Above 4G Decoding(大于 4G 解码)和 Intel VT-d 是开启状态。这样可以给 PCIe 设备分配更宽裕的 MMIO(内存映射I/O)空间,防止在设备重置时发生地址空间重叠冲突。


方案 C:使用底层脚本拦截死锁(针对 PVE 用户的偏门绝招)

如果你用的是 PVE,且由于物理硬件天生缺陷无法解决 Reset 导致的卡死,可以安装 vendor-reset 补丁。
这是一个 Linux 内核模块,专门用来接管和修复那些在直通和复位时会挂起整机的硬件(最初为了解决 AMD GPU 的 reset bug,现在也支持部分其他设备)。

  1. 在 PVE 宿主机安装编译依赖。
  2. 克隆 https://github.com/gnif/vendor-reset 并编译安装。
  3. 在 PVE 启动时,利用 cronudev 规则,将直通网卡/核显的重置模式绑定到 vendor-reset

总结与避坑建议

面对这种「断电拔插头」的绝症,最稳妥的排查路径是:

  1. 停止核显直通给 OpenWrt。OpenWrt 只需要网络包转发,给它核显完全是得不偿失。
  2. 保持网卡直通,在 BIOS 中关闭 ASPM 并将 PCIe 槽强制指定为 Gen3/Gen2
  3. 在宿主机中开启 pcie_acs_override,彻底隔绝设备间的相互干扰。

点评评价

captcha
健康