一种基于Linux大页内存的易扩展页面架构的制作方法

文档序号:11691011阅读:305来源:国知局
一种基于Linux大页内存的易扩展页面架构的制造方法与工艺

本发明属于通信技术领域,具体涉及一种基于linux大页内存的易扩展页面架构。



背景技术:

内存管理是linux内核中最重要的一部分。内存采用“分页机制”,用于支持对大地址空间的快速、高效的管理。虽然原则上内存页面大小是可配置的,但linux内核中采用默认的4kb(4096字节)页面,即小页。当linux操作系统上运行内存需求量较大的应用程序时,由于其采用的默认页面大小为4kb,因而会产生较多tlbmiss和缺页中断,从而大大影响应用程序的性能,因此,linux内核中也引入大页面支持。当操作系统以2mb甚至更大作为分页的单位时,这大大减少tlbmiss和缺页中断的数量,显著提高应用程序的性能。

为了能以最小的代价实现大页面支持,linux操作系统采用了基于hugetlbfs特殊文件系统2m字节大页面支持。这种采用特殊文件系统形式支持大页面的方式,使得应用程序可以根据需要灵活地选择虚存页面大小。但是,从本质上讲hugetlbfs的实现方式仅仅是一个通过“打补丁”的手段来支持灵活的内存页面大小,受限于linux内核。大页文件系统与小页仍共用伙伴系统,这使得在大页上的开发设计时,难免会影响到小页,不利于进一步的开发和扩展。



技术实现要素:

鉴于上述,本发明提供了一种基于linux大页内存的易扩展页面架构,该架构不再与小页文件系统共用伙伴系统,被单独管理,且能够与linux内核进行解耦,提升内存存储调用的独立性。

一种基于linux大页内存的易扩展页面架构,包括:大页内存及调用大页内存的接口函数,所述的大页内存分为多个节点,每个节点分为多个分区,每个分区由以双向链表的形式连接在一起的多个2m大页组成,所述的接口函数包括用于获取单个大页的申请函数、用于释放大页的释放函数、用于将大页占为己有且禁止其他进程访问的锁函数以及用于恢复大页自由的解锁函数。

所述的每个大页包含以下几个条目:

flags:用于标记页面的属性,且其中包含如下标志位:

pg_locked,当页被一个进程访问时,该位置1,其他进程等待;

pg_dirty,当页中的内容被修改后,该位置1,表示数据要写回;

pg_private,该位为1表示页不能被共享,为0可以被共享;

pg_referenced,pg_active,两个标志位共同来记录一个页的访问活跃程度,用在冷热页调度中,两个位都为1时进入热页池,都为0时进入冷页池,其他情况不移动;

mapping:用来指引正在映射的索引节点inode;

index:表示在映射表中的偏移;

lru:用于每个分区的大页双向链表构建,大页链表顺序按照最近最少使用算法,故叫做lru,这里lru指向前大页的lrui-1和后大页的lrui+1;

mapcount:用于记录页共享者的个数。

所述的申请函数实现从大页内存中获取单个大页,具体过程为:

(a-1)查询linux系统中的node_possible_map,获取节点分布,判断节点的个数以及节点是否含有内存空间,并从第一个含有内存空间的节点进行查询;

(a-2)获取当前节点的分区分布,判断当前节点是否含有分区,若是,执行步骤(a-3),若否,结束该节点的查询,并执行步骤(a-7);

(a-3)查找当前节点的第一分区,并判断当前分区中是否空闲大页,若是,执行步骤(a-6),若否,执行步骤(a-4);

(a-4)判断当前节点的下一个分区中是否含有空闲大页,若是,执行步骤(a-6),若否,执行步骤(a-5);

(a-5)重复循环步骤(a-4),直到遍历当前节点的所有分区为止,若当前节点的最后一个分区不含有空闲大页,执行步骤(a-7)。

(a-6)将空闲大页的共享计数mapcount设为1,并将该大页从当前分区的活动链表上去除,调整该分区中前后大页的lru1、lru2,使lru1指向后大页,lru2指向前大页,返回获取的大页,结束函数;

(a-7)将下一个节点作为当前节点,执行步骤(a-2),直到遍历所有含有内存空间的节点,若遍历到最后一个含有内存空间的节点中的最后一个分区的所有大页,未找到空闲大页,则获取大页失败。

所述的释放函数实现将不使用的大页释放到大页内存中,具体过程为:

(b-1)判断当前大页的共享计数mapcount是否为1,若是,执行步骤(b-2),若否,将共享计数mapcount减1,结束大页释放;

(b-2)判断是否能够获取当前大页所在的节点及分区信息,若是,执行步骤(b-3),若否,执行报错;

(b-3)根据获取的当前大页所在的节点及分区信息,将该大页添加至其所在分区的大页链表上,调整该大页的lru1,使lru指向正确的前后大页,调整前后大页的lru2、lru3,使lru2、lru3指向该大页,并将该大页所属的分区的空间大页数目加1,将该大页所属的节点的空闲大页数目加1,将该大页的共享计数mapcount设为0,大页释放完成。

所述的锁函数实现将大页占为己有,禁止其他进程访问,具体过程为:

(c-1)查看当前大页的标志flags,判断当前大页的属性是否为禁止锁,若是,退出查看,若否,执行步骤(c-2);

(c-2)继续查看当前大页的标志flags,判断当前大页是否已经被锁,若是,执行步骤(c-3),若否,执行步骤(c-4);

(c-3)将当前进程添加到该大页所属节点的一个等待队列中;

(c-4)将大页标志里flags中的pg_locked设为1,完成该大页的上锁。

所述的解锁函数实现恢复大页自由,可以被其他进程访问,具体过程为:

修改大页的标志flags,将标志flags中的pg_locked设为0,表示该大页可以被其他进程访问。由于大页被锁,之前的所有请求该大页是进程都被添加到该大页所属的节点中的等待队列中,此时大页被解锁,将重新唤醒节点中等待队列的进程,让其继续运行。

本发明在linux的内存管理中,实现了一套易拓展的大页构架。该大页构架抛弃了原有的伙伴系统机制,与小页之间进行切割,单独成块。同时,大页构建也实现了构架本身的结构定义、接口函数的定义。本发明的大页构架不会牵涉到原有小页的功能和实现,可以方便进行大页的压缩、迁移等开发。

附图说明

图1为本发明实施例大页内存的组织方式的示意图;

图2为本发明实施例大页架构与上层接口示意图。

具体实施方式

为了更为具体地描述本发明,下面结合附图及具体实施方式对本发明的技术方案进行详细说明。

本发明以linux系统的内存管理为基础,并根据内核中的“分页机制”下的大页模式。通过简化,实现了一种基于linux内存管理的非伙伴系统大页架构。在内核中的组织方式,与原有大页架构完全不同。

如图1所示的是本实施例大页内存采用的组织方式。在numa体系的计算机中,大页内存分为3个节点node,每个节点的内存分为3个分区section,考虑性能方面的原因,分区的大小设为1g;每个分区由以双向链表的形式连接在一起的3个2m大页hugepage。

实际应用时,大页内存可划分为任意个节点,且每个节点可划分为任意个分区。每个分区中都会建立一个双向链表,每个大页中的lru项,用来记录该大页的后一个大页和前一大页。

大页是大页内存中的基本单元,其中含有一些元数据,来记录本大页的信息。这些信息会在调用时使用,帮助大页的组织和管理。具体分为下面几个条目:

flags:用于标记页面的属性,flags中包含如下标志位:

pg_locked,当页被一个进程访问时,该位置1,其他进程等待;

pg_dirty,当页中的内容被修改后,该位置1,表示数据要写回;

pg_private,该位为1表示页不能被共享,为0可以被共享;

pg_referenced,pg_active,两个标志位共同来记录一个页的访问活跃程度,用在冷热页调度中,两个位都为1时进入热页池,都为0时进入冷页池,其他情况不移动。

mapping:用来指引正在映射的索引节点inode;

index:表示在映射表中的偏移;

lru:用于每个分区的大页双向链表构建(大页链表顺序按照最近最少使用算法,故叫做lru),这里lru指向前后大页的lrui-1、lrui+1;

mapcount:用于记录页共享者的个数。

如图2所示,本实施例还提供了四个用于本大页内存的四个接口函数,具体包括:申请函数alloc_page、释放函数free_page、锁函数lock_page以及解锁函数unlock_page。

申请函数alloc_page用于从大页内存中获取单个大页,具体实现过程为:

(a-1)查询linux系统中的node_possible_map,获取节点分布,判断节点的个数以及节点是否含有内存空间,并从第一个含有内存空间的节点进行查询;

(a-2)获取当前节点的分区分布,判断当前节点是否含有分区,若是,执行步骤(a-3),若否,结束该节点的查询,并执行步骤(a-7);

(a-3)查找当前节点的第一分区,并判断当前分区中是否空闲大页,若是,表示可以获取该空闲大页,执行步骤(a-6),若否,执行步骤(a-4);

(a-4)判断当前节点的下一个分区中是否含有空闲大页,若是,执行步骤(a-6),若否,执行步骤(a-5);

(a-5)重复循环步骤(a-4),直到遍历当前节点的所有分区为止,若当前节点的最后一个分区不含有空闲大页,执行步骤(a-7)。

(a-6)将空闲大页的共享计数mapcount设为1,表示当前有一个进程在访问该空闲大页,并将该大页从当前分区的活动链表上去除,同时,由于该页已被获取,不再空闲,调整该分区中前后大页的lrui-1、lrui+1,使lrui-1指向后大页,lrui+1指向前大页,保持正确指向,返回获取的大页,结束函数;

(a-7)将下一个节点作为当前节点,执行步骤(a-2),直到遍历所有含有内存空间的节点,若遍历到最后一个含有内存空间的节点中的最后一个分区的所有大页,未找到空闲大页,则获取大页失败。

释放函数free_page用于将不在使用大页释放到大页内存中,具体实现过程为:

(b-1)判断当前大页的共享计数mapcount是否为1,若是,执行步骤(b-2),若否,说明还有其他进程在使用,仅将共享计数mapcount减1,结束大页释放;

(b-2)判断是否能够获取当前大页所在的节点及分区信息,若是,执行步骤(b-3),若否,执行报错;

(b-3)根据获取的当前大页所在的节点及分区信息,将该大页添加至其所在分区的大页链表上,调整该大页的lrui,使lru指向正确的前后大页,调整前后大页的lrui-1、lrui+1,使lrui-1、lrui+1指向该大页,并将该大页所属的分区的空间大页数目加1,将该大页所属的节点的空闲大页数目加1,将该大页的共享计数mapcount设为0,大页释放完成。

锁函数lock_page实现将大页占为己有,禁止其他进程访问,具体实现过程为:

(c-1)查看当前大页的标志flags,判断当前大页的属性是否为禁止锁,若是,退出查看,若否,执行步骤(c-2);

(c-2)继续查看当前大页的标志flags,判断当前大页是否已经被锁,若是,执行步骤(c-3),若否,执行步骤(c-4);

(c-3)将当前进程添加到该大页所属节点的一个等待队列中;

(c-4)将大页标志里flags中的pg_locked设为1,表示该大页不能再被其他进程访问,完成该大页的上锁。

解锁函数unlock_page实现恢复大页自由,可以被其他进程访问,具体过程为:

修改大页的标志flags,将标志flags中的pg_locked设为0,表示该大页可以被其他进程访问。由于大页被锁,之前的所有请求该大页是进程都被添加到该大页所属的节点中的等待队列中,此时大页被解锁,将重新唤醒节点中等待队列的进程,让其继续运行。

以上的大页内存适用于现有的linux系统中,该内存构架不会牵涉到小页系统,提升了可扩展性。

以上所述的具体实施方式对本发明的技术方案和有益效果进行了详细说明,应理解的是以上所述仅为本发明的最优选实施例,并不用于限制本发明,凡在本发明的原则范围内所做的任何修改、补充和等同替换等,均应包含在本发明的保护范围之内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1