淺淺講解下Linux內(nèi)存管理之CMA
說明:
Kernel版本:4.14
ARM64處理器,Contex-A53,雙核
使用工具:Source Insight 3.5, Visio
1. 概述
Contiguous Memory Allocator, CMA
,連續(xù)內(nèi)存分配器,用于分配連續(xù)的大塊內(nèi)存。CMA分配器
,會Reserve一片物理內(nèi)存區(qū)域:
設備驅(qū)動不用時,內(nèi)存管理系統(tǒng)將該區(qū)域用于分配和管理可移動類型頁面;
設備驅(qū)動使用時,用于連續(xù)內(nèi)存分配,此時已經(jīng)分配的頁面需要進行遷移;
此外,CMA分配器
還可以與DMA子系統(tǒng)
集成在一起,使用DMA的設備驅(qū)動程序無需使用單獨的CMA API
。
2. 數(shù)據(jù)結構
內(nèi)核定義了struct cma
結構,用于管理一個CMA區(qū)域
,此外還定義了全局的cma數(shù)組
,如下:
base_pfn
:CMA區(qū)域物理地址的起始頁幀號;count
:CMA區(qū)域總體的頁數(shù);*bitmap
:位圖,用于描述頁的分配情況;order_per_bit
:位圖中每個bit
描述的物理頁面的order
值,其中頁面數(shù)為2^order
值;
來一張圖就會清晰明了:

【文章福利】小編推薦自己的Linux內(nèi)核技術交流群:【749907784】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ? ??


3. 流程分析
3.1 CMA區(qū)域創(chuàng)建
3.1.1 方式一 根據(jù)dts來配置
之前的文章也都分析過,物理內(nèi)存的描述放置在dts
中,最終會在系統(tǒng)啟動過程中,對dtb
文件進行解析,從而完成內(nèi)存信息注冊。
CMA
的內(nèi)存在dts
中的描述示例如下圖:

在dtb
解析過程中,會調(diào)用到rmem_cma_setup
函數(shù):

3.1.2 方式二 根據(jù)參數(shù)或宏配置
可以通過內(nèi)核參數(shù)或配置宏,來進行CMA區(qū)域的創(chuàng)建,最終會調(diào)用到cma_declare_contiguous
函數(shù),如下圖:

3.2 CMA添加到Buddy System
在創(chuàng)建完CMA區(qū)域
后,該內(nèi)存區(qū)域成了保留區(qū)域,如果單純給驅(qū)動使用,顯然會造成內(nèi)存的浪費,因此內(nèi)存管理模塊會將CMA區(qū)域
添加到Buddy System
中,用于可移動頁面的分配和管理。CMA區(qū)域
是通過cma_init_reserved_areas
接口來添加到Buddy System
中的。
core_initcall(cma_init_reserved_areas);
core_initcall
宏將cma_init_reserved_areas
函數(shù)放置到特定的段中,在系統(tǒng)啟動的時候會調(diào)用到該函數(shù)。

3.3?CMA分配/釋放
CMA分配,入口函數(shù)為
cma_alloc
:

CMA釋放,入口函數(shù)為
cma_release
:函數(shù)比較簡單,直接貼上代碼
3.4?DMA使用
代碼參考driver/base/dma-contiguous.c
,主要包括的接口有:
在上述的接口中,實際調(diào)用的就是cma_alloc/cma_release
接口來實現(xiàn)的。
整體來看,CMA分配器還是比較簡單易懂,也不再深入分析。
原文作者:LoyenWang
