为什么我不能映射超过 1G 的大页面?
Why can't I mmap more than 1G hugepages?
pqy@3500X ~/projects/hp/build $ cat ../main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int n = atoi(argv[1]);
void *addr = mmap(NULL, n*1024*1024*1024, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, 0);
if(addr == -1){
perror("mmap");
}
return 0;
}
pqy@3500X ~/projects/hp/build $ cat /proc/meminfo |grep -i huge
AnonHugePages: 1058816 kB
ShmemHugePages: 0 kB
FileHugePages: 36864 kB
HugePages_Total: 4
HugePages_Free: 4
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
Hugetlb: 4194304 kB
pqy@3500X ~/projects/hp/build $ ./hp 1
pqy@3500X ~/projects/hp/build $ ./hp 2
mmap: Cannot allocate memory
pqy@3500X ~/projects/hp/build $ ./hp 3
mmap: Cannot allocate memory
pqy@3500X ~/projects/hp/build $ ./hp 4
mmap: Invalid argument
我有 4 个免费的 1G 大页面,我想将所有大页面映射到我的进程。但是在我的测试程序中,我只能成功映射1G。较大的值会抛出 "Cannot allocate memory" 或 "Invalid argument",这让我感到困惑。这里有陷阱吗?
您的 n
变量是一个 int
,在 Linux 和 x86_64 中是 32 位宽。这意味着值 2
或更高溢出。
实际上,2
和 3
产生负数,这些负数被解释为巨大的 64 位无符号值(因此分配失败),而 4
恰好产生 0
(因此参数无效)。
pqy@3500X ~/projects/hp/build $ cat ../main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int n = atoi(argv[1]);
void *addr = mmap(NULL, n*1024*1024*1024, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, 0);
if(addr == -1){
perror("mmap");
}
return 0;
}
pqy@3500X ~/projects/hp/build $ cat /proc/meminfo |grep -i huge
AnonHugePages: 1058816 kB
ShmemHugePages: 0 kB
FileHugePages: 36864 kB
HugePages_Total: 4
HugePages_Free: 4
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
Hugetlb: 4194304 kB
pqy@3500X ~/projects/hp/build $ ./hp 1
pqy@3500X ~/projects/hp/build $ ./hp 2
mmap: Cannot allocate memory
pqy@3500X ~/projects/hp/build $ ./hp 3
mmap: Cannot allocate memory
pqy@3500X ~/projects/hp/build $ ./hp 4
mmap: Invalid argument
我有 4 个免费的 1G 大页面,我想将所有大页面映射到我的进程。但是在我的测试程序中,我只能成功映射1G。较大的值会抛出 "Cannot allocate memory" 或 "Invalid argument",这让我感到困惑。这里有陷阱吗?
您的 n
变量是一个 int
,在 Linux 和 x86_64 中是 32 位宽。这意味着值 2
或更高溢出。
实际上,2
和 3
产生负数,这些负数被解释为巨大的 64 位无符号值(因此分配失败),而 4
恰好产生 0
(因此参数无效)。