为啥使用 numa_alloc_onnode() 进行分配会导致“页面不存在”?

Posted

技术标签:

【中文标题】为啥使用 numa_alloc_onnode() 进行分配会导致“页面不存在”?【英文标题】:Why do allocations with numa_alloc_onnode() lead to "The page is not present"?为什么使用 numa_alloc_onnode() 进行分配会导致“页面不存在”? 【发布时间】:2011-11-12 01:03:28 【问题描述】:

当我像这样使用 numa_alloc_onnode() 在特定的 NUMA 节点上分配内存时:

char *ptr;
if ((ptr = (char *) numa_alloc_onnode(1024,1)) == NULL) 
  fprintf(stderr,"Problem in %s line %d allocating memory\n",__FILE__,__LINE__);
  return(1);

然后使用 move_pages() 尝试确认分配的内存确实在节点 1 上:

  printf("ptr is on node %d\n",get_node(ptr));

在哪里

// This function returns the NUMA node that a pointer address resides on.

int get_node(void *p)

  int status[1];
  void *pa;
  unsigned long a;

  // round p down to the nearest page boundary

  a  = (unsigned long) p;
  a  = a - (a % ((unsigned long) getpagesize()));
  pa = (void *) a;    

  if (move_pages(0,1,&pa,NULL,status,0) != 0) 
    fprintf(stderr,"Problem in %s line %d calling move_pages()\n",__FILE__,__LINE__);
    abort();
  

  return(status[0]);


我得到答案“ptr 在节点 -2 上”。从 errno-base.h 我发现 2 是 ENOENT,move_pages() 手册页说 -ENOENT 在这种情况下的状态意味着“页面不存在”。

如果我用普通的 malloc() 替换 numa_alloc_onnode() 它工作正常:我得到一个节点号。

有人知道这里发生了什么吗?

提前致谢。

【问题讨论】:

【参考方案1】:

numa_alloc_onnode(3) 说:

   All numa memory allocation policy only takes effect when a
   page is actually faulted into the address space of a process
   by accessing it. The numa_alloc_* functions take care of this
   automatically.

这是否意味着您需要在内核实际为您提供页面之前将某些内容存储到新分配的页面中?

【讨论】:

你是对的。你比我快12秒!事实证明,写入分配的空间(一个简单的 ptr[0] = 0; 就可以了)使上面的代码按预期工作:它给了我一个节点号。看来,读书不算数。在我看来,这也与手册页相矛盾:这是一个 numa_alloc_* 函数,它没有被自动处理!如果相关的话,我正在使用 Debian Squeeze。 嘿,关于“自动”的那一点也让我感到困惑——但后来我记得它是由一位德国内核工程师编写的,他可能认为“自动设置页面错误机制”。 :)

以上是关于为啥使用 numa_alloc_onnode() 进行分配会导致“页面不存在”?的主要内容,如果未能解决你的问题,请参考以下文章

如何在特定的 NUMA 内存节点上实例化 C++ 对象?

为啥使用 glTranslatef?为啥不直接更改渲染坐标?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥在参数周围使用 /*、*/ 以及为啥在提取数组长度时使用 >>>? [复制]

为啥我们使用 hadoop mapreduce 进行数据处理?为啥不在本地机器上做呢?

为啥 CoreGui Roblox 锁定在 DataModel 中,为啥受信任的用户不能使用 CoreScripts?