平时看/proc/meminfo中,总能看到CMA的身影,且好像总是被用光了。他是做什么的呢,为啥作为预留内存能用的干干净净呢~? 一起看下!
CmaTotal: 438272 kB
CmaFree: 0 kB
Contiguous Memory Allocator, 连续内存分配器,用于分配连续的大块内存。
预留了一片物理内存区域:
- 设备驱动不用时,内存管理系统将该区域用于分配和管理可移动类型页面;
- 设备驱动使用时,用于连续内存分配,此时已经分配的页面需要进行迁移或丢弃;此外,CMA分配器还可以与DMA子系统集成在一起,使用DMA的设备驱动程序无需使用单独的CMA API。
msm-4.19/kernel/dma/contiguous.c
=> struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
unsigned int align, gfp_t gfp_mask);
=> cma_alloc(dev_get_cma_area(dev), count, align, no_warn);
DMA释放也是
=> bool dma_release_from_contiguous(struct device *dev, struct page *pages,
int count);
驱动直接从DMA分配内存就不用页表了,但是如果给buddy使用,估计还是要MMU转换的。
结构体定义: msm-4.19/mm/cma.h
struct cma {
unsigned long base_pfn; //CMA区域物理地址的起始页帧号;
unsigned long count; //CMA区域总体的页数;
unsigned long *bitmap; //描述页的分配情况;
unsigned int order_per_bit; /* Order of pages represented by one bit */
//位图中每个bit描述的物理页面的order值,其中页面数为2^order值;
struct mutex lock;
#ifdef CONFIG_CMA_DEBUGFS
struct hlist_head mem_head;
spinlock_t mem_head_lock;
#endif
const char *name;
};
extern struct cma cma_areas[MAX_CMA_AREAS];
extern unsigned cma_area_count;
CMA创建
从dtsi文件中解析,像高通就放在android/vendor/xxxx/proprietary/devicetree-4.19/xxxx/kona.dtsi
/* global autoconfigured region for contiguous alloca