CMA是什么
在我们使用ARM等嵌入式Linux系 统的时候,一个头疼的问题是GPU,Camera,HDMI等都需要预留大量连续内存,这部分内存平时不用,但是一般的做法又必须先预留着。通过CMA机制,我们可以做到不预留内存,这些内存平时是可用的,只有当需要的时候才被分配给Camera,HDMI等设备。(本段纯属百度,阅完即可,不必惦记)
如果对CMA的实现过程有兴趣可以百度或者google。我在这里给大家来点实在的!!
CMA段内存到底是reserved 还是 memory的?内核下free统计值是否包含CMA内存?
Cma段内存既是reserved又是memory的。但更像是一段普通的memory。
start_kernel -> setup_arch -> arm_memblock_init -> dma_contiguous_reserve -> dma_declare_contiguous
在dma_declare_contiguous函数中,调用__memblock_alloc_base得到内存。这里只是将内存给扣了出来。
内存扣出来做什么?当然是留出来用哦!但CMA初始化中做了一个有趣的动作!
void __init init_cma_reserved_pageblock(struct page *page)
{
unsigned i = pageblock_nr_pages;
struct page *p = page;
do {
__ClearPageReserved(p);
set_page_count(p, 0);
} while (++p, --i);
set_page_refcounted(page);
set_pageblock_migratetype(page, MIGRATE_CMA);
__free_pages(page, pageblock_order);
totalram_pages += pageblock_nr_pages;
#ifdef CONFIG_HIGHMEM
if (PageHighMem(page))
totalhigh_pages += pageblock_nr_pages;
#endif
}
#endif
在这个函数中,先将CMA区中的page设置为MIGRATE_CMA,然后放入伙伴系统中,等待用户使用(NOTE:MIGRATE_CMA是伙伴系统中页属性的概念,所以CMA区也只是伙伴系统中的一个概念,不是一个ZONE)。
这样一初始化后,free统计时也会将CMA区的内存统计进去
用户态程序何时分配MIGRATE_CMA页框?
首先让我们看下标志位__GFP_MOVABLE的定义
#define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE)
#define ___GFP_MOVABLE 0x08u
这个标志位在很多地方都有使用,如磁盘文件系统分配页缓存、用户态程序分配堆栈空间等。
那我们在来看下,此类标志位是怎么影响页面分配的?
分配页面的其余流程的先不做分析&#x