CMA简介【转】

转自:https://blog.csdn.net/jasonactions/article/details/123085907?spm=1001.2014.3001.5502

kernel: 5.10
arch: arm64

1. 前言
CMA是一段连续的内存区域,它的所有页面都是可迁移类型,平时在不需要大块连续内存的时候,这段CMA区域可供系统或其它驱动使用,在驱动需要大块内存的时候,已占用的部分需要迁移出去,空闲出大块连续内存以供分配。

2. 配置CMA区域
有三种方式可以配置CMA区域大小,dts,commdline, 内核的配置项,优先级分别是dts > commandline > 内核配置项,分别举例如下:

In the device tree:
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0 0x3c000000>;
alloc-ranges = <0 0x96000000 0 0x3c000000>;
linux,cma-default;
};

On the kernel command line:
cma=256MB
1
In the kernel configuration:
CONFIG_CMA_SIZE_MBYTES=960
CONFIG_CMA_SIZE_PERCENTAGE=25
# CONFIG_CMA_SIZE_SEL_MBYTES is not set
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
CONFIG_CMA_SIZE_SEL_MIN=y
# CONFIG_CMA_SIZE_SEL_MAX is not set

3. CMA API
对于用户来讲,使用cma仍然会采用原有的dma接口来调用,这对用户是感知不到的,接口可参考DMA-API.txt

4. CMA的工作机制
首先必须在cmdline或dts或内核配置项中为cma预留区域;

arm64_memblock_init中会解析预留区域,将这部分区域添加到memlbok.reserved,这其中包含了CMA定义的区域,这部分区域会被初始化给cma;

bootmem_init->sparse_init会为所有的物理内存bank创建page;

初始化时cma_init_reserved_areas->cma_activate_area->init_cma_reserved_pageblock 将cma区域的空闲page给buddy,并标注这些pageblock的属性为MIGRATE_CMA;

mm_init->mem_init->memblock_free_all->free_low_memory_core_early 只是释放>memblock.memory的空闲空间给buddy,且排除所有的memblock.reserved区域

通过dma接口申请连续物理内存,就可能会从CMA中申请,如果发现CMA区域已经被其它用户申请则需要将这些页面进行迁移
参考文档
A deep dive into CMA
CMA模块学习笔记
Contiguous Memory Allocator - CMA (Linux)
DMA-API.txt
DMA-API-HOWTO.txt
————————————————
版权声明:本文为CSDN博主「HZero.chen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jasonactions/article/details/123085907

posted @ 2022-10-20 09:55  Sky&Zhang  阅读(463)  评论(0编辑  收藏  举报