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 攻击
Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐