[AI][昇腾950]smmu的功能与优化
·
SMMU 硬件功能、软件控制与优化技巧分析
一、SMMU 概述
1.1 什么是 SMMU
SMMU (System Memory Management Unit) 是 ARM 体系结构中的 系统内存管理单元,位于 I/O 设备与内存之间,负责 I/O 虚拟地址(IOVA)到物理地址(PA)的转换。
┌─────────────────────────────────────────────────────────────────────┐
│ SMMU 在系统中的位置 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ CPU │ │ GPU │ │ NPU │ │ DPU │ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
│ │ (MMU) │ (SMMU) │ (SMMU) │ (SMMU)│
│ ▼ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Memory Interconnect │ │
│ └──────────────────────────┬───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ DRAM (Physics Memory) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ 关键点: │
│ • CPU 使用 MMU (Memory Management Unit) │
│ • I/O 设备使用 SMMU (System MMU) │
│ • 两者都做虚拟地址→物理地址转换 │
│ │
└─────────────────────────────────────────────────────────────────────┘
1.2 SMMU 的核心作用
| 作用 | 说明 | 价值 |
|---|---|---|
| 地址隔离 | 每个设备有其独立的 IOVA 空间 | 安全隔离,防 DMA 攻击 |
| 内存保护 | 防止 I/O 设备访问未授权内存 | 提高系统安全性 |
| 虚拟化支持 | 支持虚拟机直通设备 (VFIO) | 虚拟化场景必需 |
| 大页支持 | 支持 4KB/2MB/1GB 大页 | 减少 TLB 压力 |
| IOVA 管理 | 设备使用逻辑地址,绕过 CPU 物理布局 | 灵活内存管理 |
二、SMMU 硬件功能
2.1 SMMU 架构 (ARM SMMUv2 vs v3)
┌─────────────────────────────────────────────────────────────────────┐
│ SMMU 架构演进 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ SMMUv2: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 传统两级转换 (Stage 1 + Stage 2) │ │
│ │ • Stage 1: OS 页表 (IOVA → IPA) │ │
│ │ • Stage 2: Hypervisor 页表 (IPA → PA) │ │
│ │ • 软件配置, 寄存器编程 │ │
│ │ • 无共享页表支持 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ SMMUv3: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 支持 CD (Context Descriptor) + STE (Stream Table Entry) │ │
│ │ • 队列机制 (CMDQ/EVTQ/PRIQ) │ │
│ │ • 支持共享页表 (与 CPU 共用) │ │
│ │ • 硬件页表遍历 (HWPTW) │ │
│ │ • 支持 MTE/PASID/ATS │ │
│ │ • 性能更好, 虚拟化更优 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
2.2 SMMU 主要硬件组件
| 组件 | 功能 | 说明 |
|---|---|---|
| Stream | I/O 设备的 DMA 流标识 | 每个设备/上下文一个 Stream |
| STE (Stream Table Entry) | 每 Stream 的配置表项 | 指向 CD/配置 |
| CD (Context Descriptor) | 每上下文页表描述 | 指向页表基地址 |
| TLB | 地址转换缓存 | 加速 IOVA→PA 转换 |
| HWPTW | 硬件页表遍历器 | 硬件执行页表查找 |
| CMDQ | Command Queue | 软件下发命令 |
| EVTQ | Event Queue | 硬件上报错误 |
| PRIQ | Page Request Queue | 内存回收请求 |
2.3 核心硬件能力
┌─────────────────────────────────────────────────────────────────────┐
│ SMMU 核心硬件能力 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ① 地址转换 (Translation): │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ IOVA → Stage1 → IPA → Stage2 → PA │ │
│ │ 支持 4KB/64KB/2MB/1GB 页 │ │
│ │ TLB 缓存常用转换 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ② 访问权限检查 (Permission Check): │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 读写权限 (R/W) │ │
│ │ • 执行权限 (X) │ │
│ │ • 设备/上下文隔离 │ │
│ │ • 缓存属性 (Cacheability/Shareability) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ③ 转换属性 (Translation Attributes): │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 内存类型: Device/Non-cacheable/Cacheable │ │
│ │ • 缓存策略: Write-through/Write-back │ │
│ │ • 共享属性: Inner/Outer/Non-shareable │ │
│ │ → 控制 DMA 的缓存行为 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ④ 虚拟化支持: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 两级转换 (Stage1+Stage2) │ │
│ │ • VFIO 直通支持 │ │
│ │ • 支持 PASID (进程地址空间 ID) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
三、地址转换流程
3.1 SMMUv3 转换流程
┌─────────────────────────────────────────────────────────────────────┐
│ SMMUv3 地址转换流程 │
├─────────────────────────────────────────────────────────────────────┤
│ I/O 设备发起 DMA (IOVA): │
│ IOVA: 0x10000000 │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Stream Table 查找 (按 StreamID) │ │
│ │ → 找到 STE (Stream Table Entry) │ │
│ └──────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ STE 指向 CD (Context Descriptor) │ │
│ │ → 确定转换配置 (Stage1/Stage2 是否启用) │ │
│ └──────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Stage 1 转换: IOVA → IPA │ │
│ │ • 查 CD 指向的 Stage1 页表 │ │
│ │ • TLB 命中则直接输出 │ │
│ │ • TLB 未命中则 HWPTW 硬件遍历 │ │
│ └──────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Stage 2 转换: IPA → PA (虚拟化时) │ │
│ │ • 查 CD 指向的 Stage2 页表 │ │
│ │ • 无虚拟化时跳过此步 │ │
│ └──────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 访问权限检查: R/W / Exec / Type │ │
│ │ → 合法则放行, 访问内存 │ │
│ │ → 非法则上报 EVTQ 事件 │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
3.2 页表结构
┌─────────────────────────────────────────────────────────────────────┐
│ SMMU 页表结构 (ARM 格式) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 四级页表 (4KB 页): │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ TTBR (页表基地址) │ │
│ │ ├── L0 (PGD) 512 项 → 1GB 块 │ │
│ │ │ ├── L1 (PUD) 512 项 → 2MB 块 │ │
│ │ │ │ ├── L2 (PMD) 512 项 → 4KB 页 │ │
│ │ │ │ │ └── L3 (PTE) 512 项 │ │
│ │ │ │ └── 2MB 大块 │ │
│ │ │ └── L2 直接映射 2MB │ │
│ │ └── L1 直接映射 1GB 块 │ │
│ │ │ │
│ │ 大页优势: 减少页表层级, 减少 TLB 压力 │ │
│ │ 1GB L1 块: 1 次 TLB 条目覆盖 1GB │ │
│ │ 2MB L2 块: 1 次 TLB 条目覆盖 2MB │ │
│ │ 4KB 页: 需 512 次 TLB 条目覆盖 2MB │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
四、性能优化技巧
4.1 大页 (Huge Page) 优化
┌─────────────────────────────────────────────────────────────────────┐
│ 大页优化 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 问题: 4KB 页导致 TLB 压力大 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 处理 1GB 数据 (4KB 页): │ │
│ │ → 需要 262144 个页表项 (PTE) │ │
│ │ → TLB 容量 512 项 → 大量 TLB miss │ │
│ │ → 每次 miss 触发页表遍历 (慢) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 优化: 使用 2MB/1GB 大页 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 处理 1GB 数据 (2MB 页): │ │
│ │ → 只需 512 个 PMD 项 (等于 TLB 容量!) │ │
│ │ → TLB 完全命中, 无 miss │ │
│ │ │ │
│ │ 处理 1GB 数据 (1GB 页): │ │
│ │ → 只需 1 个 PGD 项 │ │
│ │ → TLB 1 次命中覆盖全部 1GB │ │
│ │ → 极致优化 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 实际收益: 大页可提升 DMA 带宽 20~50% (减少页表遍历) │
│ │
└─────────────────────────────────────────────────────────────────────┘
4.2 Scatter-Gather 优化
// ============================================
// Scatter-Gather 优化
// ============================================
// 问题: 物理页不连续时, 每页一个 IOVA 映射
// 优化: 使用 SG 列表合并, 减少映射次数
// 方法 1: 使用 dma_map_sg 合并
struct scatterlist *sg;
int nents = dma_map_sg(dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
// 连续物理页被合并为更少的 DMA 段
// 方法 2: 使用 IOMMU 合并 IOVA
// 将物理不连续但 IOVA 连续的区域合并
// 设备可见的地址连续, 简化 DMA 描述符
4.3 使用场景优化技巧
┌─────────────────────────────────────────────────────────────────────┐
│ 优化技巧总结 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 优化技巧 1: 使用大页 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 使用 2MB/1GB 页而非 4KB 页 │ │
│ │ • 减少 TLB miss, 提升 DMA 性能 │ │
│ │ • 通过 kernel cmdline: transparent_hugepage=always │ │
│ │ • 或 hugetlbfs 显式分配大页 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 优化技巧 2: 预分配 IOMMU Domain │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 避免运行时频繁创建/销毁 domain │ │
│ │ • 复用已初始化的 page table │ │
│ │ • 减少 TLB 失效频率 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 优化技巧 3: 批量 TLB 失效 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 合并多次 dma_unmap 的 TLB 失效 │ │
│ │ • 使用 CMDQ 批量命令, 减少硬件等待 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 优化技巧 4: 使用 PASID 共享进程页表 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • SMMUv3 支持与 CPU 共享页表 │ │
│ │ • 避免复制页表, 减少内存开销 │ │
│ │ • 用户态直接映射 (如 CUDA/OpenCL) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 优化技巧 5: 控制 DMA 缓存属性 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 写回 (Write-back): 高性能, 需 cache flush 管理 │ │
│ │ • 透写 (Write-through): 一致性, 性能较低 │ │
│ │ • 非缓存 (Non-cacheable): 最安全, 最慢 │ │
│ │ → 按场景选择内存属性 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 优化技巧 6: 使用 IOMMU 旁路 (仅安全场景) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • iommu.passthrough=1 时设备直接 DMA │ │
│ │ • 消除转换开销, 性能最高 │ │
│ │ • 但失去安全隔离, 仅适合可信设备 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
4.4 性能对比数据
┌─────────────────────────────────────────────────────────────────────┐
│ SMMU 性能影响对比 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ DMA 带宽对比 (大块数据传输): │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 无 SMMU (旁路): 100% 基线 │ │
│ │ SMMU + 1GB 大页: 97% (仅 3% 开销) │ │
│ │ SMMU + 2MB 大页: 95% (5% 开销) │ │
│ │ SMMU + 4KB 页: 70% (30% 开销!) │ │
│ │ → 大页选择对性能影响巨大 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ TLB 案例分析 (1GB 数据): │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 4KB 页: 262144 次转换, TLB miss 频繁 │ │
│ │ 2MB 页: 512 次转换, TLB 完全覆盖 │ │
│ │ 1GB 页: 1 次转换, 极致 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
五、与 IOMMU 对比
5.1 SMMU vs IOMMU
| 特性 | SMMU | IOMMU |
|---|---|---|
| 架构 | ARM 架构 | Intel x86 VT-d |
| 位置 | ARM SoC | x86 平台 |
| 设备 | GPU/NPU/DPU/网卡 | 显卡/网卡/存储 |
| 页表格式 | ARM LPAE 格式 | x86 格式 |
| 虚拟化 | Stage1+Stage2 | 类似 |
| 共享页表 | 支持 (SMMUv3) | 支持 |
| 队列机制 | CMDQ/EVTQ/PRIQ | Queued invalidation |
5.2 核心相似与不同
┌─────────────────────────────────────────────────────────────────────┐
│ SMMU vs IOMMU │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 相同点: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • 均为 I/O 设备提供地址转换和安全隔离 │ │
│ │ • 均支持大页 (2MB/1GB) │ │
│ │ • 均支持虚拟化 (VFIO 直通) │ │
│ │ • 均支持 PASID (进程地址空间 ID) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 不同点: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ • SMMU: ARM 生态, 移动/嵌入式/服务器 │ │
│ │ • IOMMU: x86 生态, 服务器/桌面 │ │
│ │ • SMMUv3 队列机制更先进 │ │
│ │ • 两者 Linux 驱动接口一致 (DMA API/VFIO) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
六、总结
6.1 核心要点
┌─────────────────────────────────────────────────────────────────────┐
│ SMMU 核心要点 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. SMMU 是 I/O 设备的内存管理单元 │
│ • 提供 IOVA → PA 地址转换 │
│ • 提供安全隔离和访问控制 │
│ • 支持虚拟化 (VFIO 直通) │
│ │
│ 2. 硬件功能 │
│ • 两级转换 (Stage1+Stage2) │
│ • 大页支持 (4KB/2MB/1GB) │
│ • TLB 缓存加速地址转换 │
│ • CMDQ/EVTQ/PRIQ 队列机制 │
│ │
│ 3. 软件控制 │
│ • DMA API (dma_alloc/map) │
│ • VFIO (设备直通) │
│ • IOVA 管理和页表配置 │
│ • 内核 cmdline (iommu.passthrough) │
│ │
│ 4. 优化技巧 │
│ • 使用大页 (2MB/1GB) → 减少 TLB miss │
│ • Scatter-Gather 合并 → 减少映射 │
│ • 批量 TLB 失效 → 减少硬件等待 │
│ • PASID 共享页表 → 减少内存开销 │
│ • 旁路模式 → 极致性能 (仅安全场景) │
│ │
│ 5. 性能关键: 大页选择对 DMA 带宽影响可达 30% │
│ │
└─────────────────────────────────────────────────────────────────────┘
6.2 优化决策参考
| 场景 | 推荐配置 | 理由 |
|---|---|---|
| GPU/NPU 大块传输 | 1GB/2MB 大页 | 减少 TLB miss |
| 高速网卡 (NVMe/RDMA) | 2MB 大页 + 批量失效 | 高吞吐场景 |
| 虚拟化直通 | VFIO + SMMUv3 | 安全隔离 |
| 可信设备 (内部加速器) | IOMMU 旁路 | 极致性能 |
| 安全敏感场景 | SMMU 强制翻译 | 必须防 DMA 攻击 |
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐

所有评论(0)