Hi Andi, > Date: Sat, 10 Jan 2009 07:18:09 +0100 > From: Andi Kleen <andi@xxxxxxxxxxxxxx> > To: Andi Kleen <andi@xxxxxxxxxxxxxx> > Cc: cpw@xxxxxxx, linux-numa@xxxxxxxxxxxxxxx > Subject: [PATCH] Fix test/prefered v2 > > Fix test/prefered v2 > > Couple of bugs here: > > - First the kernel errors out of the nodemask is < MAXNUMNODES, > so have to discover that at runtime. There's no function > in libnuma for this (perhaps there should be one?), so i > wrote one here. There is numa_num_possible_nodes(). It determines the size of the kernel nodemask_t (MAX_NUMNODES) by counting the size of Mems_allowed: in /proc/self/status. (And if that is not available, falls back to a procedure very similar to your max_numnode().) The patch, but using numa_num_possible_nodes() is below. It returns the same results, in my tests. Is there some subtle difference between numa_num_possible_nodes() and your function that I'm missing? -Cliff > - The loop set the node in the wrong mask, breaking the test > > v2: Correct max_numnode detection > > Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx> > > --- numactl-2.0.2/test/prefered.c 2008-08-05 16:36:58.000000000 +0200 > +++ numactl-2.0.2-hack/test/prefered.c 2009-01-10 07:00:16.000000000 +0100 > @@ -6,20 +6,38 @@ > #include <assert.h> > #include <unistd.h> > #include <stdlib.h> > +#include <errno.h> > > #define err(x) perror(x),exit(1) > > +/* Discover MAXNUMNODE of the kernel */ > +int max_numnode(void) > +{ > + int v; > + unsigned size = 64; > + struct bitmask *mask = numa_bitmask_alloc(size); > + while (get_mempolicy(NULL, mask->maskp, mask->size, &v, MPOL_F_ADDR) < 0 && > + errno == EINVAL) { > + numa_bitmask_free(mask); > + size <<= 1; > + mask = numa_bitmask_alloc(size); > + } > + numa_bitmask_free(mask); > + return size; > +} > + > int main(void) > { > int max = numa_max_node(); > + int maxmask = max_numnode(); > struct bitmask *nodes, *mask; > int pagesize = getpagesize(); > int i; > int pol; > int node; > int err = 0; > - nodes = numa_bitmask_alloc(max+1); > - mask = numa_bitmask_alloc(max+1); > + nodes = numa_bitmask_alloc(maxmask); > + mask = numa_bitmask_alloc(maxmask); > > for (i = max; i >= 0; --i) { > char *mem = mmap(NULL, pagesize*(max+1), PROT_READ|PROT_WRITE, > @@ -33,8 +51,8 @@ > > numa_bitmask_clearall(nodes); > numa_bitmask_clearall(mask); > - numa_bitmask_setbit(mask, i); > + numa_bitmask_setbit(nodes, i); > > if (mbind(adr, pagesize, MPOL_PREFERRED, nodes->maskp, > nodes->size, 0) < 0) > err("mbind"); --- test/prefered.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) Index: numactl-dev/test/prefered.c =================================================================== --- numactl-dev.orig/test/prefered.c +++ numactl-dev/test/prefered.c @@ -6,20 +6,22 @@ #include <assert.h> #include <unistd.h> #include <stdlib.h> +#include <errno.h> #define err(x) perror(x),exit(1) int main(void) { int max = numa_max_node(); + int maxmask = numa_num_possible_nodes(); struct bitmask *nodes, *mask; int pagesize = getpagesize(); int i; int pol; int node; int err = 0; - nodes = numa_bitmask_alloc(max+1); - mask = numa_bitmask_alloc(max+1); + nodes = numa_bitmask_alloc(maxmask); + mask = numa_bitmask_alloc(maxmask); for (i = max; i >= 0; --i) { char *mem = mmap(NULL, pagesize*(max+1), PROT_READ|PROT_WRITE, @@ -33,7 +35,7 @@ int main(void) numa_bitmask_clearall(nodes); numa_bitmask_clearall(mask); - numa_bitmask_setbit(mask, i); + numa_bitmask_setbit(nodes, i); if (mbind(adr, pagesize, MPOL_PREFERRED, nodes->maskp, nodes->size, 0) < 0) -- To unsubscribe from this list: send the line "unsubscribe linux-numa" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html