linux dma cache和主存数据不一致问题

news2024/9/20 6:13:53

1、问题原因

根本原因是cache和dma的目的地址存在重叠。

如果DMA的目的地址与Cache所缓存的内存地址访问有重叠(如上图所示) , 经过DMA操作, 与Cache缓存对应的内存中的数据已经被修改, 而CPU本身并不知道, 它仍然认为Cache中的数据就是内存中的数据, 那在以后访问Cache映射的内存时, 它仍然使用陈旧的Cache数据。 这样就会发生Cache与内存之间数据“不一致性”的错误。

2、解决问题的方法

2.1、使用不带cahce的内存申请函数去申请DMA

如用函数dma_alloc_coherent();申请的内存是uncached的。

2.2、手动同步cache

如调用函数dma_cache_sync();

有时给DMA用的内存是其他模块已经分配好的,例如协议栈发包时,最终要把skb的地址和长度交给DMA,除了将skb地址转换为物理地址外,还要将CPU cache写回(因为cache里可能是新的,内存里是旧的)。

2.3、流式DMA映射(DMA Streaming Mapping)

相关接口为 dma_map_sg(), dma_unmap_sg(),dma_map_single(),dma_unmap_single()。

一致性缓存的方式是内核专门申请好一块内存给DMA用。而有时驱动并没这样做,而是让DMA引擎直接在上层传下来的内存里做事情。例如从协议栈里发下来的一个包,想通过网卡发送出去。但是协议栈并不知道这个包要往哪里走,因此分配内存的时候并没有特殊对待,这个包所在的内存通常都是可以cache的。这时,内存在给DMA使用之前,就要调用一次dma_map_sg()或dma_map_single(),取决于你的DMA引擎是否支持聚集散列(DMA scatter-gather),支持就用dma_map_sg(),不支持就用dma_map_single()。由于协议栈下来的包的数据有可能还在cache里面,调用dma_map_single()后,CPU就会做一次cache的flush,将cache的数据刷到内存,这样DMA去读内存就读到新的数据了。DMA用完之后要调用对应的unmap接口。unmap相关的接口里面其实有将cache置无效的操作(可以通过查看dma_unmap_sg()的函数实现来知道)。

还要注意,这几个接口都是一次性的,每次操作数据都要调用一次map和unmap。并且在map期间,CPU不能去操作这段内存,因此如果CPU去写,就又不一致了。同样的,dma_map_sg()和dma_map_single()的后端实现也都是和硬件特性相关。

2.4、cache coherent

上面说的是常规DMA,有些SoC可以用硬件做CPU和外设的cache coherence,例如在SoC中集成了叫做“Cache Coherent interconnect”的硬件,它可以做到让DMA踏到CPU的cache或者帮忙做cache的刷新。这样的话,dma_alloc_coherent()申请的内存就没必要是非cache的了。

2.5、CMA

CMA, ( Contiguous Memory Allocator) 。 通过这套机制, 我们可以做到不预留内存, 这些内存平时是可用的, 只有当需要的时候才被分配给Camera、 HDMI等设备。CMA对上呈现的接口是标准的DMA, 也是一致性缓冲区API。

3、总结

在DMA操作中cache和主存的数据不一致性的问题很常见,产生的根本原因是cache所访问的地址和dma的目的地址存在重叠,可以使用多种方法来避免这样的问题。

4、后续

上面只是理论依据,需要自己写代码实践验证才能真正地弄懂它。笔者已经通过实际的代码例程去验证理论,请看这篇文章:

Linux 流式DMA映射(DMA Streaming Mapping)-CSDN博客

参考资料

《Linux设备驱动开发详解-基于最新的Linux4.0内核》---宋宝华编著

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

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

相关文章

VScode开发ESP32

以下是所有的功能 先选择串口,再选择编译,然后再烧录

2023年最新自适应主题懒人网址导航v3.9php源码

源码简介 这个懒人网址导航源码是一个基于PHPMySQL开发的网址导航系统。该版本是在原有3.8版本的基础上进行了修复和功能增强。我们建议新用户直接使用这个最新版本,放弃旧版本。如果你有二次开发的能力,可以根据更新日志自行进行升级。我们将在后期继续…

论文阅读笔记:RepViT: Revisiting Mobile CNN From Vit Perspective

文章目录 RepViT: Revisiting Mobile CNN From Vit Perspective动机现状问题 贡献实现Block设置独立的token融合器和通道融合器减少膨胀并增加宽度 宏观设计stem的早期卷积简单分类器整体阶段比率 微观设计内核大小选择Squeeze-and-excitation层放置网络架构 实验ImageNet-1K上…

idea import配置

简介 本文记录idea中import相关配置:自动导入依赖、自动删除无用依赖、避免自动导入*包 自动导入依赖 在编辑代码时,当只有一个具有匹配名称的可导入声明时,会自动添加导入 File -> Settings -> Editor -> General -> Auto Imp…

基于xr-frame实现微信小程序的人脸识别3D模型叠加AR功能(含源码)

前言 xr-frame是一套小程序官方提供的XR/3D应用解决方案,基于混合方案实现,性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。xr-frame在基础库v2.32.0开始基本稳定,发布为正式版,但仍有一些功能还在开发&#…

笔试——双指针算法

双指针&#xff1a; 把数组下标看作指针&#xff0c;注意数组越界问题&#xff0c;注意区间边界值 文章目录 283.移动零1089.复写零 283.移动零 class Solution {public void moveZeroes(int[] nums) {int cur 0;int dest -1;while(cur < nums.length)if(nums[cur] ! 0)…

uni-app开发日志:schema2code生成的新增页和修改页因字段太多用分段器实现分段分类

schema2code默认只能实现较为简单的分组&#xff0c;当填写项目较多的时候&#xff0c;肯定是用选项卡明确分段比较合适&#xff0c;这时候schema2code自生成的就没法实现了&#xff0c;摒着最最少的代码修改来尝试设置生成前的schema和生成后的vue页面。 一、schema设计 先把…

ORA-16072: a minimum of one standby database destination is required

原因 Doc ID 260819.1 The problem is that these Data Guard protection mode will not allow the database to be opened without a Standby Database available and a corresponding setup log_archive_dest_n. Therefore the Data Guard Protection Mode must be reduced…

MATLAB 地面点构建三角网(83)

MATLAB 地面点构建三角网(83) 一、算法介绍二、算法实现1.代码一、算法介绍 使用少量的抽稀后的地面点。构建了一层2.5维的三角网,用于表示地形的起伏变化,随着点数量增多,构建和耗时都会相应增加,这里只是输出和研究三角网构建效果,并不做实际工程使用,具体的构建结果…

在容器 (podman) 中运行虚拟机 (QEMU/KVM, libvirt)

虚拟机 (virtual machine) 是一种计算机的虚拟化技术, 容器 (container) 是一种更轻量级的虚拟化技术. 虚拟机可以套娃 (嵌套, nest), 也就是在虚拟机中运行虚拟机. 容器也可以套娃, 比如 Docker in Docker, Podman in Podman, Podman in Docker 等. 容器和虚拟机也可以互相套娃…

【云原生之kubernetes实战】k8s环境中部署Nginx服务

【云原生之kubernetes实战】k8s环境中部署Nginx服务 一、Nginx介绍1.1 Nginx简介1.2 Nginx特点1.3 Nginx使用场景二、本次实践介绍2.1 本次实践简介2.2 本次环境规划三、检查k8s环境3.1 检查工作节点状态3.2 检查系统pod状态四、部署storageclass(可选)4.1 配置NFS服务器4.2 …

Leetcode42接雨水(单调栈)

题目 题目链接 解法一 求出前缀最大和后缀最大&#xff0c;用两者较小值减去当前高度&#xff0c;累加即可&#xff0c;这个思路容易想到&#xff0c;这里不赘述 class Solution { public:int trap(vector<int>& height) {vector<int> preMx(height.size()…

故障检测(同相/反相放大器+电压跟随器)+概念(开环/闭环增益+增益的频率依赖性+3dB/单位增益带宽+增益-频率依赖性+相移)

2024-8-28&#xff0c;星期二&#xff0c;20:19&#xff0c;天气&#xff1a;阴雨&#xff0c;心情&#xff1a;晴。今天没什么事情发生&#xff0c;继续学习。 今天完成了第六章运算放大器的学习&#xff0c;开始了第七章运算放大器响应的学习&#xff0c;主要学习内容为&…

毕 业 设 计(论 文)远程接入企业网络规划与设计

毕 业 设 计&#xff08;论 文&#xff09; 远程接入企业网络规划与设计 毕业设计论文中文摘要 随着Internet技术的日益普及&#xff0c;网络技术的飞速发展&#xff0c;企业信息化工作越来越受到重视&#xff0c;进入二十一世纪后&#xff0c;企业信息化不再满足于个人或单…

使用WireShark的tshark命令,在window系统Cmd命令行抓包(附环境变量的设置)

WireShark在window系统Cmd命令行的抓包应用 工作中&#xff0c;有时候会遇到抓特定数据包的情况&#xff0c;但是却不知道这个特定数据包什么时候出现。因此就需要有设备值守抓包&#xff0c;这时就可以使用wireshark提供的tshark命令抓包。 一、抓包需求&#xff1a; 例如&am…

【虚拟化】KVM常用命令操作(virsh虚拟机常用操作之开关|连接|自启|克隆|快照)

目录 ​编辑一、KVM概述 1.1 KVM工具栈 1.2 libvirt架构概述 二、使用virsh管理虚拟机 三、kvm基本功能管理 1.帮助命令 2.KVM的配置文件存放目录 3.查看虚拟机状态 4.虚拟机关机与开机 5.强制虚拟机系统关闭电源 6.通过配置文件启动虚拟机系统 7.修改虚拟机配置文…

【项目实战】MobileNetV3 医学病理识别+不使用全连接预测+迁移学习+附代码数据教程

目录 简言. 环境搭建&快速开始 1. 数据集制作 2、训练教程 2.1 迁移学习 2.2 卷积自编码器,不使用全连接 2.3训练 3 实际推理 结果: 简言. 环境搭建&快速开始 大家好,我是cv君,今天带来以前的干货,mobilenet v3的优化,能在医学病理分类中得到优异准确率…

C++语法基础(一)

第一个C程序 1. <iostream>&#xff08;C&#xff09; <iostream> 是 C 标准库中的头文件&#xff0c;用于处理输入输出操作。它提供了基于流&#xff08;stream&#xff09;的输入输出机制。 特点&#xff1a; 面向对象&#xff1a;C 中的输入输出操作是基于流…

力扣面试经典算法150题:加油站

加油站 今天的题目是力扣面试经典150题中的数组的中等难度题&#xff1a;加油站。 题目链接&#xff1a;https://leetcode.cn/problems/gas-station/description/?envTypestudy-plan-v2&envIdtop-interview-150 问题描述 在一条环路上有 n 个加油站&#xff0c;其中第 i…

pySCENIC报错、解决和完整流程(IOS系统)

该文首发于生信技能树&#xff0c;推文链接&#xff1a;https://mp.weixin.qq.com/s/W23Reg6Hi4XWxpMvfctP8g 明白了基因调控网络的基础知识之后&#xff0c;就可以尝试实际操作一下SCENIC分析。 基因调控网络的基础知识可见推文&#xff1a;https://mp.weixin.qq.com/s/sL_8…