首页
/ Linux 内核 amdxdna 驱动:AMD NPU(XDNA 架构)硬件结构、资源调度与负载运行全流程解析

Linux 内核 amdxdna 驱动:AMD NPU(XDNA 架构)硬件结构、资源调度与负载运行全流程解析

2026-09-04 12:26:20作者:邬祺芯Juliet

AMD NPU 是集成在 AMD 客户端 APU 中的多用户 AI 推理加速器,由 Linux 内核的 amdxdna 驱动管理,可高效运行 CNN、LLM 等机器学习负载。本篇技术指南基于内核文档 AMD NPU 展开,完整梳理 NPU 的硬件组成(XDNA Array、共享 L2、微控制器、Mailbox、PCIe EP)、空间/时间混合调度机制、工作负载运行流程、DMA 与错误处理路径,并结合 amdxdna 驱动源码 说明驱动如何实现设备识别、固件加载、SVA/PASID 隔离与客户端用量统计,读完后你可以理解“一个 NPU 二进制如何从编译产物走到硬件执行并返回完成信号”的完整链路。

一、硬件组成:XDNA Array 与共享 L2 内存

AMD XDNA Array:2D 计算阵列

AMD NPU 基于 AMD XDNA 架构构建,核心是 XDNA Array——由 AMD AI Engine 技术构建的 2D 计算/存储阵列:

  • 每一列由 4 行计算 tile + 1 行存储 tile 组成;
  • 每个计算 tile 内含一个 VLIW 处理器,并带有独立的程序与数据内存;
  • 存储 tile 充当 L2 内存
  • 2D 阵列可以在列边界处切分,形成空间上相互隔离的分区(spatial partition),分区可绑定到一个工作负载上下文;
  • 每一列还拥有专用 DMA 引擎,负责在主机 DDR 与存储 tile(L2)之间搬运数据。

不同平台的阵列规模不同:

NPU 平台 阵列拓扑 计算列数 L2 总容量 最大并发负载上下文
AMD Phoenix / Hawk Point 4x5 5 列 2560 KB 6 个
AMD Strix Point 4x8 8 列 4096 KB 16 个

单行存储 tile 构成一个软件管理的片上 L2 内存池,DMA 引擎在主机 DDR 与存储 tile 之间移动数据。

微控制器:NPU 固件的执行者

NPU 内部微控制器运行 NPU 固件,职责包括:

  1. 命令处理;
  2. XDNA Array 分区建立;
  3. XDNA Array 配置;
  4. 工作负载上下文管理;
  5. 工作负载编排(orchestration)。

固件使用两类隔离上下文服务请求:

  • ERT(Execution Runtime Task):每个工作负载上下文对应一个专用的隔离非特权上下文实例,负责处理该负载的用户通道请求,并在负载上下文中执行用户提供的 ctrlcode
  • MERT(Management ERT):唯一的隔离特权上下文,专门服务来自 amdxdna 驱动的管理命令。

Mailbox:特权通道与用户通道

微控制器与 amdxdna 驱动之间通过**邮箱(mailbox)**通信,分为两类通道:

通道 用途 服务者 绑定关系
特权通道 上下文建立、遥测、查询、错误处理、用户通道建立等管理任务 MERT 绑定到单个 mailbox
用户通道 向 NPU 提交工作 该上下文的 ERT 实例 每个工作负载上下文独享一个 mailbox

PCIe EP:主机侧视角

NPU 对 x86 主机 CPU 呈现为一个 PCIe Endpoint,带多个 BAR 和若干 MSI-X 中断向量。NPU 使用专用的高带宽 SoC 级 fabric 读写主机内存;每个 ERT 实例拥有独立的 MSI-X 中断,MERT 拥有单个 MSI-X 中断

BAR 数量随设备而异,按功能可归类为:

  • PSP BAR:暴露 AMD PSP(Platform Security Processor,平台安全处理器)功能;
  • SMU BAR:暴露 AMD SMU(System Management Unit,系统管理单元)功能;
  • SRAM BAR:暴露 mailbox 的环形缓冲区;
  • Mailbox BAR:暴露 mailbox 控制寄存器(head、tail、ISR 寄存器等);
  • Public Register BAR:暴露公共寄存器。

不同设备中 BAR 的组合方式不同,例如:

  • AMD Phoenix 设备:PSP、SMU、Public Register BAR 均位于 PCIe BAR index 0;
  • AMD Strix Point 设备:Mailbox 与 Public Register BAR 位于 index 0,而 PSP 的寄存器分布在 index 0(Public Register BAR)和 index 4(PSP BAR)两处。

源码中可以看到驱动按 (device_id, rev_id) 选择设备信息结构:amdxdna_pci_drv.c 定义了 PCI 设备表(0x15020x17f00x17f20x17f30x1B0B0x1B0C),其中 0x17f0 的三个 rev(0x10/0x11/0x20)分别映射到 dev_npu4_infodev_npu5_infodev_npu6_info0x17f2/0x1B0B0x17f3/0x1B0C 则分别对应 NPU3 的 PF(物理功能)与 VF(虚拟功能)信息,这与上文“具体设备 BAR 布局不同”的说明相互印证。

二、进程隔离硬件与混合调度

进程隔离硬件

XDNA Array 可被动态切分为多个隔离的空间分区,每个分区包含一列或多列,由微控制器编程列隔离寄存器完成切分。每个空间分区关联一个 PASID,同样由微控制器写入,因此 NPU 内多个空间分区可以并发地访问主机内存并受 PASID 保护。NPU 固件自身则依赖微控制器 MMU 强制的隔离上下文来分别服务用户通道与特权通道请求。

从源码结构看,驱动侧通过 IOMMU SVA 绑定获得每个客户端的 PASID:amdxdna_pci_drv.c 中的 amdxdna_sva_init() 调用 iommu_sva_bind_device()iommu_sva_get_pasid() 取回 PASID,失败则解绑并返回 -ENODEV——这是“每个工作负载上下文独占 PASID 保护”的内核侧落点。

空间与时间混合调度

AMD XDNA 架构支持对 2D 阵列进行空间 + 时间(时分)混合调度:空间分区可随负载需求动态建立与拆除。一个空间分区可以独占绑定一个工作负载上下文,另一个分区则可能被临时(时间上)共享给多个上下文;对于临时共享的分区,微控制器会随时把其 PASID 更新为当前绑定上下文,从而在时分复用下依然保持隔离。

Resource Solver:列资源分配器

Resource Solver 是 amdxdna 驱动中负责在多个负载间分配 2D 阵列的组件:

  • 每个负载在元数据中声明运行 NPU 二进制所需列数;
  • Solver 结合负载给出的提示(hints)自身启发式策略,决定 2D 阵列的(重)分区策略以及空间/时间共享下的列映射;
  • 最终的“上下文—列”绑定决策由固件(FW)强制执行

源码实现位于 aie2_solver.c。其内部以 partition_node 描述一个分区(起始列 start_col、列数 ncols、是否独占 exclusive、共享请求数 nshared),与文档中“独占/临时共享”的语义一一对应。此外 Solver 还承担 QoS 检查与 DPM(动态功耗管理)档位选择qos_meet() 依据负载的 gopsfpslatency 参数计算所需服务能力,set_dpm_level() 遍历 cu_clk_list 中的各级频率,选出能满足所有会话的最低/合适档位(无 QoS 参数时直接取最高档)。

三、应用二进制:overlay 与 ctrlcode

一个 NPU 应用负载由 NPU 编译器生成的两个独立二进制组成:

  1. AMD XDNA Array overlay:用于配置 NPU 空间分区。overlay 包含计算 tile 的流开关(stream switch)配置指令与 ELF,由绑定该负载的空间分区所关联的 ERT 实例加载到分区上;
  2. ctrlcode:用于编排已加载到空间分区上的 overlay。它由运行在保护模式下、处于该负载上下文中的 ERT 在微控制器上执行,由一系列名为 XAie_TxnOpcode 的操作码序列构成。

特殊主机缓冲区

文档还描述了两种特殊缓冲区:

  • Per-context Instruction Buffer:每个工作负载上下文使用一块 64 MB 的常驻主机缓冲区,被内存映射到服务该负载的 ERT 实例中;负载的 ctrlcode 会拷贝进这块内存。该缓冲区与其他输入/输出缓冲区一样受 PASID 保护,同时也会映射到负载的用户空间;
  • Global Privileged Buffer:驱动另外分配一块全局缓冲区,用于 MERT 错误记录等维护任务。它使用全局 IOMMU 域,只有 MERT 可以访问。

四、运行一个 NPU 负载的高层流程

文档给出了在工作负载跑起来之前的 11 个步骤,这里按执行主体分组复述:

准备阶段(编译)

  1. 将负载编译为 overlay 与 ctrlcode 二进制。

上下文建立阶段(用户态 + 驱动 + 固件)

  1. 用户态在驱动中打开上下文(context)并提供 overlay
  2. 驱动向 Resource Solver 查询为该负载预置一组列;
  3. 驱动请求 MERT 在设备上按所需列创建上下文;
  4. MERT 创建 ERT 实例,并把 Instruction Buffer 映射进 ERT 内存
  5. 用户态把 ctrlcode 拷贝到 Instruction Buffer

提交与执行阶段

  1. 用户态创建命令缓冲区(command buffer),其中包含指向输入、输出与指令缓冲区的指针,随即将命令缓冲区提交给驱动并睡眠等待完成
  2. 驱动通过 Mailbox 把命令发送给 ERT
  3. ERT 执行指令缓冲区中的 ctrlcode
  4. ctrlcode 执行过程中触发到/自主机 DDR 的 DMA,同时 XDNA Array 在并行运行;
  5. ERT 到达 ctrlcode 末尾时,触发 MSI-X 中断向驱动发送完成信号,驱动随即唤醒等待中的负载。

这条链路与源码结构吻合:驱动通过 amdxdna_mailbox.c 实现 mailbox 收发,amdxdna_ctx.c 管理工作负载上下文,amdxdna_cbuf.c 处理命令缓冲区,而 DMA 与列分配的底层差异则分别由 aie2_solver.caie2_ctx.c(第二代 XDNA)与 aie4_* 系列文件(第四代,含 UMQ 用户邮箱队列与 SR-IOV)承载。

五、启动流程:经 PSP 安全加载 NPU 固件

amdxdna 驱动通过 PSP 安全加载签名的 NPU 固件并启动 NPU 微控制器,随后等待位于 BAR 0 上特殊位置的 alive 信号。SoC 挂起(suspend)期间 NPU 会断电,恢复(resume)后重新加载 NPU 固件并再次执行握手。

源码中可以直接看到驱动声明的固件清单:amdxdna_pci_drv.c 通过 MODULE_FIRMWARE() 声明了 amdnpu/1502_00/npu.sbinamdnpu/17f0_10/npu.sbinamdnpu/17f0_11/npu.sbinamdnpu/17f0_20/npu.sbin 及其对应的 npu_7.sbin 变体——这些设备 ID(1502/17f0)与上文 PCIe 设备表一致,说明固件按设备型号分目录存放。驱动的版本演进也记录在源码注释中(当前为 0.10,从“支持 BO 用量查询”演进到“支持 AIE4 UMQ”)。

编译依赖:该驱动是 DRM 加速子系统的一部分,Kconfig 定义了 DRM_ACCEL_AMDXDNA(“AMD AI Engine”),依赖 AMD_IOMMUDRM_ACCELPCIHAS_IOMEMX86_64,并选择 DRM_SCHEDDRM_GEM_SHMEM_HELPERFW_LOADERHMM_MIRROR;选 M 时生成 amdxdna 内核模块。HMM_MIRRORAMD_IOMMU 依赖正是 SVA/PASID 用户内存保护与主机缓冲区映射(见上节 Instruction Buffer)的基础。

六、用户态组件:编译器与 UMD

NPU 生态的用户态组件包括:

  • Peano:基于 LLVM 的开源单核编译器,面向 AMD XDNA Array 计算 tile(对应开源仓库 llvm-aie);
  • IRON:面向 AMD XDNA Array NPU 的开源阵列编译器,底层使用 Peano(对应开源仓库 mlir-aie);
  • XRT 运行时栈:开源用户态驱动运行时,与 amdxdna 内核驱动对接(Xilinx/XRT);
  • XRT 的 NPU shim:面向 NPU 的开源 shim 层(amd/xdna-driver)。

即典型链路为:编译器(Peano/IRON)生成 overlay + ctrlcode → XRT + xdna-driver shim 通过 DRM 接口调用 amdxdna 内核驱动 → 驱动经 MERT/ERT 与 mailbox 调度硬件执行。

七、DMA 操作、错误处理与遥测

DMA 操作

DMA 指令编码在 ctrlcode 中,对应 XAIE_IO_BLOCKWRITE 操作码。当 ERT 执行该操作码时,即在主机 DDR 与 L2 内存之间发起 DMA 搬运——这解释了为何 DMA 不需要用户态直接参与:搬运由 ERT 在执行 ctrlcode 序列的过程中自动触发。

错误处理

错误处理路径为:

  1. MERT 检测到 XDNA Array 中的错误后,暂停对应工作负载上下文的执行,并通过特权通道向驱动发送异步消息;
  2. 驱动向 MERT 发送缓冲区指针,让 MERT 捕获与出错上下文绑定的分区的寄存器状态
  3. 驱动读取该缓冲区内容,解码错误

这与第二节的 Global Privileged Buffer(仅 MERT 可访问、位于全局 IOMMU 域)共同构成维护/错误记录的数据通路。

遥测

MERT 可上报多种遥测信息,文档列举了:

  • L1 中断计数器;
  • DMA 计数器;
  • Deep Sleep 计数器;
  • 等等。

八、DRM 客户端用量统计(fdinfo)

amdxdna 驱动实现了 DRM client usage stats 规范(见内核文档 :ref:drm-client-usage-stats``)。文档给出了示例输出:

        pos:	0
        flags:	0100002
        mnt_id:	29
        ino:	939
        drm-driver:	amdxdna_accel_driver
        drm-client-id:	3219
        drm-pdev:	0000:c5:00.1
        amdxdna_accel_driver-heap-alloc:	60 KiB
        amdxdna_accel_driver-internal-alloc:	67588 KiB
        amdxdna_accel_driver-external-alloc:	0
        drm-total-memory:	67632 KiB
        drm-shared-memory:	0

其中驱动自有的三个键值对含义是:

  • heap-alloc:客户端 heap 分配(client->heap_usage);
  • internal-alloc:驱动内部 BO 分配(total_int_bo_usage);
  • external-alloc:外部 BO 分配(total_bo_usage - internal_usage)。

源码落点在 amdxdna_pci_drv.c:fdinfo 输出函数从 struct amdxdna_client(定义于 amdxdna_pci_drv.h)读取 heap_usagetotal_bo_usagetotal_int_bo_usage 三个计数器,经 drm_fdinfo_print_size() 打印。计数维护在 GEM 路径上:amdxdna_gem.camdxdna_gem_add_bo_usage()/amdxdna_gem_del_bo_usage() 在 BO 发布/回收时增减统计。此外驱动还实现了 AMD_IOCTL_AMDXDNA_GET_ARRAY 形式的跨客户端 BO 用量聚合查询amdxdna_drm_get_bo_usage(),见 amdxdna_gem.c),可一次性得到所有客户端的 total/internal/heap 用量汇总,便于用户态监控整个 NPU 的内存压力。

九、小结:从文档视角建立 NPU 内核栈心智模型

  • 硬件层:XDNA Array(VLIW 计算 tile 列 + L2 存储 tile + 每列 DMA)是算力与内存载体;微控制器固件(MERT/ERT)是控制大脑;mailbox + MSI-X 是主机与固件的通信骨架;PASID + 列隔离寄存器提供进程级空间隔离。
  • 驱动层:amdxdna 作为 DRM accel 驱动负责设备识别(PCI ID 表)、PSP 固件加载与 alive 握手、SVA/PASID 绑定、Resource Solver 列分配、上下文与命令缓冲区管理、错误解码与遥测上报,以及 DRM client usage stats。
  • 应用层:Peano/IRON 编译出 overlay 与 ctrlcode,XRT + xdna-driver shim 经 DRM 接口提交负载;执行期由 ERT 运行 ctrlcode,通过 XAIE_IO_BLOCKWRITE 触发 DDR↔L2 的 DMA,最后以 MSI-X 完成信号唤醒用户态。

阅读入口建议:文档本体 amdnpu.rst 与加速子系统总览 accel/index.rst;驱动源码 drivers/accel/amdxdna,重点关注 amdxdna_pci_drv.c(设备表/固件/fdinfo)、aie2_solver.c(资源求解)、amdxdna_ctx.c(上下文)、amdxdna_cbuf.c(命令缓冲区)、amdxdna_mailbox.c(邮箱通信)与 aie_psp.c(PSP 固件加载)。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
901
1.82 K
docsdocs
暂无描述
Markdown
888
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
589
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.51 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341