CMA,memory fragmation,compaction and migration

A reworked contiguous memory allocator

http://lwn.net/Articles/447405/

June 14, 2011

分配大块物理上连续内存的问题一直在被讨论。虚拟内存,天生的在系统上分散使用内存页,内核运行一会儿就只剩下很少的连续空闲的页。多年以来,内核开发者处理这个问题的方法是尽量避免对大的连续物理页分配的依赖。只有相当少的内核代码会尝试分配多于两个物理连续页。

最近,对大的连续页分配的需求持续增长。一个是大页和THP,另一个是有新麻烦的旧事:不能执行分散/聚集DMA操作的硬件。任何只能对物理连续区域做DMA的设备(没有IOMMU)需要一个物理连续的缓存。这种需求一般出现在相对来说比较低端的硬件,有人可能希望这种硬件会随着时间流逝越来越少。但我们现在看到的却是在获得能力提升的同时仍有连续DMA缓存需求的设备。举个例子,能获取全高清数据的视频捕捉引擎能执行很多转换,但它仍需要一个连续的缓存来保存结果。高清视频的出现加重了这个问题--这些物理连续的缓存比以前更大也更难分配了。
     大约一年以前,LWN发表过想要解决这个问题的CMA(contiguous memory allocator)补丁。这个补丁仍然遵循了传统的为满足大的分配请求的特殊目的而在启动的时候保留一部分内存的方法。几年以前,这种技术就已经被用在“bigphysarea”补丁中了,它简单的传给内核“mem=”启动参数来保留一部分物理内存不被使用。安卓的pmem驱动也是从一个保留的区域里分配内存。近20年的经验证明这种方法是可行的。不足是保留的内存就不能再被其他地方使用了;如果设备没有使用这部分内存,它就保持闲置。这种浪费越来越不被内核开发者,还有用户所欢迎。
     因为这个和其他的原因,CMA补丁未被合并。但是问题尚未解决,而现在也没人继续研究这两种方法。CMA补丁的最新版看起来有点不同,尽管还有一些问题需要解决,这个补丁还是有更大的机会合入主线的。
     CMA分配器仍然可以工作在一个保留的内存区域,但很明显这不是大家想要的操作模式。作为代替,新的CMA尝试维护内存区域,当有需求的时候连续的内存就会被创建。为实现这个目的,CMA依赖于内存管理代码中的“迁移类型”机制。
     每一个区里,页块中的页被标记为(或非)可移动的或可重声明的。可移动页一般是指页缓存或匿名页,它们通过页表和页缓存基树来被访问。只要页表和基树做相应的改动,这些页的内容就可以被移到其他地方。可重声明页是指可能会按要求返回给内核的页,它们保存数据结构比如inode缓存。不可移动页一般是内核直接指向的页,比如,通过kmalloc()获得的内存就不能在不破坏数据的情况下被移动。
     内存管理子系统会尽量把可移动页放在一起。(因为)如果想通过移动页来释放大块内存,只需要一个不可移动的页就可以摧毁所有的努力。通过把可移动页聚在一起,内核希望能按要求释放大块区域从而避免了这种问题。内存压缩代码依赖这些可移动页区域来工作。
     CMA通过增加一个新的“CMA”的迁移类型来扩展这种机制,它就像“movable”类型,但有两点不同。“CMA”类型是粘贴的,被标记为CMA的页就不会再被内核改变了。内存分配器不再从CMA区域分配不可移动页,并且只有在其它方法不可用的情况下才会为其他使用来分配CMA页。所以,被标记为用作CMA的内存区域只包含可移动页,并且有相对较多的空闲页。
     换句话说,被标记用作CMA的内存仍然可以被系统的其他部分使用,但有个限制是它只能包含可移动页。当一个驱动需要连续的内存时,CMA分配器会尝试从其中一个内存区域中分配足够的页来创建适当大小的连续缓存。如果那些内存区域的页是可移动的(现实中有时不会满足),驱动就会获得它需要的缓存。但这个缓存不需要时,内存可以被用作其他目的。
     有人可能会疑惑为何需要这种机制,内存压缩已经可以为THP创建大块物理连续的内存了。答案是DMA缓存有一些跟大页不同的需求。它们可能更大,举个例子,大多数架构上THP是2MB,而DMA缓存能达到10MB或更多。也有可能存在只能映射DMA缓存到特定内存范围的奇葩硬件--CMA的开发者Marek Szyprowski貌似就这有中硬件。最后,一个2MB的大页必须2MB对齐,而DMA缓存的对齐要求则更宽松一些。CMA分配器可以获得正好是需要的数量的内存(不用像伙伴分配器那样扩展到下一个2的幂的大小)而不用担心过度严格的对齐要求。
     CMA补丁提供了一些函数以方便创建内存区域和为特定范围的内存建立“内容/上下文”。然后有cm_alloc()和cm_free()来获取和释放缓存。但是,设备驱动最好不要直接调用CMA,而是把感知CMA集成到DMA函数里。当一个驱动调用比如dma_alloc_coherent()函数,CMA会被自动使用来满足要求。大多数情况下,这是就可以满足需求了。
剩余的关于CMA的疑问中的一个是关于如何在第一时间创建特殊区域。当前的方案是希望在系统的板文件(board file:系统相关的设置)中加入一些特殊的调用,这很像ARM的做事方法。社区的目的是不再使用板文件,所以得找其它方法。就像Arnd Bergmann指出的,把这些信息移到设备树也不是一个选项;这其实就是一个机制的问题。Arnd正在推动可以在大多数系统上设置一些合理的默认设置的方法,特殊挑战的奇葩系统的修复可以随后加上。
     最终的结果是这个补丁进入主线之前起码还得再有一轮迭代。但是CMA满足了一个真实的需求。这些代码有潜力使物理连续内存分配更加可靠,同时最小化对系统其它部分的影响。看起来值得拥有。

(转载本站文章请注明作者和出处 http://www.cnblogs.com/baiyw/,请勿用于任何商业用途)

时间: 2024-10-04 21:00:53

CMA,memory fragmation,compaction and migration的相关文章

xenserver6.2 内存leak故障处理

从日志来看,系统内存leak导致out of memory. Oct 30 14:22:35 xenserver-21622 kernel: [36474919.505097] lowmem_reserve[]: 0 0 0 0 Oct 30 14:22:35 xenserver-21622 kernel: [36474919.505104] DMA: 566*4kB 3*8kB 6*16kB 1*32kB 1*64kB 0*128kB 0*256kB 1*512kB 0*1024kB 0*20

systemd:添加systemd.log_level=debug systemd.log_target=console

[    0.000000] Booting Linux on physical CPU 0x0[    0.000000] Linux version 4.14.98-imx_4.14.98_2.0.0_ga+g5d6cbea ([email protected]) (gcc version 7.3.0 (GCC)) #1 SMP PREEMPT Sun Apr 14 10:53:57 UTC 2019[    0.000000] Boot CPU: AArch64 Processor [41

systemd:添加systemd.show_status=0

[    0.000000] Booting Linux on physical CPU 0x0[    0.000000] Linux version 4.14.98-imx_4.14.98_2.0.0_ga+g5d6cbea ([email protected]) (gcc version 7.3.0 (GCC)) #1 SMP PREEMPT Sun Apr 14 10:53:57 UTC 2019[    0.000000] Boot CPU: AArch64 Processor [41

systemd:不添加任何参数

[    0.000000] Booting Linux on physical CPU 0x0[    0.000000] Linux version 4.14.98-imx_4.14.98_2.0.0_ga+g5d6cbea ([email protected]) (gcc version 7.3.0 (GCC)) #1 SMP PREEMPT Sun Apr 14 10:53:57 UTC 2019[    0.000000] Boot CPU: AArch64 Processor [41

[转]Linux内核最新的连续内存分配器(CMA)——避免预留大块内存

http://blog.csdn.net/21cnbao/article/details/7309757 在我们使用ARM等嵌入式Linux系统的时候,一个头疼的问题是GPU,Camera,HDMI等都需要预留大量连续内存,这部分内存平时不用, 但是一般的做法又必须先预留着.目前,Marek Szyprowski和Michal Nazarewicz实现了一套全新的Contiguous Memory Allocator.通过这套机制,我们可以做到不预留内存,这些内存平时是可用的,只有当需要的时候才

CMA连续物理内存用户空间映射---(一)

背景: 在多媒体和图像处理等应用中,经经常使用到大块内存,尤其是硬件编解码.须要内核分配大块的物理连续内存. 这里希望通过把从内核分配的连续物理内存映射到用户空间.在用户空间经过处理,又能够入队到驱动中. 前提: Kernel Config中 依据需求配置和调整CMA的大小. 方法: (一) 1.驱动注冊misc设备. 2.驱动实现IOCTL的内存分配,使用dma_alloc_writecombine从CMA中拿出一个内存. 3.驱动实现mmap,通过remap_pfn_range,把上面第二步

VCL to UniGUI Migration Wizard

Free Evaluation Edition of The Automatic Migration Scripting Wizard For Converting Legacy Delphi Code using Standard VCL to UniGUI For Delphi Berlin 10.1 & Seattle 10. Scan Free Millions of Lines of Delphi Code & See in Your Own Eyes How Easy &

low memory killer配置的思考

OOM_ADJ对于低内存的时候,我们总是想尽量杀掉background的app,尽量保留persist service(比如输入法),让前台app能够流畅的运行.1,background app的adj尽量设高一些,但是max和mini之前,尽量还是要保留一些差距,这样让系统可以逐步去kill进程,而不是一次杀掉很多.一次杀掉很多app很容易造成系统卡顿.2,previeous app和home launcer的adj一定要独立出来,并且不能设置太低,previous app可能会占用很多的内存

(转)SDL 1.2 to 2.0 Migration Guide--SDL1.2更新到SDL2.0指南

SDL 1.2 to 2.0 Migration Guide 目录 SDL 1.2 to 2.0 Migration Guide Translations Introduction Overview of new features Looking for more information Moving from SDL 1.2 to 2.0 Some general truths Video Setting up a game with the new video API If your gam