浅析Linux设备驱动:DMA内存映射

文章目录

    • 概述
    • DMA与Cache一致性
    • DMA映射类型
    • 一致性DMA映射
      • dma_alloc_coherent
    • 流式DMA映射
      • dma_map_single
      • 数据同步操作
        • dma_direct_sync_single_for_cpu
        • dma_direct_sync_single_for_device
    • 相关参考

概述

现代计算机系统中,CPU访问内存需要经过Cache,但外部设备通常不感知Cache的存在,因此CPU和外设在访问DMA内存时,必须谨慎处理内存数据的一致性问题。为了处理这种一致性问题,同时为了兼顾多种设备类型,Linux系统会采用不同的规则来映射DMA内存,开发者遵循这套规则对DMA内存进行操作。

DMA与Cache一致性

DMA内存中的数据会涉及到CPU和设备的共同访问,区别在于CPU通常经过Cache访问内存,但常规的设备通常不会感知Cache的存在。因此,CPU写入的数据可能因为还存在Cache中而未及时刷入内存,从而导致设备没有DMA到最新的数据;反过来,设备已经向设备DMA了新的数据,但CPU可能仍然在使用Cache中旧的数据。
在这里插入图片描述
解决这种DMA与Cache间数据一致性的方法通常有两种,一种是设备硬件支持Cache一致性协议;另外一种就是软件通过同步操作来保证数据一致性。根据硬件是否支持Cache一致性,可以将设备分成两类:

  • cache coherence设备:设备之间的读写不需要关心cache的一致性问题,硬件将确保数据一致,比如连接在ARM CCI端口上的设备就是cache coherence设备;
  • non-coherence设备:需要额外的软件操作(flush/invalidate)等操作来确保数据一致;

DMA映射类型

Linux系统支持两种DMA映射类型:一致性DMA映射(Consistent DMA Mapping)和流式DMA映射(Streaming DMA Mapping)。二者的核心差异在于:

  • 一致性DMA映射情况下,无论是CPU还是设备,在访问DMA内存时,全程都不使用Cache,从而避免数据一致性问题;
  • 流式DMA映射则只在DMA传输数据时,通过软件操作来处理Cache的同步,以减轻关闭Cache对性能的影响。

一致性DMA映射

一致性DMA映射本质上是利用了硬件的支持,禁用了DMA内存缓存区的Cache功能。 CPU和DMA controller在发起对DMA缓冲区的并行访问的时候不需要考虑cache的影响,也就是说不需要软件进行Cache操作,CPU和DMA controller都可以看到对方对DMA缓冲区的更新。

dma_alloc_coherent

DMA一致性映射使用dma_alloc_coherent接口来分配DMA内存,实现流程如下:
在这里插入图片描述
dma_alloc_cohrent通过几种不同的方式分配DMA内存:

  1. 优先从Device Cohorent Pool申请内存,这是设备专用的DMA内存池;
  2. 若设备使用直接映射,通过dma_direct_alloc分配内存;
  3. 若设备使用IOMMU,通过IOMMU提供的操作接口分配内存。

流式DMA映射

流式DMA映射是一次性的,一般是需要进行DMA传输的时候才进行mapping,一旦DMA传输完成,就立刻ummap,或者使用dma_sync_*接口进行同步,并且硬件可以为顺序化访问进行优化。流式DMA映射是怎么保证数据一致性的呢,它的方式更加复杂,让我们从数据的两个方向来分析:

  • DMA_TO_DEVICE:CPU将数据写入cache,然后同步cache与RAM(映射区域),同步操作完成后设备再从RAM(映射区域)获取数据;
  • DMA_FROM_DEVICE:CPU标记RAM(映射区域)对应的cache line为无效状态,以避免设备将数据写入RAM(映射区域)后,CPU从cache中获得"脏数据"。

流式DMA映射根据数据方向对cache进行"flush/invalid",既保证了数据一致性,也避免了完全关闭cache带来的性能影响。
在这里插入图片描述

dma_map_single

DMA流式映射使用dma_map_single或dma_map_sg接口映射DMA内存,其中dma_map_sg支持Scantter/Gathter的处理,这里以dma_map_single接口说明DMA内存的申请流程:
在这里插入图片描述
dma_map_single支持两种方式映射DMA内存:

  • 直接映射方式,底层使用SWIOTLB机制实现;
  • 设备支持IOMMU,通过IOMMU提供的操作接口映射内存。

数据同步操作

DMA流式映射提供了两个接口:dma_direct_sync_single_for_cpu和dma_direct_sync_single_for_device,用于完成DMA内存数据的同步。

dma_direct_sync_single_for_cpu

如果你需要多次访问同一个流式映射DMA缓冲区,并且在DMA传输之间读写DMA缓冲区上的数据,这时候你需要使用dma_sync_single_for_cpu进行DMA缓冲区的sync操作,以便CPU和设备可以看到最新的、正确的数据。
在这里插入图片描述

dma_direct_sync_single_for_device

如果CPU操作了DMA缓冲区的数据,然后你又想让硬件设备访问DMA缓冲区,这时候,在真正让硬件设备去访问DMA缓冲区之前,你需要调用dma_direct_sync_single_for_device接口以便让硬件设备可以看到cpu更新后的数据。
在这里插入图片描述

相关参考

  • Dynamic DMA mapping guide
  • 扒开DMA映射的内裤
  • 看完秒懂:Linux DMA mapping机制分析

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

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

相关文章

16. BI - 推荐系统之 ALS 实现

本文为 「茶桁的 AI 秘籍 - BI 篇 第 16 篇」 文章目录 对 MovieLens 进行电影推荐 Hi,你好。我是茶桁。 前面两节课的内容中,我们从矩阵分解到 ALS 原理,依次给大家讲解了推荐系统中的一个核心概念。 矩阵分解中拆矩阵的背后其实是聚类。就说 k 等于几…

IT廉连看——C语言——操作符

IT廉连看—操作符 c语言中有许多操作符,可以用于对变量进行各种不同的操作 一、算术操作符 - * / % 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点…

tinymce问题处理

Vite构建工具下Tinymce踩坑指南 解决方案是在路劲前面增加/,这个跟上面链接有些区别,区别原因应该是如果路由采用的是createWebHashHistory则应该去掉/,如果是createWebHistory则应该加上/ 页面引用,一种异步加载,一种同步加载&…

供应链大数据:穿越经济迷雾的指南针

随着经济形势的变幻莫测,企业运营面临着前所未有的挑战。在这个充满不确定性的时代,供应链大数据如同一盏明亮的指南针,为企业提供精准的方向指引。下面,我们将深入探讨供应链大数据如何帮助企业洞察市场趋势、优化库存管理、降低…

猫毛过敏却想养猫时?如何缓解猫毛过敏?宠物空气净化器推荐

作为一个新养猫的主人,一开始并没有发现对猫咪过敏。直到养了半年才意识到这个问题,而此时我已经和猫咪有了深厚的感情。我不想放弃我的猫咪,但是留着它的话,我经常会因为流眼泪、打喷嚏、眼睛发红等过敏症状而影响日常生活&#…

神经网络系列---归一化

文章目录 归一化批量归一化预测阶段 测试阶段γ和β(注意)举例 层归一化前向传播反向传播 归一化 批量归一化 (Batch Normalization)在训练过程中的数学公式可以概括如下: 给定一个小批量数据 B { x 1 , x 2 , … …

WPF真入门教程29--MVVM常用框架之MvvmLight

1、MVVM模式回顾 关于mvvm模式的基础知识,请看这2个文章: WPF真入门教程23--MVVM简单介绍 WPF真入门教程24--MVVM模式Command命令 做过VUE开发或微信小程序开发的伙伴,就知道MVVM模式,核心就是数据驱动控件,全栈开…

软考 系统分析师系列知识点之需求获取(1)

所属章节: 第11章. 软件需求工程 第2节. 需求获取 需求获取是一个确定和理解不同的项目干系人的需求和约束的过程。需求获取是一件看上去很简单、做起来却很难的事情。需求获取是否科学、准备是否充分,对获取出来的结果影响很大,这是因为大部…

弱引用与C++智能指针

笔试题遇到了弱引用,但是C标准库是没有这个概念的,学了智能指针但是没有听说过弱引用,因此总结一下两者 学习视频链接来自B站 https://www.bilibili.com/video/BV1gV4y1G7fH?p2&vd_sourcefa4ef8f26ae084f9b5f70a5f87e9e41b智能指针 C的…

C语言:指针的进阶讲解

目录 1. 二级指针 1.1 二级指针是什么? 1.2 二级指针的作用 2. 一维数组和二维数组的本质 3. 指针数组 4. 数组指针 5. 函数指针 6. typedef的使用 7. 函数指针数组 7.1 转移表 1. 二级指针 如果了解了一级指针,那二级指针也是可以很好的理解…

基于django的购物商城系统

摘要 本文介绍了基于Django框架开发的购物商城系统。随着电子商务的兴起,购物商城系统成为了许多企业和个人创业者的首选。Django作为一个高效、稳定且易于扩展的Python web框架,为开发者提供了便捷的开发环境和丰富的功能模块,使得开发购物商…

第三百六十五回

文章目录 1. 概念介绍2. 方法与信息2.1 获取方法2.2 详细信息 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取设备信息"相关的内容,本章回中将介绍如何获取App自身的信息.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在本…

【mysql】1000w数据量的分页查询SQL,如何优化提升性能?

文章目录 优化场景特别注意!!!有前提,谨慎使用 优化场景 当表数据量非常大时,需要进行分页查询如果慢的时候,可以考虑优化下。 假设一页展示10条,查询第10w条后面的数据时候变慢了… 优化思路&…

【Java程序设计】【C00284】基于Springboot的校园疫情防控管理系统(有论文)

基于Springboot的校园疫情防控管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的校园疫情防控系统 本系统分为系统功能模块、管理员功能模块以及学生功能模块。 系统功能模块:在系统首页可以查…

【Unity】双击C#脚本文件以单个文件打开(Visual Studio)、父类找不到、引用找不到、无法跳转等问题

问题:新安装一个Unity后,突然发现在工程里双击C#脚本,会一个一个打开,虽然也是用VS软件打开了,但是它无法被正确识别为Unity工程的C#脚本,也就是说所有命名空间无效,因为没关联上整个工程的解决…

【蓝牙协议栈】常见蓝牙分析工具介绍

目录 1. HCI 录制工具 2. Air log 工具 3. Vendor chip 工具 本文主要介绍调试蓝牙协议栈,定位蓝牙问题的工具,而不是常用的编译烧录工具等,也不是开发蓝牙芯片的工具!本小节计划通过几个方面以及场景来介绍调试蓝牙的工具&…

【Vue3】‘vite‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。

问题 今天拿到别人项目的时候,我平时比较习惯用pnpm,我就使用pnpm i先下载依赖包,下载完成后,启动项目,就开始报以下错误! 但是当我执行pnpm i的时候,vite不应该就已经被我下载下来了吗 研究了…

【数据结构和算法初阶(C语言)】时间复杂度(衡量算法快慢的高端玩家,搭配例题详细剖析)

目录 1.算法效率 1.1如何衡量一个算法的好坏 1.2 算法的复杂度 2.主菜-时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.2.1算法的最好,最坏和平均的情况 3.经典时间复杂度计算举例 3.1计算冒泡排序的时间复杂度 3.2计算折半查找的时间复杂度 3.…

LLM权重量化

LLM权重量化 浮点表示的背景知识Nave 8位量化使用LLM.int8() 进行8位量化结论References 大型语言模型(llm)以其广泛的计算需求而闻名。通常,模型的大小是通过将**参数的数量(大小)乘以这些值的精度(数据类型)**来计算的。为了节省内存,可以通过称为量化…

Windows中的Git Bash运行conda命令:未找到命令的错误(已解决)

在windows中的Gitbash中 打开激活conda环境,并运行(前提是你先安装好git(自己去官网下载))。 要能够在Gitbash上运行Conda, 临时配置 如果你只是临时用一下,就是临时爽一把,那就按…