当前位置: 首页 > Linux

大页面摘要

时间:2023-04-06 19:46:53 Linux

0。概述本文总结了hugepage使用中的一些知识点。参考内核版本为4.1.12注:本文为原创,转载请注明出处1.hugepage是什么,有什么用?大页面与传统的4K小页面进行比较。一般来说,常见的架构提供两种大页面大小,比如常见的2M大页面和1G大页面。这两个大页大小其实也分别对应PMD和PUD的一个页表项所能覆盖的物理内存大小。当然,有些架构(比如arm64)通过contiguous-tlb特性支持2个以上的大页面。大页的主要优点:使用大页可以减少页表项的数量,从而降低TLBMiss的概率,提高系统内存访问性能。当然,有优点也有缺点。大页面的使用降低了内存管理的粒度和灵活性。如果程序不使用大量内存,使用大页也可能造成内存浪费。2.如何使用hugepage一般来说有3种方法:使用mmap+MAP_HUGETLB直接匿名映射使用shmget+SHM_HUGETLB属性分配挂载hugetlbfs,在hugetlbfs下创建文件,然后使用mmap映射注意:前提是使用上面的方法是加载了系统Hugetlbfs,并且有空闲的hugepages。可以通过cat/proc/meminfo查看是否有空闲内存。另外,本质上,匿名大页面在大页面文件系统中也有相应的匿名文件,但它们并不是真正的匿名页面。HugePages_Total:10HugePages_Free:10HugePages_Rsvd:0HugePages_Surp:0Hugepagesize:2048kBDirectMap4k:92308kBDirectMap2M:1861632kB3。如何开启大页面功能一般有两种方法1)在bootline中设置大页面参数。页面本质上是由连续的4K小页面组成的,所以在系统启动时保留大页面的成功率是最高的。一共有三个参数,从名字上就很清楚了default_hugepagesz=1Ghugepagesz=1Ghugepages=4如果不定义default_hugepagesz,默认的hugepage大小为2M#defineHPAGE_SHIFTPMD_SHIFT#defineHPAGE_SIZE(_AC(1,UL)</proc/sys/vm/nr_hugepages这个方法预留空闲大页4.系统中是否可以同时存在多种类型的大页在Linux系统中,两种大页面可以同时存在。至于为什么有2种,我个人的理解是因为largepages页面往往对应的是PMD和PUD级别的页表项覆盖的物理内存大小。这已经没有多大意义了。可以通过下面的bootline设置两种类型的hugepagesdefault_hugepagesz=1Ghugepagesz=1Ghugepages=4hugepagesz=2Mhugepages=4内核启动的时候会解析bootline,然后把相应的信息存入下面的结构体#defineHUGE_MAX_HSTATE2structhstatehstates[HUGE_MAX_HSTATE];void__inithugetlb_add_hstate(unsignedorder){structhstate*h;无符号长我;if(size_to_hstate(PAGE_SIZE<=HUGE_MAX_HSTATE);BUG_ON(订单==0);h=&hstates[hugetlb_max_hstate++];...snprintf(h->name,HSTATE_NAME_LEN,"hugepages-%lukB",huge_page_size(h)/1024);parsed_hstate=h;//解析hugepages参数时使用这个变量}static__initintsetup_hugepagesz(char*opt){unsignedlongps=memparse(opt,&opt);if(ps==PMD_SIZE){//2Mhugepageshugetlb_add_hstate(PMD_SHIFT-PAGE_SHIFT);}elseif(ps==PUD_SIZE){//1G大页面hugetlb_add_hstate(PUD_SHIFT-PAGE_SHIFT);}else{pr_err("hugepagesz:不支持的页面大小%luM\n",ps>>20);返回0;}返回1;}__setup("hugepagesz=",setup_hugepagesz);5.如何使用指定的大页大小在使用mmap或shmget获取大页时,如果直接使用MAP_HUGETLB或SHM_HUGETLB参数,获取的大页大小为2MFILE:mmap.c...elseif(flags&MAP_HUGETLB){structuser_struct*user=NULL;结构hstate*hs;hs=hstate_sizelog((标志>>MAP_HUGE_SHIFT)&SHM_HUGE_MASK);if(!hs)return-EINVAL;...FILE:hugetlb.hstaticinlinestructhstate*hstate_sizelog(intpage_size_log){if(!page_size_log)返回&default_hstate;returnsize_to_hstate(1UL<hstate=size_to_hstate(ps);if(!pconfig->hstate){//如果没有找到匹配的大小,将报错pr_err("Unsupportedpagesize%luMB\n",ps>>20);返回-EINVAL;}休息;}//最终的hstate信息保存在hugetlbfs的sb结构中structhugetlbfs_sb_info*sbinfo;sb->s_fs_info=sbinfo;sbinfo->hstate=config.hstate;//hugetlbfs中的所有后续文件文件结构可以关联hstate结构staticinlinestructhstate*hstate_inode(structinode*i){structhugetlbfs_sb_info*hsb;hsb=HUGETLBFS_SB(i->i_sb);returnhsb->hstate;}staticinlinestructhstate*hstate_file(structfile*f){returnhstate_inode(file_inode(f));}//让mmap知道使用多大的hugepage,具体参考hugetlbfs_file_mmap函数6.hugepagepagefaulthandling普通小页的pagefault处理是不一样的。具体过程如下。另外,alloc_huge_page函数的参数如下staticstructpage*alloc_huge_page(structvm_area_struct*vma,unsignedlongaddr,intavoid_reserve)//通过下面的代码,可以传vma或者hstatestructhstate*h=hstate_vma(vma);//本质上是调用hstate_vma函数staticinlinestructhstate*hstate_vma(structvm_area_struct*vma){returnhstate_file(vma->vm_file);}7.Hugepage扩展如果想同时支持两种以上的hugepages,比如2M,32M,1G,可以修改HUGE_MAX_HSTATE宏定义,也可以修改hugepagepte的底层操作接口。下面的例子是arm64contiguous-tlb的补丁,供参考。http://www.spinics.net/lists/…