Skip to content

Commit

Permalink
cpumask: use nr_cpumask_bits for parsing functions
Browse files Browse the repository at this point in the history
Commit 513e3d2 ("cpumask: always use nr_cpu_ids in formatting and
parsing functions") converted both cpumask printing and parsing
functions to use nr_cpu_ids instead of nr_cpumask_bits.  While this was
okay for the printing functions as it just picked one of the two output
formats that we were alternating between depending on a kernel config,
doing the same for parsing wasn't okay.

nr_cpumask_bits can be either nr_cpu_ids or NR_CPUS.  We can always use
nr_cpu_ids but that is a variable while NR_CPUS is a constant, so it can
be more efficient to use NR_CPUS when we can get away with it.
Converting the printing functions to nr_cpu_ids makes sense because it
affects how the masks get presented to userspace and doesn't break
anything; however, using nr_cpu_ids for parsing functions can
incorrectly leave the higher bits uninitialized while reading in these
masks from userland.  As all testing and comparison functions use
nr_cpumask_bits which can be larger than nr_cpu_ids, the parsed cpumasks
can erroneously yield false negative results.

This made the taskstats interface incorrectly return -EINVAL even when
the inputs were correct.

Fix it by restoring the parse functions to use nr_cpumask_bits instead
of nr_cpu_ids.

Link: http://lkml.kernel.org/r/[email protected]
Fixes: 513e3d2 ("cpumask: always use nr_cpu_ids in formatting and parsing functions")
Signed-off-by: Tejun Heo <[email protected]>
Reported-by: Martin Steigerwald <[email protected]>
Debugged-by: Ben Hutchings <[email protected]>
Cc: <[email protected]>	[4.0+]
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
htejun authored and torvalds committed Feb 8, 2017
1 parent 0911d00 commit 4d59b6c
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions include/linux/cpumask.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ static inline void cpumask_copy(struct cpumask *dstp,
static inline int cpumask_parse_user(const char __user *buf, int len,
struct cpumask *dstp)
{
return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpu_ids);
return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpumask_bits);
}

/**
Expand All @@ -575,7 +575,7 @@ static inline int cpumask_parselist_user(const char __user *buf, int len,
struct cpumask *dstp)
{
return bitmap_parselist_user(buf, len, cpumask_bits(dstp),
nr_cpu_ids);
nr_cpumask_bits);
}

/**
Expand All @@ -590,7 +590,7 @@ static inline int cpumask_parse(const char *buf, struct cpumask *dstp)
char *nl = strchr(buf, '\n');
unsigned int len = nl ? (unsigned int)(nl - buf) : strlen(buf);

return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpu_ids);
return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpumask_bits);
}

/**
Expand All @@ -602,7 +602,7 @@ static inline int cpumask_parse(const char *buf, struct cpumask *dstp)
*/
static inline int cpulist_parse(const char *buf, struct cpumask *dstp)
{
return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpu_ids);
return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpumask_bits);
}

/**
Expand Down

0 comments on commit 4d59b6c

Please sign in to comment.