在ARM架构的嵌入式系统中,SMMU(System Memory Management Unit)作为IOMMU(Input/Output Memory Management Unit)的实现,为DMA外设访问系统内存提供了关键的内存管理功能。SMMU的主要作用包括地址翻译、内存保护和设备隔离,这些功能对于现代嵌入式系统的稳定性和安全性至关重要。
SMMU通过以下三个核心功能为DMA设备提供系统内存访问服务:
地址翻译(Translation):将设备提供的虚拟地址(IOVA)转换为系统物理地址(PA),使设备能够透明地访问分散在物理内存中的数据。
内存保护(Protection):通过转换表中的权限设置,可以精细控制每个设备对内存区域的访问权限(读/写/执行),防止设备越权访问。
设备隔离(Isolation):即使多个设备共享同一个SMMU连接,也能为每个设备配置独立的转换和保护属性,确保设备间的内存访问相互隔离。
SMMU Fault是指当DMA设备通过SMMU访问系统内存时,由于各种原因导致访问失败而触发的错误。常见触发场景包括:
这些错误会导致系统产生SMMU Fault中断,如果不妥善处理,可能引发系统稳定性问题。
当前高通平台分析SMMU Fault主要依赖三种手段:
这些方法存在信息不完整、分析效率低、对人员经验依赖高等问题。
我们的SMMU Fault维测方案旨在解决以下问题:
在XCD等复杂平台上实现有效的SMMU Fault维测面临多重挑战:
我们的解决方案基于对IOVA(IO Virtual Address)的精细监控,核心思路是:
方案引入了以下核心数据结构:
iova_mapping结构体:记录IOVA释放时的关键信息
c复制struct iova_mapping {
pid_t pid; // 释放线程的进程ID
pid_t tgid; // 释放线程的线程组ID
char comm[16]; // 释放线程的名称
u64 free_nsec; // 释放时间戳(纳秒级)
unsigned long free_stack[8]; // 释放调用栈
};
iova_shadow结构体:管理2MB大小IOVA区域的标记信息
c复制struct iova_shadow {
unsigned long start_pfn; // 起始PFN
atomic_t count; // 使用中的iova_mapping数量
struct hlist_node node; // 哈希链表节点
struct list_head list; // 内存池链表
struct iova_mapping mapping[512]; // 512个4K页的映射信息
};
方案在以下关键路径插入监控逻辑:
IOVA分配路径:
code复制alloc_iova_fast → iova_rcache_get/iova_alloc → 清除对应iova_mapping
IOVA释放路径:
code复制free_iova_fast → iova_rcache_insert/iova_free → 填充对应iova_mapping
SMMU Fault处理路径:
code复制arm_smmu_context_fault → report_iommu_fault_helper → check_iova_status
Rcache用于管理小尺寸(order≤5)且频繁分配的IOVA,其维测实现包括:
数据结构扩展:
关键操作:
RB tree用于管理大尺寸(order>5)的IOVA,实现更为复杂:
内存优化设计:
关键操作:
为确保方案的实际可用性,我们实施了多项优化:
内存占用控制:
性能影响最小化:
我们在dwc3 USB驱动和GPU驱动等场景进行了充分测试:
Rcache测试案例:
log复制[ 268.528427] check_iova_status
[ 268.537031] find_iova_rcache pfn:0xef3d7 log_size:0
[ 268.547453] BUG: iova rcahce error
[ 268.555798] iova iova_domain:00000000bcc533bd pfn:0xef3d7 addr: 0xef3d7000 has been released
[ 268.569369] iova released by pid:14924 tgid:14886 comm:UsbFfs-worker free_ts 268528288266 ns
[ 268.582848] iova freed backtrace:
[ 268.591072] free_iova_fast+0x184/0x228
[ 268.591086] iommu_dma_free_iova+0x1b0/0x418
RB tree测试案例:
log复制[ T295][C0][irq/58-arm-smmu] check_iova_status
[ T295][C0][irq/58-arm-smmu] find_iova_rbtree pfn:0xfac00
[ T295][C0][irq/58-arm-smmu] iova iova_domain:ffffff88b7388008 pfn:0xfac00 addr: 0xfac00000 has been released
[ T295][C0][irq/58-arm-smmu] iova released by pid:386 tgid:386 comm:recovery free_ts 22713308089 ns
内存占用:
CPU开销:
该方案在实际项目中取得了显著效果:
动态配置机制:
非致命Fault处理:
性能持续优化:
本SMMU Fault维测方案通过创新的IOVA标记和追踪机制,有效解决了复杂嵌入式系统中DMA内存访问问题的诊断难题。方案兼具实用性和高效性,已在多个量产项目中验证其价值,为系统稳定性和开发效率带来了显著提升。随着DMA设备在车载、移动等领域的广泛应用,这套维测方案将发挥越来越重要的作用。