lib: bitmap: support "N" as an alias for size of bitmap

While this is done for all bitmaps, the original use case in mind was
for CPU masks and cpulist_parse() as described below.

It seems that a common configuration is to use the 1st couple cores for
housekeeping tasks.  This tends to leave the remaining ones to form a
pool of similarly configured cores to take on the real workload of
interest to the user.

So on machine A - with 32 cores, it could be 0-3 for "system" and then
4-31 being used in boot args like nohz_full=, or rcu_nocbs= as part of
setting up the worker pool of CPUs.

But then newer machine B is added, and it has 48 cores, and so while
the 0-3 part remains unchanged, the pool setup cpu list becomes 4-47.

Multiple deployment becomes easier when we can just simply replace 31
and 47 with "N" and let the system substitute in the actual number at
boot; a number that it knows better than we do.

Cc: Yury Norov <yury.norov@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Suggested-by: Yury Norov <yury.norov@gmail.com> # move it from CPU code
Acked-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
This commit is contained in:
Paul Gortmaker 2021-02-21 03:08:25 -05:00 committed by Paul E. McKenney
parent f3c869caef
commit 2c4885d24e
2 changed files with 24 additions and 5 deletions

View file

@ -68,6 +68,13 @@ For example one can add to the command line following parameter:
where the final item represents CPUs 100,101,125,126,150,151,... where the final item represents CPUs 100,101,125,126,150,151,...
The value "N" can be used to represent the numerically last CPU on the system,
i.e "foo_cpus=16-N" would be equivalent to "16-31" on a 32 core system.
Keep in mind that "N" is dynamic, so if system changes cause the bitmap width
to change, such as less cores in the CPU list, then N and any ranges using N
will also change. Use the same on a small 4 core system, and "16-N" becomes
"16-3" and now the same boot input will be flagged as invalid (start > end).
This document may not be entirely up to date and comprehensive. The command This document may not be entirely up to date and comprehensive. The command

View file

@ -519,11 +519,17 @@ static int bitmap_check_region(const struct region *r)
return 0; return 0;
} }
static const char *bitmap_getnum(const char *str, unsigned int *num) static const char *bitmap_getnum(const char *str, unsigned int *num,
unsigned int lastbit)
{ {
unsigned long long n; unsigned long long n;
unsigned int len; unsigned int len;
if (str[0] == 'N') {
*num = lastbit;
return str + 1;
}
len = _parse_integer(str, 10, &n); len = _parse_integer(str, 10, &n);
if (!len) if (!len)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
@ -571,7 +577,9 @@ static const char *bitmap_find_region_reverse(const char *start, const char *end
static const char *bitmap_parse_region(const char *str, struct region *r) static const char *bitmap_parse_region(const char *str, struct region *r)
{ {
str = bitmap_getnum(str, &r->start); unsigned int lastbit = r->nbits - 1;
str = bitmap_getnum(str, &r->start, lastbit);
if (IS_ERR(str)) if (IS_ERR(str))
return str; return str;
@ -581,7 +589,7 @@ static const char *bitmap_parse_region(const char *str, struct region *r)
if (*str != '-') if (*str != '-')
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
str = bitmap_getnum(str + 1, &r->end); str = bitmap_getnum(str + 1, &r->end, lastbit);
if (IS_ERR(str)) if (IS_ERR(str))
return str; return str;
@ -591,14 +599,14 @@ static const char *bitmap_parse_region(const char *str, struct region *r)
if (*str != ':') if (*str != ':')
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
str = bitmap_getnum(str + 1, &r->off); str = bitmap_getnum(str + 1, &r->off, lastbit);
if (IS_ERR(str)) if (IS_ERR(str))
return str; return str;
if (*str != '/') if (*str != '/')
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
return bitmap_getnum(str + 1, &r->group_len); return bitmap_getnum(str + 1, &r->group_len, lastbit);
no_end: no_end:
r->end = r->start; r->end = r->start;
@ -625,6 +633,10 @@ static const char *bitmap_parse_region(const char *str, struct region *r)
* From each group will be used only defined amount of bits. * From each group will be used only defined amount of bits.
* Syntax: range:used_size/group_size * Syntax: range:used_size/group_size
* Example: 0-1023:2/256 ==> 0,1,256,257,512,513,768,769 * Example: 0-1023:2/256 ==> 0,1,256,257,512,513,768,769
* The value 'N' can be used as a dynamically substituted token for the
* maximum allowed value; i.e (nmaskbits - 1). Keep in mind that it is
* dynamic, so if system changes cause the bitmap width to change, such
* as more cores in a CPU list, then any ranges using N will also change.
* *
* Returns: 0 on success, -errno on invalid input strings. Error values: * Returns: 0 on success, -errno on invalid input strings. Error values:
* *