Skip to content

Commit 050c17f

Browse files
Ralph Campbelltorvalds
authored andcommitted
numa: change get_mempolicy() to use nr_node_ids instead of MAX_NUMNODES
The system call, get_mempolicy() [1], passes an unsigned long *nodemask pointer and an unsigned long maxnode argument which specifies the length of the user's nodemask array in bits (which is rounded up). The manual page says that if the maxnode value is too small, get_mempolicy will return EINVAL but there is no system call to return this minimum value. To determine this value, some programs search /proc/<pid>/status for a line starting with "Mems_allowed:" and use the number of digits in the mask to determine the minimum value. A recent change to the way this line is formatted [2] causes these programs to compute a value less than MAX_NUMNODES so get_mempolicy() returns EINVAL. Change get_mempolicy(), the older compat version of get_mempolicy(), and the copy_nodes_to_user() function to use nr_node_ids instead of MAX_NUMNODES, thus preserving the defacto method of computing the minimum size for the nodemask array and the maxnode argument. [1] http://man7.org/linux/man-pages/man2/get_mempolicy.2.html [2] https://lore.kernel.org/lkml/1545405631-6808-1-git-send-email-longman@redhat.com Link: http://lkml.kernel.org/r/20190211180245.22295-1-rcampbell@nvidia.com Fixes: 4fb8e5b ("include/linux/nodemask.h: use nr_node_ids (not MAX_NUMNODES) in __nodemask_pr_numnodes()") Signed-off-by: Ralph Campbell <rcampbell@nvidia.com> Suggested-by: Alexander Duyck <alexander.duyck@gmail.com> Cc: Waiman Long <longman@redhat.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent a841c67 commit 050c17f

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

mm/mempolicy.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,7 +1314,7 @@ static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
13141314
nodemask_t *nodes)
13151315
{
13161316
unsigned long copy = ALIGN(maxnode-1, 64) / 8;
1317-
const int nbytes = BITS_TO_LONGS(MAX_NUMNODES) * sizeof(long);
1317+
unsigned int nbytes = BITS_TO_LONGS(nr_node_ids) * sizeof(long);
13181318

13191319
if (copy > nbytes) {
13201320
if (copy > PAGE_SIZE)
@@ -1491,7 +1491,7 @@ static int kernel_get_mempolicy(int __user *policy,
14911491
int uninitialized_var(pval);
14921492
nodemask_t nodes;
14931493

1494-
if (nmask != NULL && maxnode < MAX_NUMNODES)
1494+
if (nmask != NULL && maxnode < nr_node_ids)
14951495
return -EINVAL;
14961496

14971497
err = do_get_mempolicy(&pval, &nodes, addr, flags);
@@ -1527,7 +1527,7 @@ COMPAT_SYSCALL_DEFINE5(get_mempolicy, int __user *, policy,
15271527
unsigned long nr_bits, alloc_size;
15281528
DECLARE_BITMAP(bm, MAX_NUMNODES);
15291529

1530-
nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
1530+
nr_bits = min_t(unsigned long, maxnode-1, nr_node_ids);
15311531
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
15321532

15331533
if (nmask)

0 commit comments

Comments
 (0)