【问题标题】:Why can't I mmap more than 1G hugepages?为什么我不能映射超过 1G 的大页面?
【发布时间】:2020-06-05 14:09:03
【问题描述】:
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 巨页,我想将所有内容都映射到我的进程中。但是在我的测试程序中,我只能成功mmap 1G。较大的值会引发“无法分配内存”或“无效参数”,这让我很困惑。这里有什么陷阱吗?

【问题讨论】:

  • 提示:用clang -fsanitize=undefined编译

标签: c linux mmap huge-pages


【解决方案1】:

您的n 变量是int,在 x86_64 的 Linux 中是 32 位宽。这意味着2 或更高的值溢出。

在实践中,23 产生的负数被解释为巨大的 64 位无符号值(因此分配失败),而 4 正好产生 0(因此参数无效) .

【讨论】:

  • 特别是,乘法 n*1024*1024*1024 是作为 int 完成的,因此会溢出。最简单的修复方法可能是 (size_t)n * 1024 * 1024 * 1024n * 1024UL * 1024UL * 1024UL
猜你喜欢
  • 2020-04-07
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 2016-08-30
  • 1970-01-01
  • 2017-06-09
相关资源
最近更新 更多