伙伴系统分析

:
:.1
:3.4.0
基本概念:
关于伙伴系统算法的原理还是比较好理解的,这里不作复数 。直接看下关键数据结构 。
struct zone {~~snipstruct free_areafree_area[MAX_ORDER];//每一阶以一个元素保存,平台最大11阶 。~~snip};
可以看到每个zone都有它自己的,效果如下图:

伙伴系统分析

文章插图
相关信息可以从/proc/读取到,各个值含义依次为节点号, zone类型,后面的值表示从0阶开始各个阶空闲的页数:
#cat/proc/buddyinfoNode0, zoneNormal702733148471372211Node0, zoneHighMem01122000000
伙伴系统分析

文章插图
struct free_area {/*同样阶数保存到一个链表上 */struct list_head free_list[MIGRATE_TYPES];/*当前空闲页块的数目 。*/unsigned longnr_free;};
效果如下图:
伙伴系统分析

文章插图
是作为反碎片的一种机制,专有名叫迁移类型 。大概的原理就是将伙伴系统的内存页分为几种类型,有可移动,不可移动,可回收等,同一类型的页放在一个区域,如不可回收的页不能放在可移动类型区域,这样对可以移动区域,伙伴系统就可以回收了 。
enum {MIGRATE_UNMOVABLE,MIGRATE_RECLAIMABLE,MIGRATE_MOVABLE,MIGRATE_PCPTYPES, /* the number of types on the pcp lists */MIGRATE_RESERVE = MIGRATE_PCPTYPES,#ifdef CONFIG_CMAMIGRATE_CMA,#endifMIGRATE_ISOLATE, /* can't allocate from here */MIGRATE_TYPES};
:不可移动页,在内存中有固定位置,不能移动 。核心内核分配的大部分内存属于此类 。
:可回收页,不能移动,但能删除 。内核线程会操作次区域 。
:可移动又可回收页,用户空间程序使用此类,通过页表映射实现,如果应用程序虚拟地址空间有变化,只要变化页表就可以了 。
: 当系统内存相当少而且比较紧急时,才用到此区域 。
:这个是为了避免预留大块内存实现的,当需要大块内存的时候如audio/等,它可以被使用;当小内存申请需要时,它也可以被使用,避免了pmem/ion的弊端,不过似乎要基于DMA 。后面打算用一篇文章来分析cma.
: NUMA系统上使用,我们用UMA,不管它 。
当某个迁移类型的内存不足时,会向另外一个迁移类型去要内存 。这个跟zone的申请机制很像!下面结构规定了当前迁移类型不够时下一个使用的类型,如的使用顺序是:->-> -> .
static int fallbacks[MIGRATE_TYPES][4] = {[MIGRATE_UNMOVABLE]= { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE,MIGRATE_RESERVE },[MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE,MIGRATE_MOVABLE,MIGRATE_RESERVE },#ifdef CONFIG_CMA[MIGRATE_MOVABLE]= { MIGRATE_CMA,MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },[MIGRATE_CMA]= { MIGRATE_RESERVE }, /* Never used */#else[MIGRATE_MOVABLE]= { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE,MIGRATE_RESERVE },#endif[MIGRATE_RESERVE]= { MIGRATE_RESERVE }, /* Never used */[MIGRATE_ISOLATE]= { MIGRATE_RESERVE }, /* Never used */};
迁移类型的信息可以从/proc/读到:
#cat /proc/pagetypeinfoPage block order: 10Pages per block:1024Free pages count per migrate type at order012345678910Node0, zoneNormal, typeUnmovable11201011100Node0, zoneNormal, typeReclaimable818300000000Node0, zoneNormal, typeMovable110115461250000Node0, zoneNormal, typeReserve00010111111Node0, zoneNormal, typeIsolate00000000000Node0, zoneHighMem, typeUnmovable00000000000Node0, zoneHighMem, typeReclaimable00000000000Node0, zoneHighMem, typeMovable01000000000Node0, zoneHighMem, typeReserve00122000000Node0, zoneHighMem, typeIsolate00000000000Number of blocks typeUnmovableReclaimableMovableReserveIsolateNode 0, zoneNormal13817820Node 0, zoneHighMem101410