Resizeable BAR支持在树莓派上的实现
虽然并非Linux现代显卡支持的绝对必要条件,但Resizable BAR支持通过允许GPU在PCIe总线上以大于256MB的数据块传输数据,从而提升GPU性能。
一月,我在树莓派Linux仓库中提交了一个议题:在Pi 5上支持Resizable BAR。
与大多数带有BIOS或UEFI支持的PC不同,树莓派默认应该支持BAR调整大小。然而,在树莓派OS上测试Intel Xe GPU驱动程序(适用于Alchemist/Battlemage GPU)时,我会遇到如下错误:
1
2
3
4
5
|
# 在Arc A750上
[ 10.099135] xe 0000:03:00.0: [drm] Failed to resize BAR2 to 8192M (-ENOSPC). Consider enabling 'Resizable BAR' support in your BIOS
# 在Arc B580上
[ 4.795416] xe 0001:03:00.0: [drm] Failed to resize BAR2 to 16384M (-ENOSPC). Consider enabling 'Resizable BAR' support in your BIOS
|
经过一些固件更新后,Pi OS能够正确构建PCIe总线,但Intel驱动程序仍然无法干净地调整BAR大小。
通过Pi OS开发者(特别感谢P33M和6by9)和更广泛的Pi社区之间的广泛调试,我们发现了一种让可调整大小的BAR与Xe驱动程序配合使用的方法:
如何启用Resizable BAR
嗯,我应该说"某种程度上"——因为目前,你必须选择一个BAR大小来调整,并为Xe驱动程序配置该大小。
首先,作为参考,这里是我们稍后将使用的resource2_resize选项的位值与BAR大小的映射表:
| 位 / 大小 |
位 / 大小 |
位 / 大小 |
| 1 = 2MB |
6 = 64MB |
11 = 2GB |
| 2 = 4MB |
7 = 128MB |
12 = 4GB |
| 3 = 8MB |
8 = 256MB |
13 = 8GB |
| 4 = 16MB |
9 = 512MB |
14 = 16GB |
| 5 = 32MB |
10 = 1GB |
15 = 32GB |
我选择了8GB BAR1,因为这是A750在错误消息中要求的(Failed to resize BAR2 to 8192M)。
要让调整大小工作(假设你已经安装了Xe驱动程序,目前这需要在Pi上自定义内核构建):
- 将Xe驱动程序加入黑名单,以便在BAR调整大小之前不会加载:编辑
/etc/modprobe.d/raspi-blacklist.conf并添加blacklist xe
- 编辑
/boot/firmware/cmdline.txt,并在参数中添加xe.vram_bar_size=8192
- 重启Pi
- 执行手动BAR调整大小:
1
2
3
4
|
# echo 0001:02:02.0 > /sys/bus/pci/drivers/pcieport/unbind
# echo 0001:02:01.0 > /sys/bus/pci/drivers/pcieport/unbind
# echo 0001:01:00.0 > /sys/bus/pci/drivers/pcieport/unbind
# echo 13 > /sys/bus/pci/devices/0001\:00\:00.0/0001\:01\:00.0/0001\:02\:01.0/0001\:03\:00.0/resource2_resize
|
- 探测Xe:
sudo modprobe xe(在另一个窗口中使用dmesg --follow监控dmesg)
注意,对于A750,上面第一个命令中的功能号是02:04.0,但对于B580是02:02.0。你可以使用lspci查看为"Intel Corporation Device"列出的PCI桥设备。
为了让这工作,你还需要上游Linux补丁"在调整大小时释放未使用的桥资源",这在6by9的"在Pi 5上测试PCIe显卡"拉取请求中有所考虑,我现在正在自己的Pi上测试。
完成所有这些并探测xe后,它似乎对内存布局很满意,不再抱怨"小BAR设备"(Pi的默认BAR大小是256MB):
1
2
3
4
5
6
7
8
9
10
11
12
|
[ 375.318614] xe 0001:03:00.0: enabling device (0000 -> 0002)
[ 375.318793] xe 0001:03:00.0: [drm] unbounded parent pci bridge, device won't support any PM support.
[ 375.318935] xe 0001:03:00.0: [drm] Found dg2/g10 (device ID 56a1) discrete display version 13.00 stepping C0
[ 375.320059] xe 0001:03:00.0: [drm] VISIBLE VRAM: 0x0000001800000000, 0x0000000200000000
[ 375.320237] xe 0001:03:00.0: [drm] VRAM[0, 0]: Actual physical size 0x0000000200000000, usable size exclude stolen 0x00000001fc000000, CPU accessible size 0x00000001fc000000
[ 375.320241] xe 0001:03:00.0: [drm] VRAM[0, 0]: DPA range: [0x0000000000000000-200000000], io range: [0x0000001800000000-19fc000000]
[ 375.320245] xe 0001:03:00.0: [drm] Total VRAM: 0x0000001800000000, 0x0000000200000000
[ 375.320248] xe 0001:03:00.0: [drm] Available VRAM: 0x0000001800000000, 0x00000001fc000000
[ 375.334678] xe 0001:03:00.0: vgaarb: VGA decodes changed: olddecodes=io+mem,decodes=none:owns=none
[ 375.338149] xe 0001:03:00.0: [drm] Finished loading DMC firmware i915/dg2_dmc_ver2_08.bin (v2.8)
[ 375.343724] xe 0001:03:00.0: [drm] GT0: Using GuC firmware from i915/dg2_guc_70.bin version 70.49.4
...
|
更多详细信息和日志请参见此评论。
自动化调整大小
每次启动时都必须输入所有这些命令相当烦人。因此,用户RSC-Games发布了一个systemd单元来自动执行此操作。
在/usr/bin/bar_resize.sh中创建一个脚本:
1
2
3
4
5
6
7
8
|
#!/usr/bin/env bash
# 注意:这个脚本可以更自动化一些,检测正确的卡或者如果没有识别到卡就退出
# 我把这留给复制粘贴它的人作为练习 ;)
echo 0001:02:02.0 > /sys/bus/pci/drivers/pcieport/unbind
echo 0001:02:01.0 > /sys/bus/pci/drivers/pcieport/unbind
echo 0001:01:00.0 > /sys/bus/pci/drivers/pcieport/unbind
echo 13 > /sys/bus/pci/devices/0001\:00\:00.0/0001\:01\:00.0/0001\:02\:01.0/0001\:03\:00.0/resource2_resize
modprobe xe
|
(注意:为A750设置02:04.0,或为B580设置02:02.0,并根据你的目标BAR调整大小更改13。)
确保该脚本可执行(sudo chmod +x /usr/bin/bar_resize.sh),然后在/etc/systemd/system/resize-bar.service中创建一个systemd单元文件:
1
2
3
4
5
6
7
8
9
|
[Unit]
Description=Resize the BAR allocation and manually load the Xe driver.
[Service]
Type=oneshot
ExecStart=/usr/bin/bar_resize.sh
[Install]
WantedBy=basic.target
|
然后启用该单元:
1
|
sudo systemctl enable resize-bar.service
|
你仍然需要手动添加/boot/firmware/cmdline.txt更改(xe.vram_bar_size=8192),并确保blacklist xe在/etc/modprobe.d/raspi-blacklist.conf文件中。
注意:如果你要换出AMD卡或暂时不使用Intel卡,请务必撤销这些更改,并禁用该服务(sudo systemctl disable resize-bar.service)。
结论
我们正在接近在Pi上完全支持Intel eGPU——AMD eGPU自去年年底以来一直稳定,在yanghaku提交了一个更简单的补丁后更是如此,该补丁很有希望被合并到Pi OS的linux内核中!请参见我最新的eGPU测试结果。
我还在我的16GB型号Pi 500+上使用B580测试了16GB BAR,但当我尝试时收到了错误echo: write error: No space left on device。我假设BAR大小可以大于设备上的RAM,但也许这个假设是错误的?这也让我研究为什么只有12GB VRAM的卡会请求16GB BAR,据我所知,这与像SR-IOV这样的潜在用途有关,其中多个VM可以访问单个设备,因此需要更多的BAR空间来共享物理设备……BAR对我来说仍然有点神秘。↩︎