音频smmu问题之smmu学习

news2024/10/6 22:27:02

一、音频smmu 内存访问问题

在工作中,遇到一个smmu问题,主要log信息如下:

arm-smmu 15000000.apps-smmu: Unhandled arm-smmu context fault from soc:spf_core_platform:qcom,msm-audio-ion!
arm-smmu 15000000.apps-smmu: FAR = 0x000000001fff8000
arm-smmu 15000000.apps-smmu: PAR = 0x0000000000000000
arm-smmu 15000000.apps-smmu: FSR = 0x40000408 [PF R SS]
arm-smmu 15000000.apps-smmu: FSYNR0 = 0x320002
arm-smmu 15000000.apps-smmu: FSYNR1 = 0xe00e
arm-smmu 15000000.apps-smmu: context bank# = 0x30
arm-smmu 15000000.apps-smmu: TTBR0 = 0x0000000000000000
arm-smmu 15000000.apps-smmu: TTBR1 = 0x0000000000000000
arm-smmu 15000000.apps-smmu: SCTLR = 0x0a5f00e7 ACTLR = 0x00000003
arm-smmu 15000000.apps-smmu: CBAR = 0x0001f300
arm-smmu 15000000.apps-smmu: MAIR0 = 0xf404ff44 MAIR1 = 0x0000efe4
arm-smmu 15000000.apps-smmu: SID = 0x1001
arm-smmu 15000000.apps-smmu: Client info: BID=0x7, PID=0x0, MId=0xe
arm-smmu 15000000.apps-smmu: soft iova-to-phys=0x00000000bc299000
arm-smmu 15000000.apps-smmu: hard iova-to-phys(ATOS)=0x00000000bc299000

1、从堆栈来看大致可以了解到, 这是由于SMMU监测到某个模块非法的访问DMA地址后, 引起了内核崩溃. 那么, 为何有这个错误SMMU访问错误? 这个错误又是哪个模块导致的? 是在什么情况下引起的SMMU内存错误了? 这不得不从SMMU本身说起.

继续来看下问题的日志. 堆栈的前面一部分是有关SMMU的状态寄存器:
FAR(Fault Address Register): 表示发生错误的IO虚拟地址
PAR(Physical Address Register): 发生错误时查找到的物理地址, 这里是全0, 说明相应的IOVA地址没有映射
FSR(Fault Status Register): 表示SMMU错误的类型(转换/权限等), 这里的值0x40000408 [PF R SS], 说明是一个读操作时引起的页表访问错误
TTBRm(Translation Table Base Address):
TTBR0: 保存Translation Table0的基地址
TTBR1: 保存Translation Table1的基地址
SID(Stream ID): SID是对应设备使用SMMU映射内存时的标识

重点看下如下两行日志, 我们可以知道发生内存映射异常的IOVA地址是0x1fff8000, 对应的SID是0x1001

arm-smmu 15000000.apps-smmu: FAR = 0x000000001fff8000
arm-smmu 15000000.apps-smmu: SID = 0x1001

SID一般在设备树DTS的配置中指定的或者可以在modem代码中查看

路径:/trustzone_images/core/settings/kernel/iortlib/config/xxx/xxx.c

2、理清楚这些SMMU的日志只是第一步, 但是对于为何会发生SMMU访问异常还是毫无头绪. 这个只能通过阅读驱动源代码弄清楚代码流程才能一步步揭开迷雾了.

网卡需要传数据时, 获取到当前的缓冲区对应的DMA内存地址(IOVA)后, 通过SMMU向对应的RAM地址传输数据
发送完成后, 通过中断告知驱动有数据需要接收
CPU接收到中断后, 驱动会把DMA的映射解除, 数据交由CPU处理; 接着驱动把对应的数据发送到协议栈继续处理

那么, 问题来了, SMMU是何时收到DMA访问异常错误的了? 是在第三个步骤, 驱动解除DMA地址映射后, 有地方再次尝试使用该DMA地址导致的吗? 从驱动的逻辑来看, 每次传送完成, DMA地址与RAM地址解除映射后, 没有地方会再次尝试获取该DMA地址了(对应buffer的DMA地址已经置空). 退一步说, 如果是驱动使用的时候发生的问题, 那么异常的堆栈应该会打印出来, 但是现在只有SMMU相关的日志.

所以, 问题的源头只能是在网卡通过SMMU往对应的DMA地址发送数据的时候, 就是说如果网卡给DMA传输数据的大小超过了预分配的buffer的大小的话, SMMU会发现对应的DMA地址没有映射到物理地址, 从而报错. 解决问题的办法也很简单, 只需要把buffer大小由原来的1538修改为2048(2kb)就可以了:

从高通给的一些问题案例来说, 一般SMMU都是由于需要传输的数据大小与实际的buf大小不一致导致的. 总的说来, SMMU的问题看起来十分棘手, 但只要把基本的概念与原理弄清楚, 把代码流程梳理完整, 解决这类问题并不是件十分困难的事情.

二、smmu 相关知识学习

1、概述

简单来说, SMMU(System Memory Management Unit)是ARM为外设访问系统RAM提供了一种类似于MMU的虚拟内存访问机制, 外设可以通过DMA直接访问RAM, 而无需CPU的干预. 如此, 外设可以通过一个虚拟的地址即可访问物理地址(可以不连续), 做到了不同外设之间IO地址空间的彼此独立与隔离. 因此, SMMU也通常被称为IOMMU(Input/Output MMU).

下图是从ARM SMMU Spec手册里的一张SMMU简图: SMMU为设备与RAM之间构建了一个设备虚拟地址(IOVA)与物理地址之间的映射关系, 每次执行DMA数据传输的时候, 都要通过SMMU将IOVA地址翻译成对应的物理地址.
在这里插入图片描述
那么对于设备驱动来说, 如何使用SMMU了? 不妨来看下SMMU相关的API.

arm_iommu_create_mapping: 配置设备所要使用的VA(Virtual Address, 虚拟地址)的范围
arm_iommu_attach_device: 将分配好的VA地址范围与设备绑定, 并开启SMMU地址转换
dma_map_single/dma_unmap_single: 分配/去除某个DMA地址, 这种方式是异步的, 常用于一次性传输的场景(传输完成后DMA的映射即解除了)
dma_alloc_coherent/dma_free_coherent: 一致性(consistent), 同步(synchronous)的DMA内存分配方法, 确保CPU与设备的数据始终是同步的, 一般用于需要常驻内存的一些数据
这里不对IOMMU的代码做深入分析了. 有关IOMMU相关的流程可以参考内核代码:

kernel/drivers/iommu: SMMU驱动, 用于配置SMMU, 为设备驱动提供接口
kernel/arch/arm64/mm: 与平台相关的SMMU的页表分配的实现

2、smmu寄存器

FAR(Fault Address Register): 表示发生错误的IO虚拟地址
PAR(Physical Address Register): 发生错误时查找到的物理地址, 这里是全0, 说明相应的IOVA地址没有映射
FSR(Fault Status Register): 表示SMMU错误的类型(转换/权限等), 这里的值0x40000408 [PF R SS], 说明是一个读操作时引起的页表访问错误
TTBRm(Translation Table Base Address):
TTBR0: 保存Translation Table0的基地址
TTBR1: 保存Translation Table1的基地址
SID(Stream ID): SID是对应设备使用SMMU映射内存时的标识

参考
https://mp.weixin.qq.com/s/IsNUsalsE2sZOd2AJlXtjQ?poc_token=HLeZ2WWjwsFSMFprJ21xG6cSnuJWTNdnE0gRy9h5
https://zhuanlan.zhihu.com/p/662140784
https://zhuanlan.zhihu.com/p/650483261

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1469223.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【大数据】Flink 内存管理(四):TaskManager 内存分配(实战篇)

《Flink 内存管理》系列(已完结),共包含以下 4 篇文章: Flink 内存管理(一):设置 Flink 进程内存Flink 内存管理(二):JobManager 内存分配(含实际…

小米标准模组+MCU 快速上手开发(一)——之固件下载

小米标准模组+MCU 开发笔记之固件下载 背景技术名词简介● 小米IoT开发者平台● 小米IoT 模组● ESP系列简介问题描述 + 解决方式问题1:固件下载是否有示例,如何下载到硬件板卡中?问题2:固件下载的官方程序是什么?在哪里?该如何使用?问题3:固件下载时,Flash和Ram 有什…

【C++那些事儿】C++入门 | 命名空间 | 缺省参数 | 引用 | 内联函数 | auto关键字 | 范围for循环 | nullptr

📷 江池俊: 个人主页 🔥个人专栏: ✅数据结构冒险记 ✅C那些事儿 🌅 有航道的人,再渺小也不会迷途。 文章目录 前言1. C关键字(C98)2. 命名空间2.1 命名空间定义2.2 命名空间使用 3. C输入&输出4. 缺…

【初中生讲机器学习】12. 似然函数和极大似然估计:原理、应用与代码实现

创建时间:2024-02-23 最后编辑时间:2024-02-24 作者:Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏,很高兴遇见你~ 我是 Geeker_LStar,一名初三学生,热爱计算机和数学,我们一起加…

C++基础知识(六:继承)

首先我们应该知道C的三大特性就是封装、继承和多态。 此篇文章将详细的讲解继承的作用和使用方法。 继承 一个类,继承另一个已有的类,创建的过程 父类(基类)派生出子类(派生类)的过程 继承提高了代码的复用性 【1】继承的格式 class 类名:父类名 {}; 【…

基于ILI9341的TFT-LCD屏幕显示要点总结

目录 LCD常用引脚及其功能 LCD驱动流程 RGB565 关键指令 GRAM自增方向 设置开始坐标和结束坐标 写GRAM指令 读GRAM指令 本文主要参考视频如下: 第37讲 LCD-TFTLCD原理与配置介绍-M4_哔哩哔哩_bilibili 说明: 目前,市面上常见的TFT-LC…

#FPGA(IRDA)

1.IDE:Quartus II 2.设备:Cyclone II EP2C8Q208C8N 3.实验:IRDA(仿真接收一个来自0x57地址的数据0x22 (十进制34)) 4.时序图: 5.步骤 6.代码: irda_receive.v module irda_receive ( input wire…

记一次生产jvm oom问题

前言 jvm添加以下参数,发生OOM时自动导出内存溢出文件 -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/opt 内存分析工具: MAT, 下载地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation, 注意工具地址…

Uncertainty-Aware Mean Teacher(UA-MT)

Uncertainty-Aware Mean Teacher 0 FQA:1 UA-MT1.1 Introduction:1.2 semi-supervised segmentation1.3 Uncertainty-Aware Mean Teacher Framework 参考: 0 FQA: Q1: 不确定感知是什么意思?不确定信息是啥?Q2:这篇文章的精妙的点…

AI绘画工具有哪些?

AI绘画工具是利用人工智能技术来辅助或生成艺术作品的工具。这些工具可以分为两类:一类是生成艺术作品的工具,另一类是辅助艺术创作的工具。本文将介绍一些主流的AI绘画工具,并分析它们的特点和适用场景。 1. DALL-E DALL-E 是由 OpenAI 开发…

并发编程(5)共享模型之不可变

7 共享模型之不可变 本章内容 不可变类的使用不可变类设计无状态类设计 7.1 日期转换的问题 问题提出 下面的代码在运行时,由于 SimpleDateFormat 不是线程安全的, 有很大几率出现 java.lang.NumberFormatException 或者出现不正确的日期解析结果,…

Java+SpringBoot,打造极致申报体验

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…

web安全学习笔记【16】——信息打点(6)

信息打点-语言框架&开发组件&FastJson&Shiro&Log4j&SpringBoot等[1] #知识点: 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源-C…

东方博宜 1519. 求1~n中每个数的因子有哪些?

东方博宜 1519. 求1~n中每个数的因子有哪些&#xff1f; #include<iostream> using namespace std; int main() {int n ;cin >> n ;for(int i 1 ; i < n ; i){int a[1000] ;int k 0 ;for(int j 1 ; j < i ; j){if(i%j0){a[k] j ;k ;} }cout << i …

Golang Redis:构建高效和可扩展的应用程序

利用Redis的闪电般的数据存储和Golang的无缝集成解锁协同效应 在当前的应用程序开发中&#xff0c;高效的数据存储和检索的必要性已经变得至关重要。Redis&#xff0c;作为一个闪电般快速的开源内存数据结构存储方案&#xff0c;为各种应用场景提供了可靠的解决方案。在这份完…

从docx提取文本的Python实战代码

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

限流算法

下面对常见的限流算法进行讨论。目前&#xff0c;常用的限流算法主要有三种&#xff1a;计数器法、滑动窗口算法、漏桶算法和令牌桶算法。下面分别介绍其原理。 1. 计数器法 计数器法是通过计数对到来的请求进行选择性处理。如系统限制一秒内最多有X个请求&#xff0c;则在该…

opengles 顶点坐标变换常用的矩阵(九)

文章目录 前言一、opengles 常用的模型矩阵1. 单位矩阵2. 缩放矩阵3. 位移矩阵4. 旋转矩阵二、第三方矩阵数学库1. glm1.1 ubuntu 上安装 glm 库1.2 glm 使用实例1.2.1 生成一个沿Y轴旋转45度的4x4旋转矩阵, 代码实例如下1.2.2 生成一个将物体移到到Z轴正方向坐标为5处的4x4 vi…

黑马JavaWeb开发跟学(一)Web前端开发HTML、CSS基础

黑马JavaWeb开发一.Web前端开发HTML、CSS基础 引子、Web开发介绍传统路线本课程全新路线本课程适用人群课程收获一、什么是web开发二、网站的工作流程三、网站的开发模式四、网站的开发技术 前端开发基础一、前端开发二、HTML & CSS2.1 HTML快速入门2.1.1 操作第一步第二步…

数据存储-文件存储

一、CSV文件存储 csv是python的标准库 列表数据写入csv文件 import csvheader [班级, 姓名, 性别, 手机号, QQ] # 二维数组 rows [[学习一班, 大娃, 男, a130111111122, 987456123],[学习二班, 二娃, 女, a130111111123, 987456155],[学习三班, 三娃, 男, a130111111124, …