拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Linux 内核 Compute Accelerators 子系统:DRM_ACCEL 框架的设计、配置与驱动接入

Linux 内核 Compute Accelerators 子系统DRM_ACCEL 框架的设计、配置与驱动接入【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux本文基于内核仓库中的 Compute Accelerators 子系统介绍文档系统讲解 Linux 计算加速器Compute Accelerators子系统的定位、设备分类、与 DRM 子系统的复用关系以及驱动开发者接入该框架的完整步骤从CONFIG_DRM_ACCEL配置到DRIVER_COMPUTE_ACCEL特性标志、accel_open()与DEFINE_DRM_ACCEL_FOPS宏的使用再到 major 号 261、/dev/accel/*设备节点等用户空间暴露约定的源码级实现。读完后你将能够判断一款加速卡是否适合接入该框架并知道在驱动中做哪两处改动即可把设备暴露为标准 accel 设备。1. 子系统定位以统一方式向用户空间暴露计算加速器Linux 计算加速器子系统compute accelerators subsystem的设计目标是以统一的方式向用户空间暴露计算加速器并提供一组通用的基础功能引自 introduction.rst。覆盖的设备形态包括两类独立的 ASIC 芯片stand-alone ASICs集成在 SoC 或 GPU 内部的 IP 块。这些设备通常被设计用来加速机器学习ML和深度学习DL计算但accel 层并不局限于这一类加速器——它是一个更通用的“计算加速设备”框架。1.1 文档给出的三类典型设备原文档将计算加速器归纳为三类接入驱动设计时可直接作为硬件能力评估的参照类别部署形态关键硬件特征Edge AI边缘 AI边缘设备上的推理如嵌入式 ASIC/FPGA或 SoC 内部 IP例如笔记本摄像头通常通过寄存器配置可带 DMA 也可不带 DMAInference>if DRM menuconfig DRM_ACCEL bool Compute Acceleration Framework help Framework for device drivers of compute acceleration devices, such as, but not limited to, Machine-Learning and Deep-Learning acceleration devices. ... 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. Having said that, acceleration devices will have a different major number than GPUs, and will be exposed to user-space using different device files, called accel/accel* (in /dev, sysfs and debugfs). source drivers/accel/amdxdna/Kconfig source drivers/accel/ethosu/Kconfig source drivers/accel/habanalabs/Kconfig source drivers/accel/ivpu/Kconfig source drivers/accel/qaic/Kconfig source drivers/accel/rocket/Kconfig endif要点该选项是框架级开关menuconfig DRM_ACCEL只有CONFIG_DRM开启时才可见帮助文本明确说明加速器与 GPU “共用大量公共部分几乎可以复用同一套基础设施代码”但会采用不同的 major 号并以accel/accel*的命名在/dev、sysfs 和 debugfs 中暴露框架之下当前挂接的具体设备驱动 Kconfig 有amdxdna、ethosu、habanalabs、ivpu、qaic、rocket与 drivers/accel/Makefile 所组织的子目录一一对应目录结构即为drivers/accel/{amdxdna,ethosu,habanalabs,ivpu,qaic,rocket}加框架核心drm_accel.c。因此开发者接入的第一步就是确认内核已配置CONFIG_DRM_ACCEL文档“Getting Started”一节的要求。3. 与 GPU 的区分独立 major 号与设备命名约定为了防止庞大的用户空间图形软件栈Mesa 等把加速器误当作 GPU 来使用原文档“Differentiation from GPUs”一节规定了两条隔离手段使用全新的 major 号 新的设备字符文件把加速器与 GPU 在用户空间层面区隔开驱动源码单独放在内核树的drivers/accel/目录而不是drivers/gpu/drm/之下。加速器设备以专用 major 号 261暴露给用户空间并遵循如下命名约定暴露位置约定设备字符文件/dev/accel/accel*sysfs/sys/class/accel/accel*/debugfs/sys/kernel/debug/accel/*/3.1 major 号 261 的定义ACCEL_MAJOR常量定义在 include/drm/drm_accel.h 中#define ACCEL_MAJOR 261注意它放在include/drm/而非include/uapi/——该 major 号是内核内部约定用户空间通过设备节点路径访问不需要在 uAPI 头文件中声明。3.2 命名约定的源码实现devnode 回调/dev/accel/accel*这一目录结构并非 udev 规则而是由内核类class的devnode回调直接生成的。drivers/accel/drm_accel.c 中static char *accel_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, accel/%s, dev_name(dev)); } static const struct class accel_class { .name accel, .devnode accel_devnode, };即设备节点路径被硬编码为accel/设备名而设备名本身按约定是accel0、accel1……最终得到/dev/accel/accel0这样的节点sysfs 侧由class_register(accel_class)产生/sys/class/accel/accel*/。3.3 字符设备注册stub fops 与按需切换accel_core_init()在 DRM 核心初始化阶段被调用错误清理由drm_core_exit()转调accel_core_exit()完成核心动作是把 major 261 注册为一个“stub”字符设备int __init accel_core_init(void) { int ret; ret accel_sysfs_init(); ... ret register_chrdev(ACCEL_MAJOR, accel, accel_stub_fops); ... }其中accel_stub_fops只有一个真正的openstatic int accel_stub_open(struct inode *inode, struct file *filp) { const struct file_operations *new_fops; struct drm_minor *minor; ... minor drm_minor_acquire(accel_minors_xa, iminor(inode)); ... new_fops fops_get(minor-dev-driver-fops); ... replace_fops(filp, new_fops); if (filp-f_op-open) err filp-f_op-open(inode, filp); ... }从源码结构看其工作方式是所有 accel 设备共用一个已注册的 major文件打开时先根据 inode 的minor 号从accel_minors_xaDEFINE_XARRAY_ALLOC(accel_minors_xa)定义的 xarray查找到对应的drm_minor再将该file的fops替换为具体驱动的 fopsreplace_fops最后调用驱动的open。这与 DRM 自身的drm_stub_open机制完全同构——再次印证“accel 设备就是一种新的 DRM 设备类型”。minor 号与设备实例的绑定则发生在设备实例化时void accel_set_device_instance_params(struct device *kdev, int index) { kdev-devt MKDEV(ACCEL_MAJOR, index); kdev-class accel_class; kdev-type accel_sysfs_device_minor; }该函数用MKDEV(261, index)组合出 devt并把设备实例挂到accelsysfs 类/sys/class/accel/accel*之下。3.4 公共 debugfs 节点框架还为每个加速器创建了公共 debugfs 文件位于/sys/kernel/debug/accel/*/下实现于accel_debugfs_register()static const struct drm_info_list accel_debugfs_list[] { {name, accel_name_info, 0} }; void accel_debugfs_register(struct drm_device *dev) { struct drm_minor *minor dev-accel; minor-debugfs_root dev-debugfs_root; drm_debugfs_create_files(accel_debugfs_list, ACCEL_DEBUGFS_ENTRIES, dev-debugfs_root, minor); }公共节点name会打印驱动名、底层设备名、master unique 与设备 unique 信息便于在 debugfs 中识别设备归属具体驱动可在此基础上追加自己的调试节点。4. Getting Started驱动接入 accel 框架的两处改动文档“Getting Started”一节给出了驱动接入清单这里完整继承并结合源码逐条展开。4.0 前置先读 DRM 文档文档明确要求首先阅读 DRM 文档Documentation/gpu/index.rst——它不仅讲解如何编写一个新的 DRM 驱动还包含贡献流程、行为准则Code of Conduct、编码与文档风格这些都同样适用于 accel 子系统。因为 accel 驱动在机制上就是一个 DRM 驱动所有drm_driver回调open/lastclose、GEM 回调、dumb系列等的语义完全一致。4.1 改动一设置DRIVER_COMPUTE_ACCEL特性标志在你的drm_driver.driver_features字段中加入DRIVER_COMPUTE_ACCEL。该标志定义在 include/drm/drm_drv.h/** * DRIVER_COMPUTE_ACCEL: * * Driver supports compute acceleration devices. This flag is mutually exclusive with * DRIVER_RENDER and DRIVER_MODESET. Devices that support both graphics and compute * acceleration should be handled by two drivers that are connected using auxiliary bus. */ DRIVER_COMPUTE_ACCEL BIT(7),两个关键约束与文档表述一致互斥性DRIVER_COMPUTE_ACCEL与DRIVER_RENDER、DRIVER_MODESET互斥。同一个drm_device不能同时声明“渲染/显示”与“计算加速”身份这是用户空间隔离第 3 节在驱动侧的强制点图形计算双能力设备的解法若硬件既需要暴露图形设备文件又需要暴露计算设备文件应当由两个驱动分别处理并通过auxiliary bus辅助总线框架把二者连接起来——典型场景如 GPU 内嵌的算力 IP 块。4.2 改动二使用accel_open()或DEFINE_DRM_ACCEL_FOPS把驱动fops结构中的open回调改为accel_open()。drivers/accel/drm_accel.c 中的accel_open文档注释明确要求“drivers must use it as their file_operations.open method”其实现流程为int accel_open(struct inode *inode, struct file *filp) { struct drm_device *dev; struct drm_minor *minor; int retcode; minor drm_minor_acquire(accel_minors_xa, iminor(inode)); if (IS_ERR(minor)) return PTR_ERR(minor); dev minor-dev; atomic_fetch_inc(dev-open_count); /* share address_space across all char-devs of a single device */ filp-f_mapping dev-anon_inode-i_mapping; retcode drm_open_helper(filp, minor); if (retcode) goto err_undo; return 0; ... } EXPORT_SYMBOL_GPL(accel_open);可以看到它完成三件事按 minor 号在accel_minors_xa中定位drm_minor、递增设备打开计数、复用设备级 anon_inode 的address_space并交由drm_open_helper()完成 per-file 资源实例化与drm_driver.open回调。更省事的方式是使用DEFINE_DRM_ACCEL_FOPS宏定义于 include/drm/drm_accel.h一次性生成整个 fops 结构#define DRM_ACCEL_FOPS \ .open accel_open,\ .release drm_release,\ .unlocked_ioctl drm_ioctl,\ .compat_ioctl drm_compat_ioctl,\ .poll drm_poll,\ .read drm_read,\ .llseek noop_llseek, \ .mmap drm_gem_mmap, \ .fop_flags FOP_UNSIGNED_OFFSET #define DEFINE_DRM_ACCEL_FOPS(name) \ static const struct file_operations name { \ .owner THIS_MODULE, \ DRM_ACCEL_FOPS, \ }从源码结构看DRM_ACCEL_FOPS与DRM_FOPS的字段一一对应唯一区别是open从drm_open换成了accel_open。宏头部的内核文档注释还特别提醒生成的结构体已隐含static且内部引用THIS_MODULE因此不能在多个驱动间共享——每个驱动必须各自DEFINE_DRM_ACCEL_FOPS(自己的名字)后赋给drm_driver.fops。于是驱动的接入形态概括为drv-driver_features DRIVER_COMPUTE_ACCELDEFINE_DRM_ACCEL_FOPS(accel_fops)然后drv-fops accel_fops其余回调GEM、open/lastclose、命令提交等按常规 DRM 驱动编写参见 Documentation/gpu/index.rst。5. 框架核心代码导读drivers/accel/drm_accel.cdrivers/accel/drm_accel.c 全文约 210 行是 accel 子系统除各设备驱动外的全部框架代码核心构件一览构件作用accel_minors_xaxarray保存 minor 号 →drm_minor的全局映射accel_stub_open/accel_open均通过它定位设备accel_classclass创建/sys/class/accel/devnode accel_devnode使设备节点落在/dev/accel/目录accel_devnode()返回accel/设备名形式的节点路径accel_core_init()/accel_core_exit()注册/注销 major 261 的字符设备与 accel class由 DRM 核心的 init/exit 链路统一驱动accel_set_device_instance_params()为设备实例设置MKDEV(ACCEL_MAJOR, index)与 class/typeaccel_open()驱动必须使用的fops-open实现EXPORT_SYMBOL_GPLaccel_stub_open()字符设备统一入口按 minor 切换 fopsaccel_debugfs_register()创建公共 debugfsname节点从源码结构看整个框架不引入任何新的内存管理或提交队列机制——这些都直接复用 DRM/GEM/syncobj 基础设施框架自身只负责“身份”major 号、命名空间、minor 路由和公共调试入口。这也是文档中“accel 层提供 a common set of functionality”的具体所指。6. 适用前提与限制小结适用前提设备属于计算加速器类别含但不限于 ML/DL 加速且驱动愿意按 DRM 驱动的形态编写drm_driver GEM 自有 ioctl/提交接口。限制与约束CONFIG_DRM_ACCEL依赖CONFIG_DRMDRIVER_COMPUTE_ACCEL与DRIVER_RENDER/DRIVER_MODESET互斥图形计算混合设备需借助 auxiliary bus 拆成两个驱动DEFINE_DRM_ACCEL_FOPS生成的 fops 因THIS_MODULE而不可跨驱动共享用户空间看到的设备节点固定为/dev/accel/accel*major 261图形用户空间软件栈不会将其识别为 GPU 渲染设备。7. 延伸阅读Documentation/accel/index.rstaccel 文档索引另含amdxdna、qaic、rocket等具体驱动的文档入口可与 drivers/accel/ 下的驱动实现对照阅读Documentation/gpu/index.rstDRM 驱动开发、贡献流程与编码风格原文档将其列为 accel 驱动开发者的必读前置文档drivers/accel/Kconfig、drivers/accel/Makefile框架与已合入设备驱动的配置/构建入口include/drm/drm_accel.h、include/drm/drm_drv.hACCEL_MAJOR、DEFINE_DRM_ACCEL_FOPS、DRIVER_COMPUTE_ACCEL等接口的权威定义该子系统的历史讨论可追溯至 Oded Gabbay 在 2022 年发起的新子系统方案讨论与补丁集LKML 邮件线程以及 Dave Airlie 在 LPC 2022 Accelerators BOF 后的总结文章原文档 introduction.rst 的“External References”一节列有对应出处可作为背景阅读。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门