Tyr的未来:用于Arm Mali硬件的Rust GPU驱动
Source: Hacker News
Did you know…?
LWN.net 是一个靠订阅者支持的出版物;我们依赖订阅者来维持整个运营。请通过购买订阅来帮助我们,让 LWN 继续在网络上存在。
Tyr 背后的团队在 2025 年初几乎没有任何成果,目标是为 Arm Mali 硬件打造一个 Rust GPU 驱动。到年底时,我们已经能够在 Linux Plumbers Conference(LPC)上运行 SuperTuxKart(一款 3‑D 开源赛车游戏)。我们的原型是 Arm、Collabora 和 Google 合作的成果;它在整个会议期间运行良好,性能足以满足玩家需求。
值得庆幸的是,我们恰好在正确的时机获得了动力:Dave Airlie 刚刚在 Maintainers Summit 上宣布,DRM 子系统距离禁止使用 C 编写新驱动并强制使用 Rust 只剩“大约一年”。现在是时候为 2026 年制定可能的路线图,以便将所有工作上游(upstream)了。
我们想通过 Tyr 实现什么?
Miguel Ojeda 在今年的 LPC 演讲中概述了 Rust 在 Linux 内核中的使用情况,诸如 Android 的匿名共享内存子系统(ashmem)等驱动已经快速推向数百万用户。鉴于 Mali 在手机市场的庞大份额,支持这一细分市场是 Tyr 的自然目标,随后是 Mali 同样存在的其他嵌入式平台。
与此同时,我们不能忽视上游工作:目标是与 Nova Rust GPU 驱动同步演进,并确保生态系统对未来可能出现的任何新驱动都有用。原型的目的是证明一个针对 Arm Mali 的 Rust 驱动可以在可接受的性能下实现,但现在我们应该在代码上迭代并根据需要进行重构。这将让我们从错误中学习,并确定一个适合上游驱动的设计。
已有的内容与缺失的内容
- Tyr 驱动的一个版本已合并到 6.18 内核发布中,但功能有限,因为缺少一些关键的 Rust 抽象。
- 下游分支(Tyr 尚未进入主线内核的部分)保存了我们最新的原型;它已经足够好,可以运行桌面环境和游戏,尽管仍有功耗和 GPU 恢复问题需要修复。
- 该原型将用于指导我们的上游工作,并让我们尝试不同的设计方案。
像 Tyr 这样的内核模式 GPU 驱动是支撑更大用户模式驱动的一个小组件,后者实现 Vulkan 或 OpenGL 等图形 API。用户模式驱动将硬件无关的 API 调用转换为 GPU 特定的指令,以供光栅化过程使用。内核的职责集中在:
- 在应用之间共享硬件资源,
- 强制隔离和公平性,
- 保持硬件正常运行(提供 GPU 内存、在提交的工作完成时进行通知,并提供一种方式让用户空间描述作业之间的依赖链)。
我们在 LPC 2025 的演讲(YouTube 视频)中详细阐述了这些内容。

拥有可运行的原型并 不等于 已经可以在真实环境中使用。快速浏览缺失的部分即可了解原因。
- 电源管理 – Mali GPU 通常出现在移动设备上,电量十分宝贵。节能和热特性管理对用户体验至关重要,但 Tyr 目前没有电源管理或频率调节代码。支持这些功能的 Rust 抽象根本不存在。
- GPU 恢复 – 如果 GPU 卡死,系统必须在可能的范围内保持可用;否则用户可能会失去所有工作。我们的原型缺乏任何 GPU 恢复代码。这两项是可部署性的硬性要求:一个会耗尽电池或导致系统崩溃的驱动是不能发布的。
此外,Vulkan 必须能够在 Tyr 之上正确实现,否则我们可能无法实现与 Vulkan 驱动(PanVK)的即插即用兼容。这需要在使用 Tyr 代替 C 驱动时通过 Vulkan 合规性测试套件。完成后,我们就有信心在当前支持的 Mali‑G610 之外,添加对更多 GPU 型号的支持。
最后,我们将关注基准测试,以确保 Tyr 能够匹配 C 驱动的性能,同时受益于 Rust 的安全保证。我们已经展示了在可接受的性能下运行复杂游戏的案例,迄今为止结果良好。
哪些 Rust 抽象缺失?
一些必需的 Rust 基础设施仍在进行中:
- Graphics Execution Manager (GEM) shmem objects – Lyude Paul 对 GEM 共享内存对象的工作对于在没有独立显存的系统上分配内存是必需的。这在 Tyr 上尤为重要,因为 GPU 被封装在更大的系统级芯片中,需要共享系统内存。
- Lock‑free buffer region sharing – 仍有未解的问题:如何在不使用锁的情况下共享 GPU 缓冲区的非重叠区域,最好能够在类型系统中编码并在编译时检查。
- GPUVM support – 现代内核驱动必须让用户态驱动管理其自身的 GPU 地址空间视图。在 DRM 生态系统中,这一职责交由 GPUVM 处理,它包含在硬件支持的情况下管理这些地址空间的通用代码。
这些部分,加上前文提到的电源管理和恢复机制,构成了将 Tyr 推向 2026 年可投入生产、可上游的核心路线图。
# Rust GPU Driver Progress – Tyr
内存隔离与 GPUVM
- 现代 CPU 提供强大的内存隔离能力,GPU 固件也期望对某些内存段的放置拥有类似的控制。
- Alice Ryhl 正在进行以下工作:
- 用 Rust 实现的 GPUVM 抽象。
- 用于操作强制内存隔离的 IOMMU 页表的
io-pgtable抽象。
这些工作基于 Asahi Lina 早期的工作,她率先为 DRM 子系统创建了 Rust 抽象。
Source: …
未解决的 DRM 设备初始化问题
当前代码要求为驱动的私有数据提供一个初始化器,以返回一个 drm::Device 实例。
然而,一些驱动需要先拥有 drm::Device 才能构造其私有数据,这导致出现无法满足的循环依赖。
- Tyr 受此影响,因为:
- 通过 GEM shmem API 分配 GPU 内存需要
drm::Device。 - Tyr 的私有数据中的某些字段必须保存 GEM 对象(例如,用于解析和启动固件)。
- 通过 GEM shmem API 分配 GPU 内存需要
Paul Lyude 正在通过引入 drm::DeviceCtx 来解决此问题,该类型在类型系统中编码设备状态。
状态: 大部分路线图仍因 GEM shmem、GPUVM、io‑pgtable 以及设备初始化问题而受阻。
同时还有机会整合 Nova 团队的工作:
一旦这些组件就位,我们预计能够快速启动 GPU 固件,并在作业提交讨论开始之前继续前进,不再遇到进一步的阻碍。
栅栏处理与同步
- 完成 栅栏 的路径必须仔细标注;否则系统可能死锁。
- 在信号路径中只能获取安全的锁。
- DMA 栅栏必须始终在有限时间内发信号;否则系统的其他部分可能永远阻塞。
- 这些路径中的内存分配必须使用
GFP_ATOMIC。使用其他标志进行分配可能导致在内存压力下运行收缩器,从而可能等待触发它的同一作业。
所有这些内容都在内核文档中有所说明:
Current prototype: 忽略这些约束,因此在内存压力下可能随机死锁。
Fix: 系统性地审查驱动的关键部分。优雅地实现此目标——可能利用 Rust 的类型系统——仍是一个待讨论的问题。
展望未来
重新思考作业提交逻辑
现有设计假设使用 drm_gpu_scheduler,但它已经成为阻碍:
- 一些驱动现在依赖 GPU 固件来调度作业。
drm_gpu_scheduler存在难以解决的生命周期问题。
在 X.Org 开发者大会 2025 上,我们讨论了替代方案。针对 Rust 的新共识是创建一个新组件,能够:
- 在作业能够放入 GPU 环形缓冲区之前,确保作业依赖已满足。
- 一旦作业准备就绪,将调度交给固件。
由于该组件 不自行调度作业,它可能会被称为 JobQueue。这个名称传达了一个队列的概念:工作被放入其中,待依赖满足后再移除。
- Philip Stanner 正在牵头
JobQueue工作。
C 驱动互操作性
计划为 C 驱动公开一个 API,使用前文文章中描述的技术。这可能成为 第一个可供 C 驱动使用的 Rust 内核组件,标志着 Rust 在内核中的里程碑,并展示了无缝的 C–Rust 互操作性。
Tyr 作为试验平台
Tyr 可以作为新设计的试验平台:
- 如果我们能够在原型中用
JobQueue替换旧的drm_gpu_scheduler,就能验证该方法对更复杂驱动(如 Nova)的适用性。 - 预计此话题的讨论将继续。
摘要
- 进展: 在 GPUVM 的 Rust 抽象、IOMMU 页表以及设备状态编码方面取得了显著进展。
- 阻碍因素: GEM 共享内存、GPUVM、io‑pgtable,以及 DRM 设备初始化周期。
- 后续步骤: 集成 Nova 宏,解决 fence 处理,开发
JobQueue,并公开 C‑driver API。 - 展望: Tyr 在过去一年取得了实质性进展,已准备好在 2026 年及以后继续推进。