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"
表现为:
- 系统启动后只识别出 - igc0和- igc1,另外两个- igc2和- igc3不翼而飞
- 虚拟交换机 - 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 只看到 igc0 和 igc1 ?
我突然意识到问题了,是我在 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/0 和 3/0/0 对应的不是GPU设备(我拆卸掉了GPU卡),而是主板上集成的以太网设备
原因分析
- 当我在 纳斯NASSE C246 ITX主板 BIOS 中配置 PCIe bifurcation ,拆分一条PCIe x16 为 - x8x4x4之后,安装的 Nvidia Tesla P4 GPU运算卡 或 Nvidia Tesla P10 GPU运算卡 ID显示为- 1/0/0
- 当我将BIOS恢复为出厂默认配置(也就是关闭 PCIe bifurcation ),此时安装的 Nvidia Tesla P4 GPU运算卡 和 Nvidia Tesla P10 GPU运算卡 的ID会是识别成 - 2/0/0或- 3/0/0
- 为了简化配置,我同时将 - 1/0/0 2/0/0 3/0/0从HOST主机屏蔽掉(见上文- /boot/loader.conf配置)
然而,当我拆掉了主机上安装的GPU设备,重启系统后,原先对应GPU的ID 2/0/0 和 3/0/0 现在被自动对应到主板的2个以太网设备上,这导致了两个以太网卡被自动从Host上屏蔽无法访问。
警告
当Host主机上的PCIe设备更改时,原先系统识别的PCIe IDs会动态变化,这会导致 /boot/loader.conf 原先配置的 pptdevs 误屏蔽掉错误的设备!!!
我甚至可能误屏蔽了一块nvme存储(捂脸) 导致 ZFS Stripe条带化 (FreeBSD环境实践) 无法使用,当时没有想到这个可能还折腾好久重建了ZFS,悲剧啊悲剧