尝试映射大页面时mmap失败(1GB)

我做了什么:1。用root启用大页面(我的系统支持1MB大页面)

$echo 20 > /proc/sys/vm/nr_hugepages 

2.将庞大的页面文件系统安装到/ mnt / hugepages

 $mount -t hugetlbfs nodev /mnt/hugepages 

3.在巨大的页面文件系统中创建一个文件

 $touch /mnt/hugepages/hello 

然后使用mmap将大页面映射到地址0,如下面的代码所示

  #define FILE_NAME "/mnt/hugepages/hello" #define PROTECTION (PROT_READ | PROT_WRITE) // page flag #define LENGTH (1024*1024*1024) // huge page size #define FLAGS (MAP_SHARED) //page flag #define ADDR (void *) (0x0UL) //starting address of the page fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755); if (fd < 0) { // perror("Open failed"); exit(1); } // allocate a buffer using huge pages buf = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0); if (buf == MAP_FAILED) { perror("mmap"); unlink(FILE_NAME); exit(1); } 

程序输出:mmap:无法分配内存

Linux仅支持用于私有匿名映射的大页面(不受文件支持)。 即你只能为堆栈,数据和堆启用大表。

目前尚不清楚OP是在谈论1GB页面大小还是在ARMv7上,并且确实有1MB页面大小(主题与描述不符)。 这个答案是指使用1GB页面大小。

无论如何,如果你想要1GB的页面大小,你必须在启动时启用它(除非你的内存非常干净,因为只有你拥有hugepagesz连续的可用内存才能分配大页面)。 要启用gigabyte hugepages,请将hugepagesz = 1GB hugepages = n添加到GRUB_CMDLINE_LINUX,其中n是要添加的1GB页面的数量。

您现在可以使用get_huge_pages()( yah! )等接口使用1GB大页面,但仍然无法使用shm_get / mmap( boo! )进行分配。 这两个都没有指定hugepagesz的机制,需要一个解决方法,即将default_hugepagesz = 1GB设置为内核引导命令行的附加参数。

一旦你设置了所有三个参数告别TLB故障并沉浸在1GB页面大小的荣耀中!……除非你掌权,然后你应该沉浸在16GB页面大小的荣耀中;)。

  # Script to create /hugepages mount point and enable 1GB hugepages # For RHEL (6) Systems! # # MAKE SURE YOU KNOW WHAT THIS SCRIPT DOES BEFORE RUNNING! echo "hugetlbfs /hugepages hugetlbfs rw,mode=0777,pagesize=1G 0 0" \ >> /etc/fstab mkdir /hugepages sed 's/rhgb quiet/hugepagesz=1GB default_hugepagesz=1GB hugepages=16 selinux=0/' /etc/default/grub > grub cp /etc/default/grub grub.old mv -f grub /etc/default/grub grub2-mkconfig > /etc/grub2-efi.cfg # Now reboot 

请注意,您还需要使用ftruncate(2)来调整文件的大小,以便它实际保存您使用的内存量。 mmap(2)仍将适用于零大小的文件,但在尝试访问内存时,您将获得SIGBUS

使用映射区域可能会产生以下信号:

SIGBUS尝试访问与文件不对应的缓冲区的一部分(例如,超出文件末尾,包括另一个进程截断文件的情况)。

(来自mmap(2) 。)

要检查该区域是否真的使用大页面,您可以检查/proc/[pid]/smaps (在Linux上的proc(5)中记录)。 检查VmFlags包含内存区域的ht

编辑:

你顺便看了一下libhugetlbfs吗?