Mr Pang
Mr Pang

Reputation: 1181

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

I have 4 free 1G hugepages, and I would like to mmap all to my process. But in my test program, I can only mmap 1G successfully. Larger value throws "Cannot allocate memory" or "Invalid argument", which is confusing to me. Any trap here?

Upvotes: 1

Views: 461

Answers (1)

Acorn
Acorn

Reputation: 26066

Your n variable is an int, which is 32-bit wide in Linux in x86_64. This means values of 2 or higher overflow.

In practice, 2 and 3 are yielding negative numbers which get interpreted as huge 64-bit unsigned values (so the allocation fails), and 4 yields exactly 0 (so the argument is invalid).

Upvotes: 2

Related Questions