【原创】(九)Linux内存管理 - zoned page frame allocator - 4
背景
Read the fucking source code!
--By 鲁迅A picture is worth a thousand words.
--By 高尔基
说明:
- Kernel版本:4.14
- ARM64处理器,Contex-A53,双核
- 使用工具:Source Insight 3.5, Visio
1. 概述
本文将描述memory compaction
,内存碎片整理技术。
内存碎片分为内碎片和外碎片:
- 内碎片:内存页里边的碎片;
- 外碎片:内存页之间的碎片,可能会造成连续物理页面分配失败。
memory compaction
就是通过将正在使用的可移动页面迁移到另一个地方以获得连续的空闲页面的方法。针对内存碎片,内核中定义了migrate_type
用于描述迁移类型:
MIGRATE_UNMOVABLE
:不可移动,对应于内核分配的页面;MIGRATE_MOVABLE
:可移动,对应于从用户空间分配的内存或文件;MIGRATE_RECLAIMABLE
:不可移动,可以进行回收处理;
先来一张memory compaction
的概况图:
上图对应的是struct page
的操作,而针对物理内存的操作如下图所示:
在之前的文章中提到过pageblock
,我们看到图中zone
区域是以pageblock
为单位上下扫描的,pageblock
的大小定义如下(未使用huge table
情况下),与Buddy System管理中的最大块大小一致:
/* If huge pages are not used, group by MAX_ORDER_NR_PAGES */ #define pageblock_order (MAX_ORDER-1) #define pageblock_nr_pages (1UL << pageblock_order)
好了,已经有一个初步印象了,那就进一步的分析吧。
1. 数据结构
1.1 compact_priority
/* * Determines how hard direct compaction should try to succeed. * Lower value means higher priority, analogically to reclaim priority. */ enum compact_priority { COMPACT_PRIO_SYNC_FULL, MIN_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_FULL, COMPACT_PRIO_SYNC_LIGHT, MIN_COMPACT_COSTLY_PRIORITY = COMPACT_PRIO_SYNC_LIGHT, DEF_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_LIGHT, COMPACT_PRIO_ASYNC, INIT_COMPACT_PRIORITY = COMPACT_PRIO_ASYNC };
本结构用于描述memory compact
的几种不同方式:
COMPACT_PRIO_SYNC_FULL/MIN_COMPACT_PRIORITY
:最高优先级,压缩和迁移以同步的方式完成;COMPACT_PRIO_SYNC_LIGHT/MIN_COMPACT_COSTLY_PRIORITY/DEF_COMPACT_PRIORITY
:中优先级,压缩以同步方式处理,迁移以异步方式处理;COMPACT_PRIO_ASYNC/INIT_COMPACT_PRIORITY
:最低优先级,压缩和迁移以异步方式处理。
1.2 compact_result
本结构用于描述压缩处理函数的返回值: