【原创】(九)Linux内存管理 - zoned page frame allocator - 4 (2)

图来了:

【原创】(九)Linux内存管理 - zoned page frame allocator - 4

实际操作一把:
cat /proc/pagetypeinfo如下图:

【原创】(九)Linux内存管理 - zoned page frame allocator - 4

3. compact处理

这个处理的过程还是很复杂的,下图显示了大概的过程:

【原创】(九)Linux内存管理 - zoned page frame allocator - 4

下边将针对各个子模块更深入点分析。

compaction_suitable

【原创】(九)Linux内存管理 - zoned page frame allocator - 4

判断是否执行内存的碎片整理,需要满足以下三个条件:

除去申请的页面,空闲页面数将低于水印值,或者虽然大于等于水印值,但是没有一个足够大的空闲页块;

空闲页面减去两倍的申请页面(两倍表明有足够多的的空闲页面作为迁移目标),高于水印值;

申请的order大于PAGE_ALLOC_COSTLY_ORDER时,计算碎片指数fragindex,根据值来判断;

isolate_migratepages
isolate_migratepages函数中,迁移扫描器以pageblock为单位,扫描可移动页,最终把可移动的页添加到struct compact_control结构中的migratepages链表中。如下图所示:

【原创】(九)Linux内存管理 - zoned page frame allocator - 4

isolate_freepages的逻辑与isolate_migratepages类似,也是对页进行隔离处理,最终添加cc->freepages链表中。

当空闲扫描器和迁移扫描器完成扫描之后,那就是时候将两个链表中的页做一下migrate操作了。

migrate_pages

调用compact_alloc函数,从cc->freepages链表中取出一个空闲页;

调用__unmap_and_move来把可移动页移动到空闲页处;
_unmap_and_move函数涉及到反向映射,以及页缓存等,留在以后再深入看。这个函数两个关键作用:1)调用try_to_unmap删除进程页表中旧的映射关系,在需要访问的时候再重新映射到新的物理地址上;2)调用move_to_new_page函数将旧页移动到新的物理页上,其中在汇编文件arch/arm64/lib/copy_page.S中copy_page函数完成拷贝。

compact_finished
compact_finished函数主要用于检查compact是否完成。

【原创】(九)Linux内存管理 - zoned page frame allocator - 4

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgjgpf.html