伙伴(buddy)算法浅析
作者:互联网
1、伙伴算法引入
内核频繁请求和释放不同大小的一组连续页框,必然会导致在已经分配的块内分散了许多小块的空闲页框,带来的问题是,及时有足够的空闲页框可以满足请求,但是要分配一大块连续页框就无法满足,所以内核应该为分配一组连续的页框而建立一种健壮高效的分配策略。伙伴算法就是基于此。
2、伙伴算法的思想
linux把所有空闲页框分组为11个块链表,每个链表上的页框块是固定的,第i条链表中,每个页框块都包含2i个连续页,其中i称为分配阶,
假设要申请28个页,先从28即256个页框中查找空闲块,没有就去512个页框的链表中找,找到了则将页框分为2个256个页框的块,一个分配给应用,一个移到256个页框的链表中去,如果512个页框仍没有空闲块,继续向1024个页框链表查找,如果存在空闲块,则将其中256页框作为请求返回 ,剩余的768分成256和512分别插到相应的链表中,如果仍然没有,则返回错误。
3、伙伴算法在内核中的数据结构
struct zone{
struct free_area freearea[MAX_ORDER];
};
//其中,define内核中为
#define MAX_ORDER 11 //即上文中提到的11个块链表
free_area[]数组是一个struct free_area的结构体,其在内核中的定义为:
struct free_area
{
struct list_head free_list[MIGRATE_TYPES];/*说明了页的属性*/
unsigned long nr_free;/*来说明每个介中有多少个自由的页*/
};
在这个函数中有两个域,第一个是free_list,是个链表,它表示的就是当前分配阶所对应的页框块的链表。第二个nr_free指的是当前链表中空闲页框块的数目,比如free_area[2]中nr_free的值为5,表示有5个大小为4的页框块,那么总的空闲页为20.
对于free_list中的MIGRATE_TYPES表示的是迁移页的类型,在内核中的定义为:
#define MIGRATE_UNMOVABLE 0 //不可移动页:在内存中有固定位置,不能移动到其他地方
#define MIGRATE_RECLAIMABLE 1 //可回收页:不能直接移动,但可以删除,其内容可以从某些源重新生成
#define MIGRATE_MOVABLE 2 //可移动页:可以随意的移动
#define MIGRATE_RESERVE 3 //如果向具有特定可移动性地列表请求分配内存失败,这种紧急情况下可以从MIGRATE_RESERVE分配内存
#define MIGRATE_ISOLATE 4 //是一个特殊的虚拟区域,用于跨域NUMA结点移动物理内存页,在大型系统上,它有益于将物理内存页移动到接近于是用该页最频繁的CPU
#define MIGRATE_TYPES 5 //只是表示迁移类型的数目,不代表具体的区域
4.伙伴算法在内核分配页框时的实现
内核中分配页框的函数入口是:alloc_pages函数:
#define alloc_pages(gfp_mask, order) \
alloc_pages_node(numa_node_id(), gfp_mask, order)
lloc_pages_node()函数有三个参数:numa_node_id这个参数下文讲,gfp_mask这个参数指的是分配器的标志,也就是说分配的内存块所具有的属性(如果还是不懂,那就看看Linux内核设计与实现这本书,这里姑且认为是分配的内存块的属性),order指的是伙伴中的阶数。
介绍下numa_node_id
从硬件角度看,存在两种机器,uma和numa
uma多个cpu共享一个内存,numa,每个cpu有自己本地内存,然后处理器通过总线连接起来,进而可以访问其他cpu的本地内存。
4.1 __alloc_pages()函数
4.2 __alloc_pages_nodemask()函数
4.4 buffered_rmqueue伙伴算法入口函数
4.5 __rmqueue_smallest函数
4.6 expand()函数
总结
强调文本 强调文本
加粗文本 加粗文本
标记文本 sdfgsdfg
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024。
https://www.cnblogs.com/wangzahngjun/p/4943518.html
标签:buddy,MIGRATE,个页,free,链表,算法,内核,浅析,define 来源: https://blog.csdn.net/gangjindianzi/article/details/110142405