本文主要是介绍对于MIGRATE_MOVABLE的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
内存管理对于不同的zone管理区,都会划分为不同的memory block进行管理,这些memory block是按照2的幂次个页面进行管理的,对应的结构体如下:
struct zone {.../* free areas of different sizes */struct free_area free_area[MAX_ORDER];...
}struct free_area {struct list_head free_list[MIGRATE_TYPES];unsigned long nr_free;
};
这里的每个free_area结构体中都管理着大小相同的连续内存块,不同块之间使用list连接。内核较早的版本对于free_list不会做migrate_type的区分,后来引入migrate_type也是为了优化内存管理中的碎片化问题。
怎么来理解这个优化特性呢?
这里的套路和内核中引入ZONE_MOVABLE类似,当内存区中如果按照内存页是否可以被回收,是否可以被迁移等特性进行分类时,将避免了相互干扰,后期进行内存回收时将会获取更多的连续内存,这也是终极目的。
关于ZONE_MOVABLE的介绍参考我的另一篇博客:对于ZONE_MOVABLE的理解。
接下来看一下这里对页面是如何进行分类的:
enum {MIGRATE_UNMOVABLE,MIGRATE_RECLAIMABLE,MIGRATE_MOVABLE,MIGRATE_PCPTYPES, /* the number of types on the pcp lists */MIGRATE_RESERVE = MIGRATE_PCPTYPES,
#ifdef CONFIG_CMA/** MIGRATE_CMA migration type is designed to mimic the way* ZONE_MOVABLE works. Only movable pages can be allocated* from MIGRATE_CMA pageblocks and page allocator never* implicitly change migration type of MIGRATE_CMA pageblock.** The way to use it is to change migratetype of a range of* pageblocks to MIGRATE_CMA which can be done by* __free_pageblock_cma() function. What is important though* is that a range of pageblocks must be aligned to* MAX_ORDER_NR_PAGES should biggest page be bigger then* a single pageblock.*/MIGRATE_CMA,
#endif
#ifdef CONFIG_MEMORY_ISOLATIONMIGRATE_ISOLATE, /* can't allocate from here */
#endifMIGRATE_TYPES
};
这里把不同特性的内存块分类放到不同的链表中管理,比如MIGRATE_RECLAIMABLE链表中存放的都是可以直接回收的内存,一般是文件缓存页,MIGRATE_MOVABLE链表中存放的都是可以迁移的内存块,MIGRATE_CMA链表中存放的是和CMA共同使用的区域,该区域也要求必须可以被迁移,这样当外设驱动申请CMA内存时(一般用于DMA传输大块物理连续内存),伙伴系统能够及时的腾出空间给DMA使用。
当系统中剩余内存很多但不连续时,如果申请一个大块连续内存依然会导致失败,如果能够把不连续的内存通过迁移的手段进行规整,把空闲内存组合成一块连续内存,那就可以在一定程度上达到内存申请的需求,如果该区域中所有页面都可以迁移,那么问题就变得简单了,所以内核就按照页面是否可以迁移做了区分,保证了在MIGRATE_MOVABLE链表中都是可以迁移的页面,这样可以尽可能的利用页面迁移规整出大块的连续内存。
参考文章:
https://www.cnblogs.com/linhaostudy/p/10482439.html
https://blog.csdn.net/dog250/article/details/6108028
这篇关于对于MIGRATE_MOVABLE的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!