The following commit has been merged into the core/rcu branch of tip: Commit-ID: 2c4885d24e64941702a8f81c8e83289823ba35d0 Gitweb: https://git.kernel.org/tip/2c4885d24e64941702a8f81c8e83289823ba35d0 Author: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx> AuthorDate: Sun, 21 Feb 2021 03:08:25 -05:00 Committer: Paul E. McKenney <paulmck@xxxxxxxxxx> CommitterDate: Mon, 08 Mar 2021 14:16:58 -08:00 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@xxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: "Paul E. McKenney" <paulmck@xxxxxxxxxx> Cc: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx> Cc: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Suggested-by: Yury Norov <yury.norov@xxxxxxxxx> # move it from CPU code Acked-by: Yury Norov <yury.norov@xxxxxxxxx> Signed-off-by: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx> Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx> --- Documentation/admin-guide/kernel-parameters.rst | 7 +++++- lib/bitmap.c | 22 ++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.rst b/Documentation/admin-guide/kernel-parameters.rst index 1132796..d6e3f67 100644 --- a/Documentation/admin-guide/kernel-parameters.rst +++ b/Documentation/admin-guide/kernel-parameters.rst @@ -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,... +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 diff --git a/lib/bitmap.c b/lib/bitmap.c index 833f152..9f4626a 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -519,11 +519,17 @@ static int bitmap_check_region(const struct region *r) 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 int len; + if (str[0] == 'N') { + *num = lastbit; + return str + 1; + } + len = _parse_integer(str, 10, &n); if (!len) 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) { - str = bitmap_getnum(str, &r->start); + unsigned int lastbit = r->nbits - 1; + + str = bitmap_getnum(str, &r->start, lastbit); if (IS_ERR(str)) return str; @@ -581,7 +589,7 @@ static const char *bitmap_parse_region(const char *str, struct region *r) if (*str != '-') return ERR_PTR(-EINVAL); - str = bitmap_getnum(str + 1, &r->end); + str = bitmap_getnum(str + 1, &r->end, lastbit); if (IS_ERR(str)) return str; @@ -591,14 +599,14 @@ static const char *bitmap_parse_region(const char *str, struct region *r) if (*str != ':') return ERR_PTR(-EINVAL); - str = bitmap_getnum(str + 1, &r->off); + str = bitmap_getnum(str + 1, &r->off, lastbit); if (IS_ERR(str)) return str; if (*str != '/') return ERR_PTR(-EINVAL); - return bitmap_getnum(str + 1, &r->group_len); + return bitmap_getnum(str + 1, &r->group_len, lastbit); no_end: r->end = r->start; @@ -625,6 +633,10 @@ no_pattern: * From each group will be used only defined amount of bits. * Syntax: range:used_size/group_size * 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: *