目录

内核源码及路径

CONFIG_DMA_DECLARE_COHERENT

DTS示例配置

dma_direct_alloc

特殊属性快速路径 (DMA_ATTR_NO_KERNEL_MAPPING)

主体流程

1. 内存分配核心

2. 地址转换

3. 缓存一致性处理

 映射

attrs不同属性的cache处理

 cache的标示(ARM64)

dma_alloc_attrs

总结


   前述文章中,我们介绍了分配内存的几种方式以及着重介绍mmap方式的一个参数,本文介绍分配内存的过程。

内核源码及路径

路径函数及宏  功能
kernel\dma\mapping.cdma_alloc_attrs
kernel\kernel\dma\coherent.c

dma_declare_coherent_memory

dma_alloc_from_dev_coherent  DMA设备一致性内存分配

\kernel\kernel\dma\direct.cdma_direct_alloc  DMA CMA内存分配
\kernel\include\linux\dma-mapping.hdma_alloc_coherent
  arch\arm64\mm   
 
arch_dma_prep_coherent 分配内存页后,将内存页转换虚拟地址并调用__dma_flush_area
\kernel\arch\arm64\mm\cache.S__dma_flush_area 功能clean & invalidate D / U line
I:\rk3588\kernel\arch\arm64\include\asm\pgtable.hpgprot_syscached 功能Mark the prot value as outer cacheable and inner non-cacheable

  

CONFIG_DMA_DECLARE_COHERENT

声明设备默认支持硬件一致性DMA(Hardware-Coherent DMA),使得内核在分配DMA缓冲区时,自动假设设备与CPU缓存保持一致,无需软件维护同步。

场景启用 CONFIG_DMA_DECLARE_COHERENT不启用
内存分配dma_alloc_coherent() 返回硬件一致性内存默认返回非一致性内存(需手动同步)
同步操作无需调用 dma_sync_*必须显式同步缓存
设备树/ACPI配置需设备节点包含 dma-coherent 属性无特殊要求
性能更高(无同步开销)较低(依赖软件同步

如何验证硬件是否真正支持一致性?

  • 检查设备手册是否声明支持(如ARM的ACP或PCIe的ATS)。在驱动中故意省略dma_sync_*,测试数据传输是否正常。

DTS示例配置

reserved-memory {#address-cells = <1>;#size-cells = <1>;ranges;my_coherent_pool: coherent_pool@0x10000000 {compatible = "shared-dma-pool";reg = <0x10000000 0x400000>; // 4MB区域no-map;};
};my_device: my_device@0 {compatible = "vendor,coherent-device";memory-region = <&my_coherent_pool>; // 关联内存区域dma-coherent;
};

基于上述的DTS与内核配置,在分配一致性内存时,从上述DTS中的区域分配,而非从cma分配。例如我们可以将高地址内存预留出来,通过上述方式给我们的视频接口使用。

此外可以在驱动中调用接口 dma_declare_coherent_memory将保留的物理内存与设备关联。进而绕开cma

dma_direct_alloc

特殊属性快速路径 (DMA_ATTR_NO_KERNEL_MAPPING)

if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) && !force_dma_unencrypted(dev)) {page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));return page; // 返回 page 结构而非虚拟地址
}

应用场景:当内核不需要访问该内存时(如纯设备间DMA)

主体流程

 

1. 内存分配核心

page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);

  • 使用 CMA 或 buddy 分配器获取物理连续页

  • 明确排除 __GFP_ZERO 以优化性能(后续手动清零)

2. 地址转换

*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
  • 将物理地址转换为设备可识别的 DMA 地址

  • 处理可能的地址偏移(如 SMMU 前向窗口)

3. 缓存一致性处理

arch_dma_prep_coherent(page, size);
  • 确保 CPU 缓存与内存一致。这里是在分配内存后,被使用前,进行的一致性处理。架构特定实现(如 ARM 的 cache 刷写)

 映射

主要属性控制,如上一篇所述

attrs不同属性的cache处理

/** Return the page attributes used for mapping dma_alloc_* memory, either in* kernel space if remapping is needed, or to userspace through dma_mmap_*.*/
pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs)
{if (force_dma_unencrypted(dev))prot = pgprot_decrypted(prot);if (dev_is_dma_coherent(dev))return prot;
#ifdef CONFIG_ARCH_HAS_DMA_WRITE_COMBINEif (attrs & DMA_ATTR_WRITE_COMBINE)return pgprot_writecombine(prot);
#endifif (attrs & DMA_ATTR_SYS_CACHE_ONLY ||attrs & DMA_ATTR_SYS_CACHE_ONLY_NWA)return pgprot_syscached(prot);return pgprot_dmacoherent(prot);
}#define pgprot_dmacoherent(prot)	pgprot_noncached(prot)  //关闭cache

 

 cache的标示(ARM64)

/*
 * Mark the prot value as outer cacheable and inner non-cacheable. Non-coherent
 * devices on a system with support for a system or last level cache use these
 * attributes to cache allocations in the system cache.
 */


#define pgprot_syscached(prot) \__pgprot_modify(prot, PTE_ATTRINDX_MASK, \PTE_ATTRINDX(MT_NORMAL_iNC_oWB) | PTE_PXN | PTE_UXN)

 

dma_alloc_attrs

     内核分配并映射内存的流程分为三个主体,本篇介绍了左边两个。至于smmu iommu的映射目前不涉及。 

     顺便提一句 dma_alloc_coherent,因为很多教程里面都提这个接口,这个接口内部实际封装了attrs这个接口,而仅仅把attrs属性设置了0,根据上述的分析,即映射到内核时,其页面被设置了no cache的属性,即关闭了cache。

static inline void *dma_alloc_coherent(struct device *dev, size_t size,dma_addr_t *dma_handle, gfp_t gfp)
{return dma_alloc_attrs(dev, size, dma_handle, gfp,(gfp & __GFP_NOWARN) ? DMA_ATTR_NO_WARN : 0);
}

总结

    分析了dma 分配的流程,分为三种情况。

    1) dma 设备支持一致性,从设备占用的DDR中分配内存,不走cma的接口。

     2) 直接进行物理地址的映射。

     3) iommu的情况。  dma_map_ops的实现

    通过上述流程可知,dma分配的接口可以分配cache的和no cached,具体哪些驱动采用了cached呢?

     另外既然如此,流式映射的接口,诸如dma_map_single为什么不用dma_alloc_attrs 封装呢?

因为dma_map_single为单纯建立映射,并不分配内存;而dma_alloc_attrs先分配了页啊。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 大视界:基于 Java 的大数据可视化在智慧城市能源消耗动态监测与优化决策中的应用(2025 实战全景)

​​摘要​​在“双碳”战略深化落地的 2025 年&#xff0c;城市能源管理面临 ​​实时性​​、​​复杂性​​、​​可决策性​​ 三重挑战。本文提出基于 Java 技术栈的智慧能源管理平台&#xff0c;融合 ​​Flink 流处理引擎​​、​​Elasticsearch 实时检索​​、​​ECh…

微信小程序控制空调之微信小程序篇

目录 前言 下载微信开发者工具 一、项目简述 核心功能 技术亮点 二、MQTT协议实现详解 1. MQTT连接流程 2. 协议包结构实现 CONNECT包构建 PUBLISH包构建 三、核心功能实现 1. 智能重连机制 2. 温度控制逻辑 3. 模式控制实现 四、调试系统实现 1. 调试信息收集…

spring boot 详解以及原理

Spring Boot 是 Spring 框架的扩展&#xff0c;旨在简化 Spring 应用的开发和部署。它通过自动配置和约定优于配置的原则&#xff0c;让开发者能够快速搭建独立运行的、生产级别的 Spring 应用。以下是 Spring Boot 的详细解析和工作原理&#xff1a; 一、Spring Boot 的核心特…

3.4 ASPICE的系统架构与设计过程

ASPICE&#xff08;Automotive SPICE&#xff09;在系统架构与设计过程中&#xff0c;强调了在汽车软件开发中确保系统稳定性、可靠性和安全性的重要性。以下是ASPICE在系统架构与设计过程中的主要内容和步骤&#xff1a;系统架构设计准备阶段&#xff1a;需求分析&#xff1a;…

自助KTV选址指南与优化策略

选址四大铁律&#xff08;硬性条件&#xff09;产权合规&#xff1a;纯商业产权消防双通道&#xff1a;必须通过消防验收远离敏感区&#xff1a;距居民区、学校、医院等200米以上面积达标&#xff1a;满足包厢规划需求选址核心逻辑&#xff08;优先级排序&#xff09;要素关键策…

深度学习11(调参设参+批标准化)

调参技巧对于调参&#xff0c;通常采用跟机器学习中介绍的网格搜索一致&#xff0c;让所有参数的可能组合在一起&#xff0c;得到N组结果。然后去测试每一组的效果去选择。 假设我们现在有两个参数 α&#xff1a;0.1, 0.01, 0.001β&#xff1a;0.8, 0.88. 0.9这样会有9种…

Python 中 enumerate(s) 和 range() 的对比

一、enumerate(s) 是什么&#xff1f;for i, c in enumerate(s):...enumerate(s) 是一个内置函数&#xff0c;用于在遍历可迭代对象时&#xff0c;同时获得元素的索引和值。它返回的是一个**(index, element)** 元组。常用于遍历字符串、列表、元组等时&#xff0c;如果你既想拿…

【一起来学AI大模型】RAG系统流程:查询→向量化→检索→生成

RAG&#xff08;Retrieval-Augmented Generation&#xff09;系统核心流程非常精准&#xff1a; 查询 → 向量化 → 检索 → 生成 这是 RAG 实现“知识增强”的关键路径。下面我们结合具体组件&#xff08;如 ChromaDB、LangChain 检索器&#xff09;详细拆解每个步骤&#xff…

图像硬解码和软解码

一、什么是图像解码&#xff1f; 图像解码是指将压缩编码&#xff08;如 JPEG、PNG、WebP、H.264/AVC、H.265/HEVC 等格式&#xff09;的图像或视频数据还原为原始像素数据&#xff08;如 RGB、YUV&#xff09;的过程。 解码可以在CPU&#xff08;软件解码&#xff09;或专用硬…

Camera2API笔记

1. 常用对象CameraManager 相机服务。用于获取相机对象和相机信息。CameraDevices 相机设备。负责连接相机、创建会话、生成拍摄请求&#xff0c;管理相机生命周期。CameraCaptureSession 相机拍摄会话。用于预览和拍摄。一个相机只能有一个活跃会话。打开新会话时&#xff0c;…

触控屏gt1947

比较器判断是否翻转&#xff0c;周期控制器负责控制周期&#xff08;period&#xff09;。sample采器有多个影子&#xff0c;每次采样查看是否到了翻转的时候。

DNS和ICMP

域名介绍在网络通信中&#xff0c;需要用到ip加port&#xff0c;但是ip并不方便记忆&#xff0c;于是我们常用域名来对应一个ip例如&#xff1a;www.baidu.com 对应 156.36.56.98&#xff08;随便写的&#xff09;com: 一级域名. 表示这是一个企业域名. 同级的还有 "…

2022 年 12 月青少年软编等考 C 语言六级真题解析

目录 T1. 电话号码T2. 区间合并T3. 扑克牌排序T4. 现代艺术思路分析T1. 电话号码 题目链接:SOJ D1137 此题为 2021 年 12 月六级第一题原题,见 2021 年 12 月青少年软编等考 C 语言六级真题解析中的 T1。 T2. 区间合并 题目链接:SOJ D1112 此题为 2021 年 9 月六级第三…

无锁队列:从零构建生产者-消费者数据结构

高性能无锁队列&#xff1a;从零构建生产者-消费者数据结构 问题的本质 生产者-消费者问题的核心挑战不在于数据传输&#xff0c;而在于协调。传统的锁机制虽然简单&#xff0c;但带来了三个致命问题&#xff1a; 性能瓶颈&#xff1a;线程阻塞和上下文切换优先级反转&#xff…

JAVA面试宝典 -《Spring IOC核心:Bean生命周期全解析》

文章目录&#x1f331; 《Spring IOC核心&#xff1a;Bean生命周期全解析》1️⃣ 引言&#xff1a;Bean 生命周期为什么重要&#xff1f;2️⃣ Bean 生命周期概览&#xff08;图示 简要说明&#xff09;3️⃣ 每一步详细解析&#xff08;源码理解 示例&#xff09;3.1 &#…

Python 类型注解实战:`Optional` 与安全数据处理的艺术

Python 类型注解实战&#xff1a;Optional 与安全数据处理的艺术 在 Python 开发中&#xff0c;类型注解&#xff08;Type Hints&#xff09;已经成为现代 Python 项目的标配。本文将通过一个真实的认证令牌获取函数 get_auth_token()&#xff0c;深入解析 Optional 类型的应用…

深入MyBatis:CRUD操作与高级查询实战

引言 在上一篇文章中&#xff0c;我们介绍了Mybatis的基础使用。 如有需要请移步查看&#xff1a; MyBatis入门&#xff1a;快速掌握用户查询实战https://blog.csdn.net/qq_52331401/article/details/149270402?spm1001.2014.3001.5502 今天&#xff0c;我将通过一个完整的…

Flink DataStream API详解(二)

一、引言 咱两书接上回&#xff0c;上一篇文章主要介绍了DataStream API一些基本的使用&#xff0c;主要是针对单数据流的场景下&#xff0c;但是在实际的流处理场景中&#xff0c;常常需要对多个数据流进行合并、拆分等操作&#xff0c;以满足复杂的业务需求。Flink 的 DataS…

Unity3D游戏线上崩溃排查指南

前言 排查Unity3D线上游戏崩溃是个系统工程&#xff0c;需要结合工具链、日志分析和版本管理。以下是详细的排查指南和关键步骤&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;希望大家可以点击进来一起交流一下开发经验呀&#xff01; 一、崩溃信息收…

DPDK性能优化实践:系统级性能调优的方法论与实战(一套通用的方法论)

性能优化的挑战与现实困境 在高性能网络处理领域&#xff0c;性能优化往往被视为一门“玄学”而非科学。许多开发者在面对性能瓶颈时&#xff0c;要么盲目追求单一指标的极致优化&#xff0c;要么采用"试错法"进行零散的局部调优&#xff0c;结果往往是投入大量精力却…