Skip to content

Commit

Permalink
mem: Fix short of nodemask array.
Browse files Browse the repository at this point in the history
In kernel, if user specified more nodes, e.g, 512 nodes, than the
supported, e.g, 4 nodes, kernel will check if the non supported
part, e.g, 508 nodes, is all zeroed in node bitmap. Currently, we
are overrunning "nmask", whose length is shorter than MAXNODES,
and where the unsupported bits should be cleared to pass the check.

Signed-off-by: Lans Zhang <[email protected]>
Reviewed-by: Jan Stancek <[email protected]>
Reviewed-by: Wanlong Gao <[email protected]>
Reviewed-by: Zhouping Liu <[email protected]>
Signed-off-by: Wanlong Gao <[email protected]>
  • Loading branch information
Lans Zhang authored and gaowanlong committed Apr 17, 2013
1 parent 6a9c0ed commit cb2967b
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 14 deletions.
11 changes: 7 additions & 4 deletions testcases/kernel/mem/cpuset/cpuset01.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static void testcpuset(void)
{
int lc;
int child, i, status;
unsigned long nmask = 0;
unsigned long nmask[MAXNODES / BITS_PER_LONG] = { 0 };
char mems[BUFSIZ], buf[BUFSIZ];

read_cpuset_files(CPATH, "cpus", buf);
Expand All @@ -107,9 +107,12 @@ static void testcpuset(void)
case -1:
tst_brkm(TBROK | TERRNO, cleanup, "fork");
case 0:
for (i = 0; i < nnodes; i++)
nmask += 1 << nodes[i];
if (set_mempolicy(MPOL_BIND, &nmask, MAXNODES) == -1)
for (i = 0; i < nnodes; i++) {
if (nodes[i] >= MAXNODES)
continue;
set_node(nmask, nodes[i]);
}
if (set_mempolicy(MPOL_BIND, nmask, MAXNODES) == -1)
tst_brkm(TBROK | TERRNO, cleanup, "set_mempolicy");
exit(mem_hog_cpuset(ncpus > 1 ? ncpus : 1));
}
Expand Down
6 changes: 6 additions & 0 deletions testcases/kernel/mem/include/mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
#define PATH_SYS_SYSTEM "/sys/devices/system"
#define PATH_SYSVM "/proc/sys/vm/"
#define PATH_MEMINFO "/proc/meminfo"
#define BITS_PER_LONG (8 * sizeof(long))

static inline void set_node(unsigned long *array, unsigned int node)
{
array[node / BITS_PER_LONG] |= 1UL << (node % BITS_PER_LONG);
}

/* OOM */

Expand Down
6 changes: 3 additions & 3 deletions testcases/kernel/mem/ksm/ksm02.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,23 @@ int main(int argc, char *argv[])
int lc;
char *msg;
int size = 128, num = 3, unit = 1;
unsigned long nmask = 0;
unsigned long nmask[MAXNODES / BITS_PER_LONG] = { 0 };
unsigned int node;

msg = parse_opts(argc, argv, ksm_options, ksm_usage);
if (msg != NULL)
tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

node = get_a_numa_node(tst_exit);
nmask = 1 << node;
set_node(nmask, node);

setup();

for (lc = 0; TEST_LOOPING(lc); lc++) {
tst_count = 0;
check_ksm_options(&size, &num, &unit);

if (set_mempolicy(MPOL_BIND, &nmask, MAXNODES) == -1) {
if (set_mempolicy(MPOL_BIND, nmask, MAXNODES) == -1) {
if (errno != ENOSYS)
tst_brkm(TBROK | TERRNO, cleanup,
"set_mempolicy");
Expand Down
6 changes: 3 additions & 3 deletions testcases/kernel/mem/ksm/ksm04.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ int main(int argc, char *argv[])
int lc;
char *msg;
int size = 128, num = 3, unit = 1;
unsigned long nmask = 0;
unsigned long nmask[MAXNODES / BITS_PER_LONG] = { 0 };
unsigned int node;

msg = parse_opts(argc, argv, ksm_options, ksm_usage);
if (msg != NULL)
tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

node = get_a_numa_node(tst_exit);
nmask = 1 << node;
set_node(nmask, node);

setup();

Expand All @@ -105,7 +105,7 @@ int main(int argc, char *argv[])

write_memcg();

if (set_mempolicy(MPOL_BIND, &nmask, MAXNODES) == -1) {
if (set_mempolicy(MPOL_BIND, nmask, MAXNODES) == -1) {
if (errno != ENOSYS)
tst_brkm(TBROK | TERRNO, cleanup,
"set_mempolicy");
Expand Down
9 changes: 5 additions & 4 deletions testcases/kernel/mem/lib/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static void set_global_mempolicy(int mempolicy)
{
#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
&& HAVE_MPOL_CONSTANTS
unsigned long nmask = 0;
unsigned long nmask[MAXNODES / BITS_PER_LONG] = { 0 };
unsigned int num_nodes, *nodes;
int ret;

Expand All @@ -112,7 +112,7 @@ static void set_global_mempolicy(int mempolicy)
switch(mempolicy) {
case MPOL_BIND:
/* bind the second node */
nmask = 1 << nodes[1];
set_node(nmask, nodes[1]);
break;
case MPOL_INTERLEAVE:
case MPOL_PREFERRED:
Expand All @@ -123,13 +123,14 @@ static void set_global_mempolicy(int mempolicy)
return;
} else {
/* Using the 2nd,3rd node */
nmask = (1 << nodes[1]) | (1 << nodes[2]);
set_node(nmask, nodes[1]);
set_node(nmask, nodes[2]);
}
break;
default:
tst_brkm(TBROK|TERRNO, cleanup, "Bad mempolicy mode");
}
if (set_mempolicy(mempolicy, &nmask, MAXNODES) == -1)
if (set_mempolicy(mempolicy, nmask, MAXNODES) == -1)
tst_brkm(TBROK|TERRNO, cleanup, "set_mempolicy");
}
#endif
Expand Down

0 comments on commit cb2967b

Please sign in to comment.