我正在使用为以下问题numa+mbind+segfault提供的代码,每次调用mbind都会返回EINVAL。我怎样才能得到完全错误的东西?我问这个是因为EINVAL有很多原因可以归还。
page_size = sysconf(_SC_PAGESIZE);
objs_per_page = page_size/sizeof(A[0]);
assert(page_size%sizeof(A[0])==0);
split_three=num_items/3;
aligned_size=(split_three/objs_per_page)*objs_per_page;
remnant=num_items-(aligned_size*3);
piece = aligned_size;
nodemask=1;
mbind(&A[0],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);
nodemask=2;
mbind(&A[aligned_size],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);
nodemask=4;
bind(&A[aligned_size*2+remnant],piece*sizeof(double),MPOL_BIND,
&nodemask,64,MPOL_MF_MOVE);
运行程序后(通过在每次调用1,2和4之前更改节点掩码)如下所示(作为Mats Petersson的答案)。它有时会出现段错误,有时会运行良好。当它发生段错误时,dmesg如下:
Stack:
Call Trace:
mpol_new+0x5d/0xb0
sys_mbind+0x125/0x4f0
finish_task_switch+0x4a/0xf0
? __schedule+0x3cf/0x7c0
system_call_fastpath+0x16/0x1b
Code: ...
kmem_cache_alloc+0x58/0x130
答案 0 :(得分:2)
查看Linux内核的来源,您可以获得EINVAL:
MPOL_MF_STRICT | MPOL_MF_MOVE | MPOL_MF_MOVE_ALL
start
不是页面对齐的。start+len
。 [也就是说,你的len不是至少一个字节] start+len
< start
- 即负长度。MPOL_DEFAULT
且nodes
不为空或NULL
。 我的猜测是start
与页面对齐。
此代码适用于我:
#include <numaif.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define ASSERT(x) do { if (!(x)) do_assert(#x,(long)(x), __FILE__, __LINE__); } while(0)
static void do_assert(const char *expr, long expr_int, const char *file, int line)
{
fprintf(stderr, "ASSERT failed %s (%d) at %s:%d\n",
expr, expr_int, file, line);
perror("Error if present:");
exit(1);
}
int main()
{
size_t num_items = 6156000;
double *A = valloc(num_items * sizeof(double));
ASSERT(A != NULL);
int res;
unsigned long nodemask;
size_t page_size = sysconf(_SC_PAGESIZE);
size_t objs_per_page = page_size/sizeof(A[0]);
ASSERT(page_size%sizeof(A[0])==0);
size_t split_three=num_items/3;
size_t aligned_size=(split_three/objs_per_page)*objs_per_page;
size_t remnant=num_items-(aligned_size*3);
size_t piece = aligned_size;
printf("A[0]=%p\n", &A[0]);
printf("A[%d]=%p\n", piece, &A[aligned_size]);
printf("A[%d]=%p\n", 2*piece, &A[2*piece]);
nodemask=1;
res = mbind(&A[0],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);
ASSERT(res ==0);
nodemask=1;
res = mbind(&A[aligned_size],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);
ASSERT(res ==0);
nodemask=1;
res = mbind(&A[aligned_size*2],(piece+remnant)*sizeof(double),MPOL_BIND,
&nodemask,64,MPOL_MF_MOVE);
ASSERT(res == 0);
}
请注意,我在所有分配中都使用“nodemask = 1”,因为我的机器中只有一个四核处理器,因此没有其他节点可以绑定 - 这也提供EINVAL
。我认为你实际上系统中有多个节点。
我还将“残余”从A[]
移动到piece+remnant
大小,用于上一次mbind
通话。