开发者生态
morning
在 Linux 上的 PCIe 交换机后面安装四个 32 GB 可调整大小的条
摘要
My PCIe switch is a Broadcom PEX88096 in the board’s one x16 slot, with four AMD Radeon AI PRO R9700s and the two RTX 3090s from my PCIe splitter post behind it, and the build post has the whole box. ...
the
BAR
and
card
switch
Linux
Resizable
BIOS
board
post
2026-11-13
1 阅读
约7分钟阅读
dougcalobrisi
字号:
我的 PCIe 交换机是主板的一个 x16 插槽中的 Broadcom PEX88096,其后面有四个 AMD Radeon AI PRO R9700 和来自 PCIe 分线柱的两个 RTX 3090,构建柱有整个盒子。该交换机为每张卡提供八个通道,并让卡无需经过 CPU 即可相互复制。 AMD 的 ROCm 称之为点对点 (P2P),只有在映射每张卡的整个 32 GB 时才会打开它。在 Linux 上,这意味着每张卡上都有 32 GB 可调整大小的 BAR。基地址寄存器(BAR)将 CPU 地址空间的范围映射到设备的内存上。可调整大小的 BAR 是 BIOS 选项,可让卡的 BAR 为完整的 32 GB,而不是默认的 256 MB。在构建帖子后,有几个人要求提供该模块,因此它在 GitHub 上的名称为 gpu-rebar-layout 。它依赖于在任何版本中都可能发生变化的内核内部结构,因此在加载之前请阅读自述文件。邮件列表上的补丁系列修复了大小错误,但该板仍然需要在模块落地后调整大小并重新扫描,并关闭其填充( pad=0 )。为什么 BIOS 无法映射 6 个 32 GB BAR 🔗 添加 3090 后,主板停在其 POST LED 上的白色 VGA 灯处,因为每个 32 GB BAR 占用了 BIOS 的 64 GB 地址空间。地址空间帖子有数学计算。 Linux 7.0的桥接窗口大小调整bug:无法分配;没有空间 🔗 该主板的 BIOS 没有每卡可调整大小的 BAR 设置。 Linux 可以为某些卡提供较大的 BAR,而将其他卡保留为较小的 BAR,只要它在加载任何 GPU 驱动程序之前执行即可。当所有六张卡都已插入且可调整大小的 BAR 关闭时,我希望 Linux 来进行分配。计划是将每个 R9700 的 BAR 大小寄存器设置为 32 GB,删除交换机挂起的 CPU 端口,然后重新扫描,以便内核根据新大小再次布置整个交换机。每个 R9700 的 32 GB BAR 后面都有一个门铃 BAR,用于驱动程序写入的寄存器,以告诉卡有新工作。当可调整大小的 BAR 启用时,BIOS 将其设置为 256 MB。 Linux 将其保留为 2 MB。内核为交换机提供了大约 128.6 GB 的窗口。按照 Linux 7.0 的布局方式,门铃放置在每个 BAR 之后,四个窗口跨度为 224 GB(三个 64 GB 插槽加上最后一张卡的 32 GB 及其门铃)。两台 R9700 获得了 BAR,而交换机的其余部分则没有获得任何结果。 pci 0000:1b:00.0: 桥接窗口 [mem size 0x800200000 64bit pref]: 无法分配;没有空间 那是在 7.0.6 上。未打补丁的 v7.4-rc1 内核将四个中的三个置于 Linux 内核补丁测试帖子(即将发布)所涵盖的控制运行中。 0x800200000 是 32 GB 加 2 MB,一张卡的窗口。内核将交换机窗口的大小设置为其子窗口的简单总和:其中四个子窗口加上两个 3090 的 288 MB 窗口。该函数是 drivers/pci/setup-bus.c 中的 pbus_size_mem() 。对于桥的每个子项,它都会将子项的大小或对齐方式(如果较大)添加到总数中。 r_size = 资源大小(r);大小 += 最大值 (r_size, 对齐);当每个孩子的大小都是其对齐方式的倍数时,就不会留下间隙,这对于普通 BAR 来说是正确的,因为它们是 2 的幂。这里 GPU 的窗口为 32 GB 加上 2 MB(按 32 GB 对齐),因此总和忽略了一张卡的门铃与下一张卡的启动之间近 32 GB 的间隙。这是一个已知的回归。 Nikolas Britton 在 9 月份在 linux-pci 上报告了这个问题,该帖子的标题几乎逐字逐句地描述了我的问题。维护此代码的 Ilpo Järvinen 在 14 个补丁系列的资源放置修复中进行了修复,截至 11 月 6 日为 v5,但尚未合并。我测试了它并将 Tested-by 发送到 linux-pci 邮件列表。有了它,所有四台 R9700 都可以获得 32 GB。即使进行了修复,该板仍然需要在 GPU 驱动程序加载之前设置 BAR 大小并重新扫描,因为 amdgpu 在加载时调整大小无法增大其他卡已位于其中的窗口。填充 BAR 的内核模块 🔗 内核已经知道如何在不更改其大小的情况下提高 BAR 的对齐方式,但在 pci=resource_alignment= 启动选项中命名设备时会使用调整大小模式。在 R9700 上要求 32 GB 对齐也会增加其小 BAR,包括 512 KB 寄存器 BAR,它无法对齐到低于 4 GB 的 32 GB。解决方法是在加载任何 GPU 驱动程序之前从 initramfs 运行一个树外模块,initramfs 是内核启动的小型早期启动文件系统。对于每个匹配的卡,它设置 BAR 大小寄存器,然后删除交换机上方的根端口并重新扫描。在扫描和地址分配之间,它会遍历交换机下的每个总线段。它将每个较小的 64 位可预取 BAR 的对齐提高到该段上最大 64 位可预取 BAR 的大小,并对作为单独组的其他内存 BAR 执行相同的操作。每个 R9700 窗口恰好变为 64 GB,每个 3090 窗口正好变为 512 MB。一旦每个窗口都是其对齐的倍数,内核的分配器就会完成剩下的工作。重新启动后,R9700s 的内存为 160、224、288 和 352 GB,3090s 略高于它们,并且 amdgpu 报告了整个卡。
这篇文章对您有帮助吗?
订阅66必读
每日精选科技资讯,直达你的邮箱