bhyve PCI Passthrough pptdevs 经验教训

问题

这个问题困扰了我一段时间:

最初我以为我的 纳斯NASSE C246 ITX主板 BIOS存在bug,因为当时我恰好调整了一下BIOS的配置并重启了主机,然后看到FreeBSD的之前配置的 bhyve快速起步 的网桥(桥接了4个物理 igc 网卡以及3个 tap 虚拟网卡) 突然混乱不生效了:

/etc/rc.conf 中配置网桥桥接物理网卡和虚拟网卡
# 创建网桥以及用于虚拟机的tap虚拟网络设备
cloned_interfaces="bridge0 tap0 tap1 tap2"
# 重命名网桥
ifconfig_bridge0_name="igc0bridge"
# 将物理网卡(4个igcX)和虚拟网卡(tapX)连接到网桥上
ifconfig_igc0bridge="inet 192.168.7.201/24 addm igc0 addm igc1 addm igc2 addm igc3 addm tap0 addm tap1 addm tap2 up"
# 设置默认网关
defaultrouter="192.168.7.101"
# 激活物理网卡
ifconfig_igc0="up"
ifconfig_igc1="up"
ifconfig_igc2="up"
ifconfig_igc3="up"

表现为:

  • 系统启动后只识别出 igc0igc1 ,另外两个 igc2igc3 不翼而飞

  • 虚拟交换机 igc0bridge 没有分配IP地址

这样导致每次启动FreeBSD服务器都要我使用键盘和屏幕来手工配置IP地址连接网络,非常不方便

排查

我最初以为是BIOS的bug(主板硬件不稳定)导致主机重启以后无法识别物理网卡,这也是因为当时我正好修改BIOS凑巧出现了遇到了这个异常。而且,我在折腾BIOS的配置,偶然发现又正常识别出4个 igc 网卡(恢复正常),就轻率判断为硬件问题。

然而,这次在配置 FreeBSD 15环境bhyve中实现NVIDIA GPU passthrough 再次突然发生这样的情况,使得我非常抓狂,正好在测试PCI passthru时多次调整BIOS,然而我却不知道什么触发了问题。

我甚至想到是不是FreeBSD的网卡驱动是否有配置加载模块时需要传递参数?那么Linux是否正常呢?

通过Ubuntu启动安装U盘看到,Linux是识别出4个网卡的,这说明FreeBSD存在问题,BIOS是正常的。

  • 再次启动到FreeBSD系统,我尝试 pciconf -lv 检查PCI设备,突然发现原来系统是识别出了4个PCI以太网设备的:

执行 pciconf -lv 可以看到4个网卡设备,why?
...
igc0@pci0:2:0:0:	class=0x020000 rev=0x04 hdr=0x00 vendor=0x8086 device=0x125c subvendor=0x8086 subdevice=0x0000
    vendor     = 'Intel Corporation'
    device     = 'Ethernet Controller I226-V'
    class      = network
    subclass   = ethernet
igc1@pci0:3:0:0:	class=0x020000 rev=0x04 hdr=0x00 vendor=0x8086 device=0x125c subvendor=0x8086 subdevice=0x0000
    vendor     = 'Intel Corporation'
    device     = 'Ethernet Controller I226-V'
    class      = network
    subclass   = ethernet
igc2@pci0:4:0:0:	class=0x020000 rev=0x04 hdr=0x00 vendor=0x8086 device=0x125c subvendor=0x8086 subdevice=0x0000
    vendor     = 'Intel Corporation'
    device     = 'Ethernet Controller I226-V'
    class      = network
    subclass   = ethernet
igc3@pci0:5:0:0:	class=0x020000 rev=0x04 hdr=0x00 vendor=0x8086 device=0x125c subvendor=0x8086 subdevice=0x0000
    vendor     = 'Intel Corporation'
    device     = 'Ethernet Controller I226-V'
    class      = network
    subclass   = ethernet
...

那为何 ifconfig 只看到 igc0igc1 ?

我突然意识到问题了,是我在 bhyve PCI Passthrough快速起步 以及 在bhyve中实现NVIDIA GPU passthrough 等实践中,多次尝试PCI Passthru GPU设备,所以多次修改 /boot/loader.conf 来从Host上屏蔽掉某些需要Passthru给虚拟机的GPU设备,例如:

配置 /boot/loader.conf 屏蔽掉Host主机上的GPU设备
pptdevs="1/0/0 2/0/0 3/0/0"

而此时启动的主机中 2/0/03/0/0 对应的不是GPU设备(我拆卸掉了GPU卡),而是主板上集成的以太网设备

原因分析

然而,当我拆掉了主机上安装的GPU设备,重启系统后,原先对应GPU的ID 2/0/03/0/0 现在被自动对应到主板的2个以太网设备上,这导致了两个以太网卡被自动从Host上屏蔽无法访问。

警告

当Host主机上的PCIe设备更改时,原先系统识别的PCIe IDs会动态变化,这会导致 /boot/loader.conf 原先配置的 pptdevs 误屏蔽掉错误的设备!!!

我甚至可能误屏蔽了一块nvme存储(捂脸) 导致 ZFS Stripe条带化 (FreeBSD环境实践) 无法使用,当时没有想到这个可能还折腾好久重建了ZFS,悲剧啊悲剧