关注了就能看到更多这么棒的文章哦~

A Nouveau graphics driver update

By Jonathan Corbet
December 1, 2023
LPC
ChatGPT translation
https://lwn.net/Articles/953144/

迄今为止,对 NVIDIA 图形处理器的支持一直是 Linux 用户的一个痛点;NVIDIA 一直没有感觉到有必要与内核社区合作,也不觉得有必要提供自由软件版本的驱动程序,而逆向工程形成的 Nouveau 驱动程序通常难以跟上该公司产品发布的步伐。然而,近年来已经出现了一些改善的迹象。在2023年Linux Plumbers大会上,图形子系统维护人员 Dave Airlie 对 NVIDIA GPU 的支持状态进行了更新,并介绍了尚需完成的工作。

多年来,内核社区与 NVIDIA 的关系“时好时坏”,Airlie 开始说。然而,最近公司重新设计了其产品,增加了一个大型的 RISC-V 处理器(GPU 系统处理器,简称为 GSP),并将许多以前由驱动程序处理的功能移入了 GSP 固件。该公司允许将该固件用在 Linux 里,并由 Linux 发行版发布。这种安排带来了许多好处,比如说现在内核可以对 NVIDIA GPU 重新设置时钟频率,使它们采用跟专有驱动程序相同的速度运行。他说,这比起以前仅由 Nouveau 提供的固件来说是一个重大改进。

da4b68574dd0e63c676d2b658ea3363b.png

当然,也有一些缺点。该固件没有提供稳定不变的 ABI,它提供的许多调用都没有文档。固件文件本身很大,在 20-30MB 之间,并且任一个设备都需要两个固件文件。这显著地增大了系统的 /boot 目录和 initramfs 镜像(因为它必须包含内核可能会需要的所有固件版本),并迫使 Nouveau 开发人员在采用固件更新时要非常谨慎和小心。

Nouveau 的工作在长期开发者 Ben Skeggs 离开项目后面临了一些挫折,但他在离开之前成功进行了许多重构工作。Nouveau 现在针对一个版本的固件已经有了初步的 GSP 支持;该代码已经合并到 6.7-rc1 版本中。默认情况下,它仅启用对Ada系列 GPU 的支持;通过特定的命令行参数,它还可以配合Turing和Ampere设备工作。它也缺少一些功能,比如说错误处理(这应该不难添加)和传感器监控,后者现在完全无法工作。

Airlie 说,NVIDIA 的固件附带了一组 include 文件,这些文件中定义的结构会随时改变。为了处理这些改动,驱动程序将需要某种自动化的 ABI 生成能力;他指出,Apple M1 GPU 驱动程序的开发人员也遇到了同样的问题。他的建议是,如果像 M1 驱动程序一样,用 Rust 重新实现驱动程序之后,这个问题可能会变得更容易解决。

下一步

然而,支持 GSP 固件只是个开始;Airlie 又回头开始讲一般情况下如何制作一个可用的 GPU 驱动程序。多年前,显卡配备了一些视频 RAM和图形地址重映射表(GTT, graphics translation table)。驱动程序会将系统内存映射到显卡中;然后用户空间可以提交缓冲区句柄,该句柄将被重新定位到图形设备。他说,这种方法是可行的,但很慢。

当前的 GPU 具有完整的虚拟内存,这样可以节省很多开销。内核已经增加了许多用于处理这种虚拟内存的子系统,包括图形执行管理器(GEM, graphics execution manager)用于缓冲对象管理,翻译表管理器(TTM, translation taboe manager)用于不连续的视频 RAM 缓冲对象(buffer-object)管理,也包含大量的同步和 fencing 代码。最初,DRM 子系统将缓冲区的分配与虚拟内存的分配在同时进行;这样做很容易,足够实现 OpenGL。但是,他说,图形世界已经发展到不满足于这一点的状态了。

具体来说,Vulkan出现了。它引入了稀疏内存(sparse memory)的概念,以及由用户空间管理的虚拟内存。Vulkan 可以处理同步和异步方式对虚拟区域进行更新,但是会“变得复杂”。各种驱动程序开始发明自己的虚拟区域管理方式;为了将这项工作重新整合,VM_BIND API 应运而生。

Airlie 说,这与一个反复出现的模式很像。DRM 开发人员努力在图形驱动程序之间共享公共代码,但驱动程序开发人员不断尝试重新发明轮子,这是一种必须抵制的倾向。他说,这方面的工作在 mode setting 方面做得很好,但在加速方面做得不太好;例如,有一个“通用 GPU 调度程序”其实仅仅是在一个驱动程序里使用。同样,有很多驱动程序通过执行自己的虚拟区域管理来实现 VM_BIND。

作为回应,Airlie 提出了一个“好主意”,让人编写一个通用的虚拟区域管理器,名为 GPUVM,灵感来自 amdgpu 代码。这个管理器希望能对所有驱动程序都有用;现在 Nouveau、Xe(Intel 的新驱动程序)和 Panfrost 驱动程序都在使用它。希望 amdgpu 和 MSM 驱动程序也会采用它。最好的一点是,有很多位开发人员了解它的话就有助于阻止它走错方向。GPUVM 经历了很多迭代,他说,提供了“许多学习经验”。

他以 fence signaling 为例。一个 fence 表示一系列 GPU 操作已经完成;在等待这些 fence 的时候必须有时间限制,否则内存管理子系统可能会死锁。简而言之,如果给予机会的话,GPU 可以轻松地把系统中所有 RAM 都锁定(pin down)。当内存紧张时,可以调用一个 shrinker 动作,但必须等待 fence 事件发生,以便知道何时可以释放内存。如果在此过程中设置 fence 的代码决定分配更多内存,就会导致死锁。为了避免这种结果,开发人员必须严格限制可以在 fence signaling 的临界区所能执行的操作;在获取任何锁之前也必须小心。在此代码中更新页表会很有用,但是这会导致死锁问题,必须被撤销。

回到 Nouveau,Airlie 表示,使用 GPUVM 的初始 VM_BIND API、同步对象(synchronous objects)和与调度程序集成这些动作都已经在 6.6 版本中合并。目前正在进行很多改进,预计将在 6.8 版本中完成。他说,此时我们已经拥有了用于 NVIDIA 硬件的现代 GPU 驱动程序的核心部分,至少针对图形场景来说是这样的。在 Nouveau 能够支持计算应用程序(compute application)之前还有更多工作需要进行。

在用户空间方面,Faith Ekstrand 一直在为 Nouveau 开发 NVK Vulkan 驱动程序;该驱动程序最近达到了Vulkan 1.0的标准。这项工作涉及创建一个名为 NAK 的新编译器,该编译器刚刚合并到了 Mesa 中;与旧的“codegen”编译器相比,这个编译器性能要好得多(从每秒 20 帧提高到 1000 多帧)。当然,这个编译器是用 Rust 编写的。Airlie 总结说,下一步就是继续迈向 Vulkan 1.3。

视频 和 演讲幻灯片 可在此处找到。

[感谢 Linux Foundation,LWN 的旅行赞助商,支持我们参加此次活动。]

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐