【问题标题】:Ubuntu 10.04, error in using MAP_HUGETLB with MAP_SHAREDUbuntu 10.04,将 MAP_HUGETLB 与 MAP_SHARED 一起使用时出错
【发布时间】:2011-07-04 18:37:08
【问题描述】:

以下是我用于在 ubuntu 中使用大页映射文件的代码,但此调用失败并出现错误“无效参数”。但是,当我通过 mmap 中没有文件描述符参数的 MAP_ANON 标志,那么它可以工作。我无法理解这背后的可能原因。

其次,当此标志本身意味着不会将任何更改写回文件时,我无法理解为什么使用 MAP_PRIVATE 允许文件映射。这总是可以使用 MAP_ANON 来完成,还是我遗漏了什么?

有人可以帮我解决这些问题吗?

int32_t main(int32_t argc, char** argv) {
int32_t map_length = 16*1024*1024; // 16 MB , huge page size is 2 MB
int32_t protection = PROT_READ | PROT_WRITE;
int32_t flags = MAP_SHARED | MAP_HUGETLB;
int32_t file__ = open("test",O_RDWR|O_CREAT | O_LARGEFILE,s_IRWXU | S_IRGRP | S_IROTH);
if(file__ < 0 ) {
    std::cerr << "Unable to open file\n";
    return -1;
}

if (ftruncate(file__, map_length) < 0) {
    std::cerr
    << "main :: unable to truncate the file\n"
    << "main :: " << strerror(errno) << "\n"
    << "main :: error number is " << errno << "\n";
    return -1;
}
void *addr= mmap(NULL, map_length, protection, flags, file__, 0);
if (addr == MAP_FAILED) {
    perror("mmap");
    return -1;
}
const char* msg = "Hello World\n";
int32_t len = strlen(msg);
memcpy(addr,msg,len);
munmap(addr, map_length);
close(file__);
return 0;
}

【问题讨论】:

  • int32_t main 是一个错误。根据 C++ 标准,main 的返回类型和 argc 的类型都应该只是 int
  • larsmans,这会影响程序的输出吗?在我的架构上,int 与 int32_t 相同,所以它根本不重要。但从标准的角度来看,我同意这是不对的。 (之前我在写这篇评论时犯了一些错误)
  • 法拉兹:不,他只是在吹毛求疵。
  • 为什么还要使用 10.04?

标签: c++ linux mmap


【解决方案1】:

您的两个问题都归结为同一点:使用 mmap() 您可以获得两种映射:匿名内存和文件。

匿名内存(如手册页所述)不受文件系统中任何文件的支持。相反,您从对 mmap() 的 MAP_ANON 调用返回的内存是普通系统内存。这个接口的主要用户是 C 库,它使用它来获取 malloc/free 的后备存储。因此,使用 MAP_ANON 明确表示您不想映射文件。

文件支持的内存将文件(或文件的一部分)混合到应用程序的地址空间中。在这种情况下,内存内容实际上是由文件内容支持的。将 MAP_PRIVATE 标志视为首先为文件分配内存,然后将内容复制到此内存中。事实上,这不是内核正在做的事情,但我们只是假装。

HUGE_TLB 是内核为匿名内存提供的功能(请参阅在 mmap() 手册页中引用的 Documentation/vm/hugetlb-page.txt)。这应该是使用 HUGETLB 文件时 mmap() 调用失败的原因。 *编辑:不完全正确。有一个支持大页面的 RAM 文件系统 (hugetlbfs)。但是,据我了解,huge_tlb 映射不适用于任意文件。*

关于如何使用 HUGE_TLB 和相应的内存文件系统 (hugetlbfs) 的详细信息,您可能需要考虑以下关于 LWN 的文章:

【讨论】:

  • 我写过 mmap 失败并出现错误“无效参数”,这是您在执行 strerno(22) 时得到的字符串
  • 在编写此查询之前,我浏览了所有文档,但任何地方都不清楚。我会很高兴阅读类似于“MAP_HUGETLB 仅适用于 MAP_ANON”的内容。其次,在挂载hugetlbfs之后,我们可以用大页面(在这个fs上)做文件支持的mmap。如果文件支持的 mmap 确实不支持 MAP_HUGETLB,那么我们如何能够在该 fs 中将大页面用于文件支持的 mmap?一定有什么遗漏的,对吧?
  • 感谢 BjoernD,我非常感谢您为我挖掘了这些文章,但是在发布之前我已经阅读了所有这些文章。这对我理解为什么不支持这一点非常重要。如果只是因为一些技术问题而无法在一般内核版本中完成,那么我可以更改内核代码以供个人使用。我实际上正在尝试通过内核代码来理解这一点,但直到现在我还没有取得太大的成功。如果有什么关于为什么这是不可能的,那么我会很高兴听到。非常感谢您的时间和精力
  • Documentation/vm/transhuge.txt 提到透明大页面仅适用于当前版本的 MAP_ANON,这就是失败的原因。通过hugetlbfs 做这件事不是一个透明的用法。
【解决方案2】:

将 MAP_PRIVATE 添加到标志为我解决了这个问题。

【讨论】:

猜你喜欢
  • 2011-08-28
  • 2011-05-08
  • 2020-07-10
  • 2016-05-18
  • 2012-06-12
  • 2012-03-24
  • 1970-01-01
  • 2016-11-05
  • 2021-12-06
相关资源
最近更新 更多