Linux 内核 Compute Accelerators 子系统:加速卡如何以统一方式暴露给用户空间
Linux 内核的 compute accelerators(计算加速器)子系统为 AI/ML 推理与训练加速卡提供了一套统一的用户空间暴露方式与通用功能框架。本篇基于内核仓库中 Documentation/accel/ 文档目录的完整内容,结合 drivers/accel/ 与 include/drm/drm_accel.h 的源码实现,系统讲解该子系统的设备分类、与 DRM/DRM 体系的复用关系、字符设备与 major 号约定、以及编写一个 accel 驱动需要修改的两处关键点。读完后你可以掌握:理解 /dev/accel/accel* 设备节点的来龙去脉,知道如何在自己的驱动中接入 accel 框架,并了解当前内核中 amdxdna、qaic、rocket 三个在役加速卡驱动的文档位置。
子系统定位:统一暴露,不限定 ML
Documentation/accel/index.rst 是整个加速卡文档树的入口(一个 toctree 导航页),其下挂载四篇子文档:introduction.rst 总述,以及 amdxdna、qaic、rocket 三个具体驱动的文档索引。核心设计目标在 introduction.rst 中给出:
The Linux compute accelerators subsystem is designed to expose compute accelerators in a common way to user-space and provide a common set of functionality.
即:以一致的方式向用户空间暴露计算加速器,并提供一组通用功能。这些设备既可以是独立 ASIC,也可以是 SoC/GPU 内部的 IP 块。虽然这类设备通常用于加速机器学习(ML)与深度学习(DL)计算,但 accel 层并不局限于这一类加速器。
三类典型设备形态
introduction.rst 将计算加速器归为三个类别:
- Edge AI(边缘 AI):在边缘设备上做推理。可以是嵌入式 ASIC/FPGA,也可以是 SoC 内部 IP(例如笔记本网络摄像头中的视觉处理 IP)。这类设备通常通过寄存器配置,可以带或不带 DMA。
- Inference data-center(数据中心推理卡):大服务器中的单/多用户设备。可以是独立板卡,也可以是 SoC 或 GPU 内部 IP。它带有板载 DRAM(用于存放 DL 拓扑模型)、DMA 引擎、命令提交队列(内核态或用户态队列);可能带有 MMU 来管理多用户,也可能启用虚拟化(SR-IOV)以在同一设备上支持多个 VM。此类设备通常还配套 profiler、debugger 等工具。
- Training data-center(数据中心训练卡):与推理卡类似,但计算能力和内存带宽(如 HBM)更强,并且通常具备 scale-up/scale-out 机制——即与同一服务器内的其他训练卡互联,或与集群中其他服务器的训练卡互联。
文档同时指出:这些设备通常拥有各自定制的运行时用户空间软件栈,往往还包括针对其自研计算引擎的代码生成编译器;用户空间真正的公共层是 PyTorch、TensorFlow 这类 DL 框架。
复用 DRM:accel 核心是 DRM 的一部分
Sharing code with DRM 一节解释了 accel 子系统与 DRM 子系统的关系。由于这类设备可能是 GPU 内部 IP,且特性与 GPU 高度相似,accel 子系统直接复用 DRM 的代码与功能:
- accel 核心代码是 DRM 子系统的一部分,一个 accel 设备就是一种新的 DRM 设备类型;
- 这样可以复用庞大的 DRM 代码库,并与有此类设备经验的 DRM 开发者协作;
- 未来为加速器驱动新增的功能,GPU 驱动同样可以受益。
这一点在源码中得到印证:drivers/accel/drm_accel.c 直接依赖 <drm/drm_accel.h>、<drm/drm_drv.h> 等 DRM 头文件;其 Kconfig 入口(drivers/accel/Kconfig)也以 if DRM 为前提,帮助文本明确写着:
This framework is integrated with the DRM subsystem as compute accelerators and GPUs share a lot in common and can use almost the same infrastructure code.
与 GPU 的区隔:新的 major 号与设备文件
为了防止庞大的用户空间图形软件栈把加速器误当作 GPU 使用,accel 设备通过新的 major 号和新的设备字符文件与 GPU 区分开:
| 项 | 约定 |
|---|---|
| 驱动源码位置 | drivers/accel/(与 GPU 驱动分离) |
| major 号 | 261 |
| 设备字符文件 | /dev/accel/accel* |
| sysfs | /sys/class/accel/accel*/ |
| debugfs | /sys/kernel/debug/accel/*/ |
major 号 261 在 include/drm/drm_accel.h 中定义(ACCEL_MAJOR 261,另有 ACCEL_MAX_MINORS 256)。drivers/accel/drm_accel.c 中的实现与文档约定逐条对应:
- accel_devnode() 返回
"accel/%s",即 udev 按此在/dev/accel/下创建节点; - accel_class 注册了名为
accel的设备类,对应/sys/class/accel/; - accel_set_device_instance_params() 用
MKDEV(ACCEL_MAJOR, index)生成设备的dev_t,并将设备实例挂到 accel class 上; - accel_core_init() 依次注册 accel class 和
register_chrdev(ACCEL_MAJOR, "accel", &accel_stub_fops),stub fops 中的 accel_stub_open() 会在真正打开时替换为驱动自己的 fops 并转调其 open; - accel_debugfs_register() 为每个 accel minor 创建 debugfs 节点(含
name信息文件),对应文档中的 debugfs 约定。
此外,include/drm/drm_accel.h 还定义了 DRM_ACCEL_FOPS 与 DEFINE_DRM_ACCEL_FOPS(name) 宏:后者自动生成带有 owner = THIS_MODULE 的静态 struct file_operations,其中 open 指向 accel_open,read/mmap 等分别复用 drm_read、drm_gem_mmap 等 DRM 实现。文档注释特别提示该结构因引用 THIS_MODULE 不能在多个驱动间共享。
Getting Started:接入 accel 框架的完整步骤
introduction.rst 的 Getting Started 小节给出了驱动开发者接入 accel 的三步路径,这里逐条展开并给出源码佐证。
第一步:先读 DRM 文档
官方要求开发者先阅读 Documentation/gpu/index.rst。因为 accel 驱动本质上就是一个 DRM 驱动,撰写新 DRM 驱动的方法、贡献流程、行为准则与编码/文档风格对 accel 子系统完全适用。
第二步:开启 CONFIG_DRM_ACCEL
确认内核配置中打开了 CONFIG_DRM_ACCEL。在 drivers/accel/Kconfig 中它对应 menuconfig DRM_ACCEL("Compute Acceleration Framework"),并且它 depends on DRM——也就是说 accel 框架不可脱离 DRM 单独启用。该 Kconfig 随后 source 了六个驱动子目录的 Kconfig:
- drivers/accel/amdxdna/Kconfig
- drivers/accel/ethosu/Kconfig
- drivers/accel/habanalabs/Kconfig
- drivers/accel/ivpu/Kconfig
- drivers/accel/qaic/Kconfig
- drivers/accel/rocket/Kconfig
第三步:驱动的两处修改
要把一个设备暴露为加速器(相对标准 DRM 驱动),文档明确要求改两处:
- 在
drm_driver.driver_features中加入DRIVER_COMPUTE_ACCEL特性位。 源码中该位定义于 include/drm/drm_drv.h:DRIVER_COMPUTE_ACCEL = BIT(7)。文档特别强调:该特性与DRIVER_RENDER、DRIVER_MODESET互斥。若设备希望同时暴露图形和计算两种字符文件,应由两个驱动处理,并通过 auxiliary bus 框架连接二者。 - 把驱动 fops 结构中的 open 回调改为
accel_open()。 直接做法是手动指定.open = accel_open;更省事的推荐做法是使用 DEFINE_DRM_ACCEL_FOPS 宏,一次性生成正确的file_operations。accel_open()的实现见 drivers/accel/drm_accel.c#L117-L145:它通过 minor 号在accel_minors_xaxarray 中查找到对应drm_minor,递增dev->open_count,共享同一设备的anon_inode地址空间,最后调用drm_open_helper()完成逐文件资源实例化并触发驱动自己的 open 回调。
文档树中的三个在役加速器驱动
Documentation/accel/index.rst 的 toctree 还索引了三份驱动文档,它们展示了该框架当前落地的三类典型硬件:
amdxdna:AMD NPU 驱动
Documentation/accel/amdxdna/index.rst 说明 accel/amdxdna 驱动支持 AMD NPU(Neural Processing Unit),下挂 amdnpu.rst 详细介绍。对应源码位于 drivers/accel/amdxdna/,从文件结构可以看出它覆盖了文档中"数据中心推理/训练卡"的典型要素:PCI 探测(aie2_pci.c)、SR-IOV 支持(aie4_sriov.c)、mailbox 与上下文管理(amdxdna_mailbox.c、amdxdna_ctx.c)、GEM 内存对象(amdxdna_gem.c)以及 IOMMU 集成(amdxdna_iommu.c)。
qaic:Qualcomm Cloud AI 加速卡
Documentation/accel/qaic/index.rst 说明 accel/qaic 驱动支持 Qualcomm Cloud AI 机器学习加速卡,文档树含 qaic.rst(框架总述)、aic080.rst 与 aic100.rst(两款 AIC 卡片的细节)。源码 drivers/accel/qaic/ 除核心驱动 qaic_drv.c 外,还包含 MHI 控制器(mhi_controller.c)、Sahara 协议(sahara.c)、SSR(subsystem restart)处理(qaic_ssr.c)与 RAS 支持(qaic_ras.c),是一个功能完整的 PCIe 加速卡驱动。
rocket:Rockchip NPU(RK3588)
Documentation/accel/rocket/index.rst 介绍了 Rockchip NPU 驱动:
- 支持 RK3588 等 Rockchip SoC 内的 NPU,Rockchip 称其为 RKNN 或 RKNPU;
- 硬件描述参考 RK3588 TRM 第 36 章;
- 内核驱动的职责刻意保持最小化:只负责硬件上下电、缓冲区分配与映射、以及向前端单元提交 job,其余全部在用户空间完成——用户空间部分是一个 Gallium 驱动(同样叫 rocket),属于 Mesa3D 项目;
- 当前支持的硬件:RK3588。
对应源码 drivers/accel/rocket/ 结构精简而清晰:核心逻辑 rocket_core.c、设备管理 rocket_device.c、GEM 缓冲 rocket_gem.c、job 提交 rocket_job.c,与文档所述职责一一对应。
文档树全景与延伸阅读
Documentation/accel/ 目录的完整构成如下,可作为深入阅读的索引:
| 路径 | 内容 |
|---|---|
| Documentation/accel/index.rst | toctree 入口,汇总全部子文档 |
| Documentation/accel/introduction.rst | 子系统定位、设备分类、DRM 复用、major 号约定、驱动接入指南 |
| Documentation/accel/amdxdna/ | AMD NPU 驱动文档 |
| Documentation/accel/qaic/ | Qualcomm Cloud AI(AIC080/AIC100)驱动文档 |
| Documentation/accel/rocket/ | Rockchip RK3588 NPU 驱动文档 |
框架层的实现代码则集中在 drivers/accel/drm_accel.c(核心初始化、字符设备注册、open 路径、debugfs)与 include/drm/drm_accel.h(major 号、FOPS 宏、API 声明;当 CONFIG_DRM_ACCEL 未启用时,所有 API 退化为空的 static inline 桩函数,保证无 accel 设备的内核仍可编译)。
小结
从文档脉络到源码实现可以归纳出 accel 子系统的三条主线:
- 定位:以统一方式暴露 ML/DL 及其他计算加速器,覆盖从 SoC 内 IP 的 Edge AI 到带 HBM 与 scale-up 互连的训练卡三种形态;
- 架构:作为 DRM 的新设备类型复用 DRM 基础设施,但用 261 major 号、独立的
accelclass 与/dev/accel/accel*设备文件与 GPU 明确区隔,源码独立存放于 drivers/accel/; - 接入:驱动侧仅需
CONFIG_DRM_ACCEL+DRIVER_COMPUTE_ACCEL特性位 +accel_open()/DEFINE_DRM_ACCEL_FOPS三件套,即可获得统一的字符设备、内存管理与 debugfs 能力。
对驱动开发者而言,建议从 Documentation/gpu/index.rst 的 DRM 文档入手,再对照本文"接入框架的完整步骤"一章修改自己的驱动;对使用者而言,则可以直接在 /dev/accel/、/sys/class/accel/ 与 debugfs 的 accel 目录下观察自己系统中的加速器设备。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00