Linux内核:内存管理——CMA预留内存

本文介绍了Linux内核中的Contiguous Memory Allocator(CMA),它用于分配连续的大块内存,特别是在设备驱动需要DMA时。CMA会在设备驱动不使用时管理内存,当设备需要时,会进行页面迁移或丢弃。CMA的创建、添加到buddy系统、分配和释放过程以及如何处理DMA和缓存一致性问题都有详细阐述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

平时看/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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值