Linux下不启用CONFIG_CMA分配8MB物理连续内存问题咨询
不启用CONFIG_CMA分配8MB物理连续内存的解决方案
可行性说明
不启用CONFIG_CMA是可以分配超过4MB的物理连续内存的,你用dma_alloc_coherent分配超过4MB就失败,通常是两个核心原因:
- 内核默认的伙伴系统最大可分配连续内存块上限为4MB(对应4KB页大小下,阶数为10,2^10 * 4KB = 4MB)
- 系统运行后内存产生碎片化,没有足够大的连续物理页块可用
可行解决方法
- 启动阶段预留物理内存(最稳妥,无碎片化影响)
修改内核启动参数,添加内存预留配置,比如你的设备总内存为4GB,需要预留8MB连续内存,就设置启动参数为mem=4088M,预留出最高的8MB物理地址空间。后续在驱动中通过ioremap映射这段预留地址即可使用,如需适配DMA场景,只要保证预留地址在你的设备DMA寻址范围内即可,完全不需要启用CMA。 - 调整内核最大分配阶参数
修改内核配置项CONFIG_FORCE_MAX_ZONEORDER,将默认值10调整为11(对应4KB页大小下最大可分配8MB连续内存)。该方法仅适合在系统刚启动、内存未碎片化的场景使用,系统长时间运行后仍有分配失败的概率。 - 优化
dma_alloc_coherent分配标记
如果你当前调用dma_alloc_coherent时使用的是GFP_ATOMIC等不可睡眠的分配标记,且调用场景允许阻塞睡眠,可以将分配标记替换为GFP_KERNEL | __GFP_DIRECT_RECLAIM,内核会触发直接内存回收、页合并操作来整理出连续物理块,大幅提高大内存分配的成功率。 - (可选优化方案)如果后续可以调整内核配置,建议启用
CONFIG_CMA,CMA预留的内存平时可被用户态程序使用,DMA需要分配连续内存时会迁移非独占页来腾出连续块,内存利用率远高于直接启动预留内存的方案。
内容的提问来源于stack exchange,提问作者Anish Poduval
相关产品推荐
相关产品推荐

