Linux内存管理:CMA(连续内存分配)(DMA)
目录
什么是CMA
数据结构
CMA区域 cma_areas 的创建
dts方式
command line方式
将CMA区域添加到Buddy System
CMA分配
《Linux内存管理:什么是CMA(contiguous memory allocation)连续内存分配器?可与DMA结合使用》
《Linux内存管理:CMA(连续内存分配)》
《Linux 内存管理之CMA》
什么是CMA
CMA是reserved的一块内存,用于分配连续的大块内存。
- 当设备驱动不用时,内存管理系统将该区域用于分配和管理可移动类型页面;
- 当设备驱动使用时,此时已经分配的页面需要进行迁移,又用于连续内存分配;
其用法与DMA子系统结合在一起充当DMA的后端,具体可参考《没有IOMMU的DMA操作》。
数据结构
struct cma {//CMA区域物理地址的起始页帧号unsigned long base_pfn; //CMA区域总体的页数unsigned long count;//位图,用于描述页的分配情况unsigned long *bitmap;//位图中每个bit描述的物理页面的order值,其中页面数为2^order值unsigned int order_per_bit; /* Order of pages represented by one bit */struct mutex lock;
#ifdef CONFIG_CMA_DEBUGFSstruct hlist_head mem_head;spinlock_t mem_head_lock;
#endifconst char *name;
};extern struct cma cma_areas[MAX_CMA_AREAS];
extern unsigned cma_area_count;
bitmap来管理其内存的分配,0表示free,1表示已经分配。
如果order_per_bit等于0,表示按照一个一个page来分配和释放,如果order_per_bit等于1,表示按照2个page组成的block来分配和释放,以此类推。
count说明该cma_areas内存有多少个page。它和order_per_bit一起决定了bitmap指针指向内存的大小。
base_pfn定义了该cma_areas的起始page frame number,base_pfn和count一起定义了该cma_areas在内存中的范围。
CMA区域 cma_areas 的创建
CMA区域的创建有两种方法,一种是通过dts的reserved memory,另外一种是通过command line参数和内核配置参数。
dts方式
reserved-memory {/* global autoconfigured region for contiguous allocations */linux,cma {compatible = "shared-dma-pool";reusable;size = <0 0x28000000>;alloc-ranges = <0 0xa0000000 0 0x40000000>;linux,cma-default;};
};
device tree中可以包含reserved-memory node,系统启动的时候会打开rmem_cma_setup
RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
command line方式
cma=nn[MG]@[start[MG][-end[MG]]]
static int __init early_cma(char *p)
{pr_debug("%s(%s)\n", __func__, p);size_cmdline = memparse(p, &p);if (*p != '@') {/*if base and limit are not assigned,set limit to high memory bondary to use low memory.*/limit_cmdline = __pa(high_memory);return 0;}base_cmdline = memparse(p + 1, &p);if (*p != '-') {limit_cmdline = base_cmdline + size_cmdline;return 0;}limit_cmdline = memparse(p + 1, &p);return 0;
}
early_param("cma", early_cma);
系统在启动的过程中会把cmdline里的nn, start, end传给函数dma_contiguous_reserve,流程如下:
setup_arch--->arm64_memblock_init--->dma_contiguous_reserve->dma_contiguous_reserve_area->cma_declare_contiguous
将CMA区域添加到Buddy System
为了避免这块reserved的内存在不用时候的浪费,内存管理模块会将CMA区域添加到Buddy System中,用于可移动页面的分配和管理。CMA区域是通过cma_init_reserved_areas接口来添加到Buddy System中的。
static int __init cma_init_reserved_areas(void)
{int i;for (i = 0; i < cma_area_count; i++) {int ret = cma_activate_area(&cma_areas[i]);if (ret)return ret;}return 0;
}
core_initcall(cma_init_reserved_areas);
其实现比较简单,主要分为两步:
把该页面设置为MIGRATE_CMA标志
通过__free_pages将页面添加到buddy system中
CMA分配
《没有IOMMU的DMA操作》里讲过,CMA是通过cma_alloc分配的。cma_alloc->alloc_contig_range(..., MIGRATE_CMA,...),向刚才释放给buddy system的MIGRATE_CMA类型页面,重新“收集”过来。
用CMA的时候有一点需要注意:
也就是上图中黄色部分的判断。CMA内存在分配过程是一个比较“重”的操作,可能涉及页面迁移、页面回收等操作,因此不适合用于atomic context。比如之前遇到过一个问题,当内存不足的情况下,向U盘写数据的同时操作界面会出现卡顿的现象,这是因为CMA在迁移的过程中需要等待当前页面中的数据回写到U盘之后,才会进一步的规整为连续内存供gpu/display使用,从而出现卡顿的现象。
https://mp.weixin.qq.com/s?__biz=MzIxMjE1MzU4OA==&mid=2648924073&idx=1&sn=bbaf5db820a1ef77b4b0e4190a816040&chksm=8f5d9a32b82a132499513fc05e637257aa7883010207d3593dd292f46cd2f69bbf4d0f32154f&token=1349594618&lang=zh_CN&scene=25#wechat_redirect
Linux内存管理:CMA(连续内存分配)(DMA)相关推荐
- Linux内核机制总结内存管理之连续内存分配器(二十七)
文章目录 1 连续内存分配器 1.1 使用方法 1.2 技术原理 重要:本系列文章内容摘自<Linux内核深度解析>基于ARM64架构的Linux4.x内核一书,作者余华兵.系列文章主要用 ...
- 操作系统【三】内存管理基础+连续内存分配
内存的基础知识 内存分为按字节编址(8位)和字编制(不同计算机不一样,64位计算机就是64位,即8个字节) 相对地址=逻辑地址 绝对地址=物理地址 从逻辑地址到物理地址的转换由装入解决. 装入的三种方 ...
- 【清华大学】操作系统 陈渝 Part3 ——物理内存管理 之 连续内存分配
[清华大学]操作系统 陈渝 Part3 --物理内存管理 之 连续内存分配 3.1计算机体系结构及内存分层 计算机体系机构 内存体系层次 管理内存方法 3.2地址空间 & 地址生成 地址空间定 ...
- linux进程管理内存管理,Linux专业知识四:Linux系统进程管理及查看内存
本文主讲Linux专业知识之Linux系统进程管理及查看内存的情况,以Redhat RHEL7操作系统为例. 一.进程 程序与进程:程序是静态的(文件),进程是动态的(运行的程序). 进程和线程:一个 ...
- 【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )
文章目录 一.禁止 / 开启内核抢占 与 方法保护临界区 二.编译器优化屏障 三.preempt_disable 禁止内核抢占 源码 四.preempt_enable 开启内核抢占 源码 一.禁止 / ...
- Java内存管理:Java内存区域 JVM运行时数据区
Java内存管理:Java内存区域 JVM运行时数据区 在前面的一些文章了解到javac编译的大体过程.Class文件结构.以及JVM字节码指令. 下面我们详细了解Java内存区域:先说明JVM规范定 ...
- 属性与内存管理(属性与内存管理都是相互关联的)
<span style="font-size:18px;"> 属性与内存管理(属性与内存管理都是相互关联的)第一部分一,属性:属性是OC2.0之后出来的新语法,用来取代 ...
- JVM自动内存管理机制——Java内存区域(下)
一.虚拟机参数配置 在上一篇<Java自动内存管理机制--Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...
- 95-290-050-源码-内存管理-堆外内存与堆内内存概述
2.概述 Flink的内存管理器管理着用于排序.散列和缓存所需的内存.内存以相等大小的(Segments)表示,称为内存页.操作器通过请求多个内存页来分配内存.在Flink中,内存又分为堆内存和非 ...
- C++:内存管理:C++内存管理详解
C++语言内存管理是指:对系统的分配.创建.使用这一系列操作.在内存管理中,由于是操作系统内存,使用不当会造成很麻烦的后果.本文将从系统内存的分配.创建出发,并且结合例子来说明内存管理不当会造成的结果 ...
最新文章
- python绘制直方图显示数字_Python实现绘制双柱状图并显示数值功能示例
- SpringMVC框架 学习DAY_02 : 接收请求参数/向模板页面转发数据/重定向与转发 /Session
- 【Opencv实战】入门也能学会的「黑白上色」教程与手法核心~(收藏不谢)
- 《你不知道的JavaScript(上卷)》读书笔记
- 产品原型制作_早期制作原型如何帮助您设计出色的数字产品
- nodejs里的module.exports和exports
- JavaScript设计模式之构造器、模块和原型
- PHP基础知识系统复习
- php判断号码归属,php手机号码归属地查询
- 查看DBUS接口的工具: D-Feet
- RAC环境备份归档日志和RMAN恢复启动数据库
- OSC源创会(西安)图文总结
- 风云邀请成为IT168社区Silverlight版主
- 数字电子技术1:数字逻辑概论
- STEP7 V5.7安装包下载链接及安装教程
- macos系统里面,蓝牙鼠标偶尔卡顿,飘的问题
- 未来社区系统整体解决方案
- 西门子PLC 的特殊功能寄存器
- 神经网络模型优化方法(缓解过拟合)
- 服装厂仓库货存经常丢失?环境监测技术可助力仓库管理
热门文章
- c程序设计停车场收费管理系统_智能车牌识别停车收费管理系统
- Spring框架----自动按照类型注入的Autowired注解
- .Net Core 商城微服务项目系列(十四):分布式部署携程Apollo构建配置中心
- html 自定义标签的作用
- maven2打包不同jdk版本的包
- Struts+iBatis+Spring+mysql整合开发
- .Net 平台下的版本控制 --- Subversion(SVN)1.6.x
- vb中调用aspx页面
- linux链接时报未定义的引用,g ++链接或引用不与本地安装的库一起使用:未定义的引用...
- 地图旋转_如何使用万能地图下载器计算七参数