All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] lib/bitmap.c: enhance map pattern
@ 2016-07-16  7:57 Noam Camus
  2016-07-16 12:09 ` Ben Hutchings
  2016-07-17  6:33 ` [PATCH v2] lib/bitmap.c: enhance bitmap syntax Noam Camus
  0 siblings, 2 replies; 15+ messages in thread
From: Noam Camus @ 2016-07-16  7:57 UTC (permalink / raw)
  To: decot; +Cc: ben, davem, akpm, xinhuix.pan, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

Today there are platforms with many CPUs (up to 4K).
Trying to boot only part of the CPUs may result in too long string.

For example lets take NPS platform that is part of arch/arc.
This platform have SMP system with 256 cores each with
16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
In this example there is total of 4K CPUs.
When one tries to boot only part of the HW threads from each core the
string representing the map may be long...
For example if for sake of performance we decided to boot only first half
of HW threads of each core the map will look like:
0-7,16-23,32,39,...,4080-4087

This patch introduce new format to accommodate with such use case.
I added an optional postfix to a range of CPUs which will choose
according to given modulo the desired range of reminders i.e.:
<cpu range>%modulo=<range of reminders>

For example above pattern can be described in new format like this:
0-4095%16=0-7

Note that this patch is backward compatible.

Signed-off-by: Noam Camus <noamca@mellanox.com>
---
 lib/bitmap.c |   44 ++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index c66da50..4f446bc 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -496,6 +496,9 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
  * ranges.  Consecutively set bits are shown as two hyphen-separated
  * decimal numbers, the smallest and largest bit numbers set in
  * the range.
+ * Optionally each range can be postfixed to denote that only parts of it
+ * should be set. The parts are the range of reminders modulo some value.
+ * i.e. range%mod=rem_range e.g. 0-1023%256=0-2 ==> 0,1,256,257,512,513,768,769
  *
  * Returns 0 on success, -errno on invalid input strings.
  * Error values:
@@ -507,12 +510,14 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		int is_user, unsigned long *maskp,
 		int nmaskbits)
 {
-	unsigned a, b;
+	unsigned int a, b, old_a, old_b, mod_val, mod_a, mod_b;
 	int c, old_c, totaldigits, ndigits;
 	const char __user __force *ubuf = (const char __user __force *)buf;
 	int at_start, in_range;
 
 	totaldigits = c = 0;
+	old_a = old_b = 0;
+	mod_val = mod_a = mod_b = 0;
 	bitmap_zero(maskp, nmaskbits);
 	do {
 		at_start = 1;
@@ -547,6 +552,23 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 			if ((totaldigits != ndigits) && isspace(old_c))
 				return -EINVAL;
 
+			if (c == '=') {
+				mod_val = a;
+				at_start = 1;
+				in_range = 0;
+				a = b = 0;
+				continue;
+			}
+
+			if (c == '%') {
+				old_a = a;
+				old_b = b;
+				at_start = 1;
+				in_range = 0;
+				a = b = 0;
+				continue;
+			}
+
 			if (c == '-') {
 				if (at_start || in_range)
 					return -EINVAL;
@@ -567,17 +589,31 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		}
 		if (ndigits == totaldigits)
 			continue;
+		if (mod_val) {
+			mod_a = a;
+			mod_b = b;
+			a = old_a;
+			b = old_b;
+			old_a = old_b = 0;
+		}
 		/* if no digit is after '-', it's wrong*/
 		if (at_start && in_range)
 			return -EINVAL;
-		if (!(a <= b))
+		if (!(a <= b) || !(mod_a <= mod_b))
 			return -EINVAL;
-		if (b >= nmaskbits)
+		if (b >= nmaskbits || (mod_val && (mod_b >= mod_val)))
 			return -ERANGE;
 		while (a <= b) {
-			set_bit(a, maskp);
+			if (mod_val) {
+				unsigned int rem = a % mod_val;
+
+				if (rem >= mod_a && rem <= mod_b)
+					set_bit(a, maskp);
+			} else
+				set_bit(a, maskp);
 			a++;
 		}
+		mod_val = mod_a = mod_b = 0;
 	} while (buflen && c == ',');
 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH] lib/bitmap.c: enhance map pattern
  2016-07-16  7:57 [PATCH] lib/bitmap.c: enhance map pattern Noam Camus
@ 2016-07-16 12:09 ` Ben Hutchings
  2016-07-17  6:33 ` [PATCH v2] lib/bitmap.c: enhance bitmap syntax Noam Camus
  1 sibling, 0 replies; 15+ messages in thread
From: Ben Hutchings @ 2016-07-16 12:09 UTC (permalink / raw)
  To: Noam Camus, decot; +Cc: davem, akpm, xinhuix.pan, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1485 bytes --]

On Sat, 2016-07-16 at 10:57 +0300, Noam Camus wrote:
> From: Noam Camus <noamca@mellanox.com>
> 
> Today there are platforms with many CPUs (up to 4K).
> Trying to boot only part of the CPUs may result in too long string.
> 
> For example lets take NPS platform that is part of arch/arc.
> This platform have SMP system with 256 cores each with
> 16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
> In this example there is total of 4K CPUs.
> When one tries to boot only part of the HW threads from each core the
> string representing the map may be long...
> For example if for sake of performance we decided to boot only first half
> of HW threads of each core the map will look like:
> 0-7,16-23,32,39,...,4080-4087
> 
> This patch introduce new format to accommodate with such use case.
> I added an optional postfix to a range of CPUs which will choose
> according to given modulo the desired range of reminders i.e.:
> %modulo=

This is a fairly awful syntax, and I question whether it belongs in
this generic code.

[...]
> + * Optionally each range can be postfixed to denote that only parts of it
> + * should be set. The parts are the range of reminders modulo some value.
> + * i.e. range%mod=rem_range e.g. 0-1023%256=0-2 ==> 0,1,256,257,512,513,768,769
[...]

This example seems to be wrong - did you mean '=0-1'?

Ben.

-- 

Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2] lib/bitmap.c: enhance bitmap syntax
  2016-07-16  7:57 [PATCH] lib/bitmap.c: enhance map pattern Noam Camus
  2016-07-16 12:09 ` Ben Hutchings
@ 2016-07-17  6:33 ` Noam Camus
  2016-07-17  8:10   ` [PATCH v3] " Noam Camus
  1 sibling, 1 reply; 15+ messages in thread
From: Noam Camus @ 2016-07-17  6:33 UTC (permalink / raw)
  To: decot; +Cc: ben, davem, akpm, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

Today there are platforms with many CPUs (up to 4K).
Trying to boot only part of the CPUs may result in too long string.

For example lets take NPS platform that is part of arch/arc.
This platform have SMP system with 256 cores each with
16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
In this example there is total of 4K CPUs.
When one tries to boot only part of the HW threads from each core the
string representing the map may be long...
For example if for sake of performance we decided to boot only first half
of HW threads of each core the map will look like:
0-7,16-23,32,39,...,4080-4087

This patch introduce new syntax to accommodate with such use case.
I added an optional postfix to a range of CPUs which will choose
according to given modulo the desired range of reminders i.e.:
	<cpus range>%modulo=<range of reminders>

For example, above map can be described in new symtax like this:
0-4095%16=0-7

Note that this patch is backward compatible with current syntax.

Signed-off-by: Noam Camus <noamca@mellanox.com>
---
Change Log:
Fixed typo at below example:
"0-1023%256=0-2" turned into "0-1023%256=0-1"

Syntax need to be yet more eligible for such generic code, ideas are welcomed.
---
 lib/bitmap.c |   44 ++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index c66da50..bccfd87 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -496,6 +496,9 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
  * ranges.  Consecutively set bits are shown as two hyphen-separated
  * decimal numbers, the smallest and largest bit numbers set in
  * the range.
+ * Optionally each range can be postfixed to denote that only parts of it
+ * should be set. The parts are the range of reminders modulo some value.
+ * i.e. range%mod=rem_range e.g. 0-1023%256=0-1 ==> 0,1,256,257,512,513,768,769
  *
  * Returns 0 on success, -errno on invalid input strings.
  * Error values:
@@ -507,12 +510,14 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		int is_user, unsigned long *maskp,
 		int nmaskbits)
 {
-	unsigned a, b;
+	unsigned int a, b, old_a, old_b, mod_val, mod_a, mod_b;
 	int c, old_c, totaldigits, ndigits;
 	const char __user __force *ubuf = (const char __user __force *)buf;
 	int at_start, in_range;
 
 	totaldigits = c = 0;
+	old_a = old_b = 0;
+	mod_val = mod_a = mod_b = 0;
 	bitmap_zero(maskp, nmaskbits);
 	do {
 		at_start = 1;
@@ -547,6 +552,23 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 			if ((totaldigits != ndigits) && isspace(old_c))
 				return -EINVAL;
 
+			if (c == '=') {
+				mod_val = a;
+				at_start = 1;
+				in_range = 0;
+				a = b = 0;
+				continue;
+			}
+
+			if (c == '%') {
+				old_a = a;
+				old_b = b;
+				at_start = 1;
+				in_range = 0;
+				a = b = 0;
+				continue;
+			}
+
 			if (c == '-') {
 				if (at_start || in_range)
 					return -EINVAL;
@@ -567,17 +589,31 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		}
 		if (ndigits == totaldigits)
 			continue;
+		if (mod_val) {
+			mod_a = a;
+			mod_b = b;
+			a = old_a;
+			b = old_b;
+			old_a = old_b = 0;
+		}
 		/* if no digit is after '-', it's wrong*/
 		if (at_start && in_range)
 			return -EINVAL;
-		if (!(a <= b))
+		if (!(a <= b) || !(mod_a <= mod_b))
 			return -EINVAL;
-		if (b >= nmaskbits)
+		if (b >= nmaskbits || (mod_val && (mod_b >= mod_val)))
 			return -ERANGE;
 		while (a <= b) {
-			set_bit(a, maskp);
+			if (mod_val) {
+				unsigned int rem = a % mod_val;
+
+				if (rem >= mod_a && rem <= mod_b)
+					set_bit(a, maskp);
+			} else
+				set_bit(a, maskp);
 			a++;
 		}
+		mod_val = mod_a = mod_b = 0;
 	} while (buflen && c == ',');
 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3] lib/bitmap.c: enhance bitmap syntax
  2016-07-17  6:33 ` [PATCH v2] lib/bitmap.c: enhance bitmap syntax Noam Camus
@ 2016-07-17  8:10   ` Noam Camus
  2016-07-17 13:50     ` Pan Xinhui
  2016-09-08 15:33     ` [PATCH v4] " Noam Camus
  0 siblings, 2 replies; 15+ messages in thread
From: Noam Camus @ 2016-07-17  8:10 UTC (permalink / raw)
  To: decot; +Cc: ben, davem, akpm, linux-kernel, Noam Camus

From: Noam Camus <noamca@mellanox.com>

Today there are platforms with many CPUs (up to 4K).
Trying to boot only part of the CPUs may result in too long string.

For example lets take NPS platform that is part of arch/arc.
This platform have SMP system with 256 cores each with
16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
In this example there is total of 4K CPUs.
When one tries to boot only part of the HW threads from each core the
string representing the map may be long...
For example if for sake of performance we decided to boot only first half
of HW threads of each core the map will look like:
0-7,16-23,32-39,...,4080-4087

This patch introduce new syntax to accommodate with such use case.
I added an optional postfix to a range of CPUs which will choose
according to given modulo the desired range of reminders i.e.:
	<cpus range>%modulo=<range of reminders>

For example, above map can be described in new syntax like this:
0-4095%16=0-7

Note that this patch is backward compatible with current syntax.

Signed-off-by: Noam Camus <noamca@mellanox.com>
---
Any sugestions for simpler syntax which keeps its generality are welcomed.

Change Log:
V2: Fix typo in example at function header for __bitmap_parselist()
V3: Fix typo in commit log and also typo at example
---
 lib/bitmap.c |   44 ++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index c66da50..bccfd87 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -496,6 +496,9 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
  * ranges.  Consecutively set bits are shown as two hyphen-separated
  * decimal numbers, the smallest and largest bit numbers set in
  * the range.
+ * Optionally each range can be postfixed to denote that only parts of it
+ * should be set. The parts are the range of reminders modulo some value.
+ * i.e. range%mod=rem_range e.g. 0-1023%256=0-1 ==> 0,1,256,257,512,513,768,769
  *
  * Returns 0 on success, -errno on invalid input strings.
  * Error values:
@@ -507,12 +510,14 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		int is_user, unsigned long *maskp,
 		int nmaskbits)
 {
-	unsigned a, b;
+	unsigned int a, b, old_a, old_b, mod_val, mod_a, mod_b;
 	int c, old_c, totaldigits, ndigits;
 	const char __user __force *ubuf = (const char __user __force *)buf;
 	int at_start, in_range;
 
 	totaldigits = c = 0;
+	old_a = old_b = 0;
+	mod_val = mod_a = mod_b = 0;
 	bitmap_zero(maskp, nmaskbits);
 	do {
 		at_start = 1;
@@ -547,6 +552,23 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 			if ((totaldigits != ndigits) && isspace(old_c))
 				return -EINVAL;
 
+			if (c == '=') {
+				mod_val = a;
+				at_start = 1;
+				in_range = 0;
+				a = b = 0;
+				continue;
+			}
+
+			if (c == '%') {
+				old_a = a;
+				old_b = b;
+				at_start = 1;
+				in_range = 0;
+				a = b = 0;
+				continue;
+			}
+
 			if (c == '-') {
 				if (at_start || in_range)
 					return -EINVAL;
@@ -567,17 +589,31 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		}
 		if (ndigits == totaldigits)
 			continue;
+		if (mod_val) {
+			mod_a = a;
+			mod_b = b;
+			a = old_a;
+			b = old_b;
+			old_a = old_b = 0;
+		}
 		/* if no digit is after '-', it's wrong*/
 		if (at_start && in_range)
 			return -EINVAL;
-		if (!(a <= b))
+		if (!(a <= b) || !(mod_a <= mod_b))
 			return -EINVAL;
-		if (b >= nmaskbits)
+		if (b >= nmaskbits || (mod_val && (mod_b >= mod_val)))
 			return -ERANGE;
 		while (a <= b) {
-			set_bit(a, maskp);
+			if (mod_val) {
+				unsigned int rem = a % mod_val;
+
+				if (rem >= mod_a && rem <= mod_b)
+					set_bit(a, maskp);
+			} else
+				set_bit(a, maskp);
 			a++;
 		}
+		mod_val = mod_a = mod_b = 0;
 	} while (buflen && c == ',');
 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v3] lib/bitmap.c: enhance bitmap syntax
  2016-07-17  8:10   ` [PATCH v3] " Noam Camus
@ 2016-07-17 13:50     ` Pan Xinhui
  2016-07-17 13:59       ` Pan Xinhui
  2016-09-08 15:33     ` [PATCH v4] " Noam Camus
  1 sibling, 1 reply; 15+ messages in thread
From: Pan Xinhui @ 2016-07-17 13:50 UTC (permalink / raw)
  To: Noam Camus, decot; +Cc: ben, davem, akpm, linux-kernel



在 16/7/17 16:10, Noam Camus 写道:
> From: Noam Camus <noamca@mellanox.com>
>
> Today there are platforms with many CPUs (up to 4K).
> Trying to boot only part of the CPUs may result in too long string.
>
> For example lets take NPS platform that is part of arch/arc.
> This platform have SMP system with 256 cores each with
> 16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
> In this example there is total of 4K CPUs.
> When one tries to boot only part of the HW threads from each core the
> string representing the map may be long...
> For example if for sake of performance we decided to boot only first half
> of HW threads of each core the map will look like:
> 0-7,16-23,32-39,...,4080-4087
>
> This patch introduce new syntax to accommodate with such use case.
> I added an optional postfix to a range of CPUs which will choose
> according to given modulo the desired range of reminders i.e.:
> 	<cpus range>%modulo=<range of reminders>
>
> For example, above map can be described in new syntax like this:
> 0-4095%16=0-7
>

I really think it is better to implement one function to generic a string which contanis the cpus you want to boot on, then pass this string to  __bitmap_parselist.

> Note that this patch is backward compatible with current syntax.
>
> Signed-off-by: Noam Camus <noamca@mellanox.com>
> ---
> Any sugestions for simpler syntax which keeps its generality are welcomed.
>
> Change Log:
> V2: Fix typo in example at function header for __bitmap_parselist()
> V3: Fix typo in commit log and also typo at example
> ---
>  lib/bitmap.c |   44 ++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 40 insertions(+), 4 deletions(-)
>
> diff --git a/lib/bitmap.c b/lib/bitmap.c
> index c66da50..bccfd87 100644
> --- a/lib/bitmap.c
> +++ b/lib/bitmap.c
> @@ -496,6 +496,9 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
>   * ranges.  Consecutively set bits are shown as two hyphen-separated
>   * decimal numbers, the smallest and largest bit numbers set in
>   * the range.
> + * Optionally each range can be postfixed to denote that only parts of it
> + * should be set. The parts are the range of reminders modulo some value.
> + * i.e. range%mod=rem_range e.g. 0-1023%256=0-1 ==> 0,1,256,257,512,513,768,769
>   *
>   * Returns 0 on success, -errno on invalid input strings.
>   * Error values:
> @@ -507,12 +510,14 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
>  		int is_user, unsigned long *maskp,
>  		int nmaskbits)
>  {
> -	unsigned a, b;
> +	unsigned int a, b, old_a, old_b, mod_val, mod_a, mod_b;
>  	int c, old_c, totaldigits, ndigits;
>  	const char __user __force *ubuf = (const char __user __force *)buf;
>  	int at_start, in_range;
>
>  	totaldigits = c = 0;
> +	old_a = old_b = 0;
> +	mod_val = mod_a = mod_b = 0;
>  	bitmap_zero(maskp, nmaskbits);
>  	do {
>  		at_start = 1;
> @@ -547,6 +552,23 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
>  			if ((totaldigits != ndigits) && isspace(old_c))
>  				return -EINVAL;
>
> +			if (c == '=') {
> +				mod_val = a;
> +				at_start = 1;
> +				in_range = 0;
> +				a = b = 0;
> +				continue;
> +			}
> +
> +			if (c == '%') {
> +				old_a = a;
> +				old_b = b;
> +				at_start = 1;
> +				in_range = 0;
> +				a = b = 0;
> +				continue;
> +			}
> +
>  			if (c == '-') {
>  				if (at_start || in_range)
>  					return -EINVAL;
> @@ -567,17 +589,31 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
>  		}
>  		if (ndigits == totaldigits)
>  			continue;
> +		if (mod_val) {
> +			mod_a = a;
> +			mod_b = b;
> +			a = old_a;
> +			b = old_b;
> +			old_a = old_b = 0;
> +		}
>  		/* if no digit is after '-', it's wrong*/
>  		if (at_start && in_range)
>  			return -EINVAL;
> -		if (!(a <= b))
> +		if (!(a <= b) || !(mod_a <= mod_b))
>  			return -EINVAL;
> -		if (b >= nmaskbits)
> +		if (b >= nmaskbits || (mod_val && (mod_b >= mod_val)))
>  			return -ERANGE;
>  		while (a <= b) {
> -			set_bit(a, maskp);
> +			if (mod_val) {
> +				unsigned int rem = a % mod_val;
> +
> +				if (rem >= mod_a && rem <= mod_b)
> +					set_bit(a, maskp);
> +			} else
> +				set_bit(a, maskp);
>  			a++;
>  		}
> +		mod_val = mod_a = mod_b = 0;
>  	} while (buflen && c == ',');
>  	return 0;
>  }
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3] lib/bitmap.c: enhance bitmap syntax
  2016-07-17 13:50     ` Pan Xinhui
@ 2016-07-17 13:59       ` Pan Xinhui
  2016-07-18  7:06         ` Noam Camus
  0 siblings, 1 reply; 15+ messages in thread
From: Pan Xinhui @ 2016-07-17 13:59 UTC (permalink / raw)
  To: Noam Camus, decot; +Cc: ben, davem, akpm, linux-kernel



在 16/7/17 21:50, Pan Xinhui 写道:
>
>
> 在 16/7/17 16:10, Noam Camus 写道:
>> From: Noam Camus <noamca@mellanox.com>
>>
>> Today there are platforms with many CPUs (up to 4K).
>> Trying to boot only part of the CPUs may result in too long string.
>>
>> For example lets take NPS platform that is part of arch/arc.
>> This platform have SMP system with 256 cores each with
>> 16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
>> In this example there is total of 4K CPUs.
>> When one tries to boot only part of the HW threads from each core the
>> string representing the map may be long...
>> For example if for sake of performance we decided to boot only first half
>> of HW threads of each core the map will look like:
>> 0-7,16-23,32-39,...,4080-4087
>>
>> This patch introduce new syntax to accommodate with such use case.
>> I added an optional postfix to a range of CPUs which will choose
>> according to given modulo the desired range of reminders i.e.:
>>     <cpus range>%modulo=<range of reminders>
>>
>> For example, above map can be described in new syntax like this:
>> 0-4095%16=0-7
>>
>
> I really think it is better to implement one function to generic a string which contanis the cpus you want to boot on, then pass this string to  __bitmap_parselist.
>
sorry, typos.
generic -> generate.

>> Note that this patch is backward compatible with current syntax.
>>
>> Signed-off-by: Noam Camus <noamca@mellanox.com>
>> ---
>> Any sugestions for simpler syntax which keeps its generality are welcomed.
>>
>> Change Log:
>> V2: Fix typo in example at function header for __bitmap_parselist()
>> V3: Fix typo in commit log and also typo at example
>> ---
>>  lib/bitmap.c |   44 ++++++++++++++++++++++++++++++++++++++++----
>>  1 files changed, 40 insertions(+), 4 deletions(-)
>>
>> diff --git a/lib/bitmap.c b/lib/bitmap.c
>> index c66da50..bccfd87 100644
>> --- a/lib/bitmap.c
>> +++ b/lib/bitmap.c
>> @@ -496,6 +496,9 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
>>   * ranges.  Consecutively set bits are shown as two hyphen-separated
>>   * decimal numbers, the smallest and largest bit numbers set in
>>   * the range.
>> + * Optionally each range can be postfixed to denote that only parts of it
>> + * should be set. The parts are the range of reminders modulo some value.
>> + * i.e. range%mod=rem_range e.g. 0-1023%256=0-1 ==> 0,1,256,257,512,513,768,769
>>   *
>>   * Returns 0 on success, -errno on invalid input strings.
>>   * Error values:
>> @@ -507,12 +510,14 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
>>          int is_user, unsigned long *maskp,
>>          int nmaskbits)
>>  {
>> -    unsigned a, b;
>> +    unsigned int a, b, old_a, old_b, mod_val, mod_a, mod_b;
>>      int c, old_c, totaldigits, ndigits;
>>      const char __user __force *ubuf = (const char __user __force *)buf;
>>      int at_start, in_range;
>>
>>      totaldigits = c = 0;
>> +    old_a = old_b = 0;
>> +    mod_val = mod_a = mod_b = 0;
>>      bitmap_zero(maskp, nmaskbits);
>>      do {
>>          at_start = 1;
>> @@ -547,6 +552,23 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
>>              if ((totaldigits != ndigits) && isspace(old_c))
>>                  return -EINVAL;
>>
>> +            if (c == '=') {
>> +                mod_val = a;
>> +                at_start = 1;
>> +                in_range = 0;
>> +                a = b = 0;
>> +                continue;
>> +            }
>> +
>> +            if (c == '%') {
>> +                old_a = a;
>> +                old_b = b;
>> +                at_start = 1;
>> +                in_range = 0;
>> +                a = b = 0;
>> +                continue;
>> +            }
>> +
>>              if (c == '-') {
>>                  if (at_start || in_range)
>>                      return -EINVAL;
>> @@ -567,17 +589,31 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
>>          }
>>          if (ndigits == totaldigits)
>>              continue;
>> +        if (mod_val) {
>> +            mod_a = a;
>> +            mod_b = b;
>> +            a = old_a;
>> +            b = old_b;
>> +            old_a = old_b = 0;
>> +        }
>>          /* if no digit is after '-', it's wrong*/
>>          if (at_start && in_range)
>>              return -EINVAL;
>> -        if (!(a <= b))
>> +        if (!(a <= b) || !(mod_a <= mod_b))
>>              return -EINVAL;
>> -        if (b >= nmaskbits)
>> +        if (b >= nmaskbits || (mod_val && (mod_b >= mod_val)))
>>              return -ERANGE;
>>          while (a <= b) {
>> -            set_bit(a, maskp);
>> +            if (mod_val) {
>> +                unsigned int rem = a % mod_val;
>> +
>> +                if (rem >= mod_a && rem <= mod_b)
>> +                    set_bit(a, maskp);
>> +            } else
>> +                set_bit(a, maskp);
>>              a++;
>>          }
>> +        mod_val = mod_a = mod_b = 0;
>>      } while (buflen && c == ',');
>>      return 0;
>>  }
>>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v3] lib/bitmap.c: enhance bitmap syntax
  2016-07-17 13:59       ` Pan Xinhui
@ 2016-07-18  7:06         ` Noam Camus
  2016-08-01  4:53           ` Noam Camus
  2016-09-06  9:12           ` Noam Camus
  0 siblings, 2 replies; 15+ messages in thread
From: Noam Camus @ 2016-07-18  7:06 UTC (permalink / raw)
  To: Pan Xinhui, decot; +Cc: ben, davem, akpm, linux-kernel

> From: Pan Xinhui [mailto:xinhui@linux.vnet.ibm.com] 
> Sent: Sunday, July 17, 2016 4:59 PM

>>
>> I really think it is better to implement one function to generic a string which contanis the cpus you want to boot on, then pass this string to  __bitmap_parselist.
>>
> sorry, typos.
> generic -> generate.

Please explain how this will solve the syntax issue Ben commented on?

Another syntax which might be simpler is:
<first cpu-last cpu>:<numcpus selected from group>/<cpus group size>
e.g.
0-1023:1/2 <==> 0,2,4,...,1022
1-1023:1/2 <==> 1,3,5,...,1023

So basically no need for modulo only divide the list into groups of cpus and for each group choose cpus from group start.
It is basically achieves same and hopefully more  simpler and more eligible for such generic code.

Please let me know what you think?
Is it good direction to change the syntax, or that I should turn into different approach (like Pan suggested)?

Noam.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v3] lib/bitmap.c: enhance bitmap syntax
  2016-07-18  7:06         ` Noam Camus
@ 2016-08-01  4:53           ` Noam Camus
  2016-09-06  9:12           ` Noam Camus
  1 sibling, 0 replies; 15+ messages in thread
From: Noam Camus @ 2016-08-01  4:53 UTC (permalink / raw)
  To: Pan Xinhui, decot, Ben Hutchings; +Cc: ben, davem, akpm, linux-kernel

Ping...

-----Original Message-----
From: Noam Camus 
Sent: Monday, July 18, 2016 10:06 AM
To: Pan Xinhui <xinhui@linux.vnet.ibm.com>; decot@googlers.com
Cc: ben@decadent.org.uk; davem@davemloft.net; akpm@linux-foundation.org; linux-kernel@vger.kernel.org
Subject: RE: [PATCH v3] lib/bitmap.c: enhance bitmap syntax

> From: Pan Xinhui [mailto:xinhui@linux.vnet.ibm.com]
> Sent: Sunday, July 17, 2016 4:59 PM

>>
>> I really think it is better to implement one function to generic a string which contanis the cpus you want to boot on, then pass this string to  __bitmap_parselist.
>>
> sorry, typos.
> generic -> generate.

Please explain how this will solve the syntax issue Ben commented on?

Another syntax which might be simpler is:
<first cpu-last cpu>:<numcpus selected from group>/<cpus group size> e.g.
0-1023:1/2 <==> 0,2,4,...,1022
1-1023:1/2 <==> 1,3,5,...,1023

So basically no need for modulo only divide the list into groups of cpus and for each group choose cpus from group start.
It is basically achieves same and hopefully more  simpler and more eligible for such generic code.

Please let me know what you think?
Is it good direction to change the syntax, or that I should turn into different approach (like Pan suggested)?

Noam.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v3] lib/bitmap.c: enhance bitmap syntax
  2016-07-18  7:06         ` Noam Camus
  2016-08-01  4:53           ` Noam Camus
@ 2016-09-06  9:12           ` Noam Camus
  2016-09-06 13:36             ` Ben Hutchings
  1 sibling, 1 reply; 15+ messages in thread
From: Noam Camus @ 2016-09-06  9:12 UTC (permalink / raw)
  To: Pan Xinhui, decot, Ben Hutchings; +Cc: ben, davem, akpm, linux-kernel

Hi Ben, Pan

This is a second ping.

Will appreciate your feedback wither changing syntax will do the change or that I need a different approach to achieve such enhancement.
See below for new syntax suggestion.

-Noam 

-----Original Message-----
From: Noam Camus 
Sent: Monday, August 01, 2016 7:53 AM
To: 'Pan Xinhui' <xinhui@linux.vnet.ibm.com>; 'decot@googlers.com' <decot@googlers.com>; 'Ben Hutchings' <ben@decadent.org.uk>
Cc: 'ben@decadent.org.uk' <ben@decadent.org.uk>; 'davem@davemloft.net' <davem@davemloft.net>; 'akpm@linux-foundation.org' <akpm@linux-foundation.org>; 'linux-kernel@vger.kernel.org' <linux-kernel@vger.kernel.org>
Subject: RE: [PATCH v3] lib/bitmap.c: enhance bitmap syntax

Ping...

-----Original Message-----
From: Noam Camus 
Sent: Monday, July 18, 2016 10:06 AM
To: Pan Xinhui <xinhui@linux.vnet.ibm.com>; decot@googlers.com
Cc: ben@decadent.org.uk; davem@davemloft.net; akpm@linux-foundation.org; linux-kernel@vger.kernel.org
Subject: RE: [PATCH v3] lib/bitmap.c: enhance bitmap syntax

> From: Pan Xinhui [mailto:xinhui@linux.vnet.ibm.com]
> Sent: Sunday, July 17, 2016 4:59 PM

>>
>> I really think it is better to implement one function to generic a string which contanis the cpus you want to boot on, then pass this string to  __bitmap_parselist.
>>
> sorry, typos.
> generic -> generate.

Please explain how this will solve the syntax issue Ben commented on?

Another syntax which might be simpler is:
<first cpu-last cpu>:<numcpus selected from group>/<cpus group size> e.g.
0-1023:1/2 <==> 0,2,4,...,1022
1-1023:1/2 <==> 1,3,5,...,1023

So basically no need for modulo only divide the list into groups of cpus and for each group choose cpus from group start.
It is basically achieves same and hopefully more  simpler and more eligible for such generic code.

Please let me know what you think?
Is it good direction to change the syntax, or that I should turn into different approach (like Pan suggested)?

Noam.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3] lib/bitmap.c: enhance bitmap syntax
  2016-09-06  9:12           ` Noam Camus
@ 2016-09-06 13:36             ` Ben Hutchings
  0 siblings, 0 replies; 15+ messages in thread
From: Ben Hutchings @ 2016-09-06 13:36 UTC (permalink / raw)
  To: Noam Camus, Pan Xinhui, decot; +Cc: davem, akpm, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 428 bytes --]

On Tue, 2016-09-06 at 09:12 +0000, Noam Camus wrote:
> Hi Ben, Pan
> 
> This is a second ping.
> 
> Will appreciate your feedback wither changing syntax will do the
> change or that I need a different approach to achieve such
> enhancement.
> See below for new syntax suggestion.
[...]

This syntax does look better to me.

Ben.

-- 
Ben Hutchings
Never put off till tomorrow what you can avoid all together.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v4] lib/bitmap.c: enhance bitmap syntax
  2016-07-17  8:10   ` [PATCH v3] " Noam Camus
  2016-07-17 13:50     ` Pan Xinhui
@ 2016-09-08 15:33     ` Noam Camus
  2016-09-08 22:19       ` Andrew Morton
  2016-09-11  7:40       ` [PATCH v5] " Noam Camus
  1 sibling, 2 replies; 15+ messages in thread
From: Noam Camus @ 2016-09-08 15:33 UTC (permalink / raw)
  To: decot; +Cc: ben, davem, akpm, linux-kernel, xinhui, Noam Camus

From: Noam Camus <noamca@mellanox.com>

Today there are platforms with many CPUs (up to 4K).
Trying to boot only part of the CPUs may result in too long string.

For example lets take NPS platform that is part of arch/arc.
This platform have SMP system with 256 cores each with
16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
In this example there is total of 4K CPUs.
When one tries to boot only part of the HW threads from each core the
string representing the map may be long...
For example if for sake of performance we decided to boot only first half
of HW threads of each core the map will look like:
0-7,16-23,32-39,...,4080-4087

This patch introduce new syntax to accommodate with such use case.
I added an optional postfix to a range of CPUs which will choose
according to given modulo the desired range of reminders i.e.:
    <cpus range>:sed_size/group_size

For example, above map can be described in new syntax like this:
0-4095:8/16

Note that this patch is backward compatible with current syntax.

Signed-off-by: Noam Camus <noamca@mellanox.com>
---
 lib/bitmap.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index c66da50..9fb2cbc 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -496,6 +496,11 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
  * ranges.  Consecutively set bits are shown as two hyphen-separated
  * decimal numbers, the smallest and largest bit numbers set in
  * the range.
+ * Optionally each range can be postfixed to denote that only parts of it
+ * should be set. The range will divided to groups of specific size.
+ * 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
  *
  * Returns 0 on success, -errno on invalid input strings.
  * Error values:
@@ -507,16 +512,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		int is_user, unsigned long *maskp,
 		int nmaskbits)
 {
-	unsigned a, b;
+	unsigned int a, b, old_a, old_b;
+	unsigned int group_size, used_size;
 	int c, old_c, totaldigits, ndigits;
 	const char __user __force *ubuf = (const char __user __force *)buf;
-	int at_start, in_range;
+	int at_start, in_range, in_partial_range;
 
 	totaldigits = c = 0;
+	old_a = old_b = 0;
+	group_size = used_size = 0;
 	bitmap_zero(maskp, nmaskbits);
 	do {
 		at_start = 1;
 		in_range = 0;
+		in_partial_range = 0;
 		a = b = 0;
 		ndigits = totaldigits;
 
@@ -547,6 +556,24 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 			if ((totaldigits != ndigits) && isspace(old_c))
 				return -EINVAL;
 
+			if (c == '/') {
+				used_size = a;
+				at_start = 1;
+				in_range = 0;
+				a = b = 0;
+				continue;
+			}
+
+			if (c == ':') {
+				old_a = a;
+				old_b = b;
+				at_start = 1;
+				in_range = 0;
+				in_partial_range = 1;
+				a = b = 0;
+				continue;
+			}
+
 			if (c == '-') {
 				if (at_start || in_range)
 					return -EINVAL;
@@ -567,15 +594,30 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		}
 		if (ndigits == totaldigits)
 			continue;
+		if (in_partial_range) {
+			group_size = a;
+			a = old_a;
+			b = old_b;
+			old_a = old_b = 0;
+		}
 		/* if no digit is after '-', it's wrong*/
 		if (at_start && in_range)
 			return -EINVAL;
-		if (!(a <= b))
+		if (!(a <= b) || !(used_size <= group_size))
 			return -EINVAL;
 		if (b >= nmaskbits)
 			return -ERANGE;
 		while (a <= b) {
-			set_bit(a, maskp);
+			if (in_partial_range) {
+				static int pos_in_group = 1;
+
+				if (pos_in_group <= used_size)
+					set_bit(a, maskp);
+
+				if (a == b || ++pos_in_group > group_size)
+					pos_in_group = 1;
+			} else
+				set_bit(a, maskp);
 			a++;
 		}
 	} while (buflen && c == ',');
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v4] lib/bitmap.c: enhance bitmap syntax
  2016-09-08 15:33     ` [PATCH v4] " Noam Camus
@ 2016-09-08 22:19       ` Andrew Morton
  2016-09-11  7:40       ` [PATCH v5] " Noam Camus
  1 sibling, 0 replies; 15+ messages in thread
From: Andrew Morton @ 2016-09-08 22:19 UTC (permalink / raw)
  To: Noam Camus; +Cc: decot, ben, davem, linux-kernel, xinhui

On Thu, 8 Sep 2016 18:33:25 +0300 Noam Camus <noamca@mellanox.com> wrote:

> Today there are platforms with many CPUs (up to 4K).
> Trying to boot only part of the CPUs may result in too long string.
> 
> For example lets take NPS platform that is part of arch/arc.
> This platform have SMP system with 256 cores each with
> 16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
> In this example there is total of 4K CPUs.
> When one tries to boot only part of the HW threads from each core the
> string representing the map may be long...
> For example if for sake of performance we decided to boot only first half
> of HW threads of each core the map will look like:
> 0-7,16-23,32-39,...,4080-4087
> 
> This patch introduce new syntax to accommodate with such use case.
> I added an optional postfix to a range of CPUs which will choose
> according to given modulo the desired range of reminders i.e.:
>     <cpus range>:sed_size/group_size
> 
> For example, above map can be described in new syntax like this:
> 0-4095:8/16

There should be some updates to the user-facing documentation, please. 
Documentation/kernel-parameters.txt, mainly.  Which boot parameters
does this affect?  For example, I think it accidentally alters
isolcpus=?

It would be useful to see the patch which wires this up (to arch/arc?).

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v5] lib/bitmap.c: enhance bitmap syntax
  2016-09-08 15:33     ` [PATCH v4] " Noam Camus
  2016-09-08 22:19       ` Andrew Morton
@ 2016-09-11  7:40       ` Noam Camus
  2016-09-13 22:54         ` Andrew Morton
  1 sibling, 1 reply; 15+ messages in thread
From: Noam Camus @ 2016-09-11  7:40 UTC (permalink / raw)
  To: decot; +Cc: ben, davem, akpm, linux-kernel, xinhui, Noam Camus

From: Noam Camus <noamca@mellanox.com>

Today there are platforms with many CPUs (up to 4K).
Trying to boot only part of the CPUs may result in too long string.

For example lets take NPS platform that is part of arch/arc.
This platform have SMP system with 256 cores each with
16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
In this example there is total of 4K CPUs.
When one tries to boot only part of the HW threads from each core the
string representing the map may be long...
For example if for sake of performance we decided to boot only first half
of HW threads of each core the map will look like:
0-7,16-23,32-39,...,4080-4087

This patch introduce new syntax to accommodate with such use case.
I added an optional postfix to a range of CPUs which will choose
according to given modulo the desired range of reminders i.e.:
    <cpus range>:sed_size/group_size

For example, above map can be described in new syntax like this:
0-4095:8/16

Note that this patch is backward compatible with current syntax.

Signed-off-by: Noam Camus <noamca@mellanox.com>
---
 Documentation/kernel-parameters.txt |   15 ++++++++++
 lib/bitmap.c                        |   50 ++++++++++++++++++++++++++++++++---
 2 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 623502e..4f1e95b 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -33,6 +33,21 @@ can also be entered as
 Double-quotes can be used to protect spaces in values, e.g.:
 	param="spaces in here"
 
+Some of the kernel parameters takes list of CPUs as value e.g.:
+isolcpus, task_isolation, nohz_full, irqaffinity, rcu_nocbs.
+The format of this list is:
+<cpu number>,...,<cpu number>
+or
+<cpu number>-<cpu number>
+(must be a positive range in ascending order)
+or a mixture
+<cpu number>,...,<cpu number>-<cpu number>
+Note that for special case of range one can split range into equal size of groups
+and for each group to use some amount form the begin of that group.
+<cpu number>-cpu number>:<used size>/<group size>
+For example one can add to its command line following parameter:
+isolcpus=1,2,10-20,100-2000:2/25
+
 This document may not be entirely up to date and comprehensive. The command
 "modinfo -p ${modulename}" shows a current list of all parameters of a loadable
 module. Loadable modules, after being loaded into the running kernel, also
diff --git a/lib/bitmap.c b/lib/bitmap.c
index c66da50..9fb2cbc 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -496,6 +496,11 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
  * ranges.  Consecutively set bits are shown as two hyphen-separated
  * decimal numbers, the smallest and largest bit numbers set in
  * the range.
+ * Optionally each range can be postfixed to denote that only parts of it
+ * should be set. The range will divided to groups of specific size.
+ * 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
  *
  * Returns 0 on success, -errno on invalid input strings.
  * Error values:
@@ -507,16 +512,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		int is_user, unsigned long *maskp,
 		int nmaskbits)
 {
-	unsigned a, b;
+	unsigned int a, b, old_a, old_b;
+	unsigned int group_size, used_size;
 	int c, old_c, totaldigits, ndigits;
 	const char __user __force *ubuf = (const char __user __force *)buf;
-	int at_start, in_range;
+	int at_start, in_range, in_partial_range;
 
 	totaldigits = c = 0;
+	old_a = old_b = 0;
+	group_size = used_size = 0;
 	bitmap_zero(maskp, nmaskbits);
 	do {
 		at_start = 1;
 		in_range = 0;
+		in_partial_range = 0;
 		a = b = 0;
 		ndigits = totaldigits;
 
@@ -547,6 +556,24 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 			if ((totaldigits != ndigits) && isspace(old_c))
 				return -EINVAL;
 
+			if (c == '/') {
+				used_size = a;
+				at_start = 1;
+				in_range = 0;
+				a = b = 0;
+				continue;
+			}
+
+			if (c == ':') {
+				old_a = a;
+				old_b = b;
+				at_start = 1;
+				in_range = 0;
+				in_partial_range = 1;
+				a = b = 0;
+				continue;
+			}
+
 			if (c == '-') {
 				if (at_start || in_range)
 					return -EINVAL;
@@ -567,15 +594,30 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
 		}
 		if (ndigits == totaldigits)
 			continue;
+		if (in_partial_range) {
+			group_size = a;
+			a = old_a;
+			b = old_b;
+			old_a = old_b = 0;
+		}
 		/* if no digit is after '-', it's wrong*/
 		if (at_start && in_range)
 			return -EINVAL;
-		if (!(a <= b))
+		if (!(a <= b) || !(used_size <= group_size))
 			return -EINVAL;
 		if (b >= nmaskbits)
 			return -ERANGE;
 		while (a <= b) {
-			set_bit(a, maskp);
+			if (in_partial_range) {
+				static int pos_in_group = 1;
+
+				if (pos_in_group <= used_size)
+					set_bit(a, maskp);
+
+				if (a == b || ++pos_in_group > group_size)
+					pos_in_group = 1;
+			} else
+				set_bit(a, maskp);
 			a++;
 		}
 	} while (buflen && c == ',');
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v5] lib/bitmap.c: enhance bitmap syntax
  2016-09-11  7:40       ` [PATCH v5] " Noam Camus
@ 2016-09-13 22:54         ` Andrew Morton
  2016-09-14  6:52           ` Noam Camus
  0 siblings, 1 reply; 15+ messages in thread
From: Andrew Morton @ 2016-09-13 22:54 UTC (permalink / raw)
  To: Noam Camus; +Cc: decot, ben, davem, linux-kernel, xinhui

On Sun, 11 Sep 2016 10:40:29 +0300 Noam Camus <noamca@mellanox.com> wrote:

> From: Noam Camus <noamca@mellanox.com>
> 
> Today there are platforms with many CPUs (up to 4K).
> Trying to boot only part of the CPUs may result in too long string.
> 
> For example lets take NPS platform that is part of arch/arc.
> This platform have SMP system with 256 cores each with
> 16 HW threads (SMT machine) where HW thread appears as CPU to the kernel.
> In this example there is total of 4K CPUs.
> When one tries to boot only part of the HW threads from each core the
> string representing the map may be long...
> For example if for sake of performance we decided to boot only first half
> of HW threads of each core the map will look like:
> 0-7,16-23,32-39,...,4080-4087
> 
> This patch introduce new syntax to accommodate with such use case.
> I added an optional postfix to a range of CPUs which will choose
> according to given modulo the desired range of reminders i.e.:
>     <cpus range>:sed_size/group_size
> 
> For example, above map can be described in new syntax like this:
> 0-4095:8/16
> 
> Note that this patch is backward compatible with current syntax.
> 
> Signed-off-by: Noam Camus <noamca@mellanox.com>
> ---
>  Documentation/kernel-parameters.txt |   15 ++++++++++
>  lib/bitmap.c                        |   50 ++++++++++++++++++++++++++++++++---
>  2 files changed, 61 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 623502e..4f1e95b 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -33,6 +33,21 @@ can also be entered as
>  Double-quotes can be used to protect spaces in values, e.g.:
>  	param="spaces in here"
>  
> +Some of the kernel parameters takes list of CPUs as value e.g.:
> +isolcpus, task_isolation, nohz_full, irqaffinity, rcu_nocbs.

I don't think we have a "task_isolation".  What are you trying to
refer to here?

> +The format of this list is:
> +<cpu number>,...,<cpu number>
> +or
> +<cpu number>-<cpu number>
> +(must be a positive range in ascending order)
> +or a mixture
> +<cpu number>,...,<cpu number>-<cpu number>
> +Note that for special case of range one can split range into equal size of groups
> +and for each group to use some amount form the begin of that group.
> +<cpu number>-cpu number>:<used size>/<group size>
> +For example one can add to its command line following parameter:
> +isolcpus=1,2,10-20,100-2000:2/25
> +

I think we can do better here.  Please review:

--- a/Documentation/kernel-parameters.txt~lib-bitmapc-enhance-bitmap-syntax-fix
+++ a/Documentation/kernel-parameters.txt
@@ -33,20 +33,36 @@ can also be entered as
 Double-quotes can be used to protect spaces in values, e.g.:
 	param="spaces in here"
 
-Some of the kernel parameters takes list of CPUs as value e.g.:
-isolcpus, task_isolation, nohz_full, irqaffinity, rcu_nocbs.
-The format of this list is:
-<cpu number>,...,<cpu number>
+cpu lists:
+----------
+
+Some kernel parameters take a list of CPUs as a value, e.g.  isolcpus,
+nohz_full, irqaffinity, rcu_nocbs.  The format of this list is:
+
+	<cpu number>,...,<cpu number>
+
 or
-<cpu number>-<cpu number>
-(must be a positive range in ascending order)
+
+	<cpu number>-<cpu number>
+	(must be a positive range in ascending order)
+
 or a mixture
+
 <cpu number>,...,<cpu number>-<cpu number>
-Note that for special case of range one can split range into equal size of groups
-and for each group to use some amount form the begin of that group.
-<cpu number>-cpu number>:<used size>/<group size>
-For example one can add to its command line following parameter:
-isolcpus=1,2,10-20,100-2000:2/25
+
+Note that for the special case of a range one can split the range into equal
+sized groups and for each group use some amount from the beginning of that
+group:
+
+	<cpu number>-cpu number>:<used size>/<group size>
+
+For example one can add to the command line following parameter:
+
+	isolcpus=1,2,10-20,100-2000:2/25
+
+where the final item represents CPUs 100,101,125,126,150,151,...
+
+
 
 This document may not be entirely up to date and comprehensive. The command
 "modinfo -p ${modulename}" shows a current list of all parameters of a loadable
@@ -1776,13 +1792,7 @@ bytes respectively. Such letter suffixes
 			See Documentation/filesystems/nfs/nfsroot.txt.
 
 	irqaffinity=	[SMP] Set the default irq affinity mask
-			Format:
-			<cpu number>,...,<cpu number>
-			or
-			<cpu number>-<cpu number>
-			(must be a positive range in ascending order)
-			or a mixture
-			<cpu number>,...,<cpu number>-<cpu number>
+			The argument is a cpu list, as described above.
 
 	irqfixup	[HW]
 			When an interrupt is not handled search all handlers
@@ -1799,13 +1809,7 @@ bytes respectively. Such letter suffixes
 			Format: <RDP>,<reset>,<pci_scan>,<verbosity>
 
 	isolcpus=	[KNL,SMP] Isolate CPUs from the general scheduler.
-			Format:
-			<cpu number>,...,<cpu number>
-			or
-			<cpu number>-<cpu number>
-			(must be a positive range in ascending order)
-			or a mixture
-			<cpu number>,...,<cpu number>-<cpu number>
+			The argument is a cpu list, as described above.
 
 			This option can be used to specify one or more CPUs
 			to isolate from the general SMP balancing and scheduling
@@ -2666,6 +2670,7 @@ bytes respectively. Such letter suffixes
 			Default: on
 
 	nohz_full=	[KNL,BOOT]
+			The argument is a cpu list, as described above.
 			In kernels built with CONFIG_NO_HZ_FULL=y, set
 			the specified list of CPUs whose tick will be stopped
 			whenever possible. The boot CPU will be forced outside
@@ -3268,6 +3273,8 @@ bytes respectively. Such letter suffixes
 			See Documentation/blockdev/ramdisk.txt.
 
 	rcu_nocbs=	[KNL]
+			The argument is a cpu list, as described above.
+
 			In kernels built with CONFIG_RCU_NOCB_CPU=y, set
 			the specified list of CPUs to be no-callback CPUs.
 			Invocation of these CPUs' RCU callbacks will

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v5] lib/bitmap.c: enhance bitmap syntax
  2016-09-13 22:54         ` Andrew Morton
@ 2016-09-14  6:52           ` Noam Camus
  0 siblings, 0 replies; 15+ messages in thread
From: Noam Camus @ 2016-09-14  6:52 UTC (permalink / raw)
  To: Andrew Morton; +Cc: decot, ben, davem, linux-kernel, xinhui

> From: Andrew Morton [mailto:akpm@linux-foundation.org] 
> Sent: Wednesday, September 14, 2016 1:54 AM

>> diff --git a/Documentation/kernel-parameters.txt 
>> b/Documentation/kernel-parameters.txt
>> index 623502e..4f1e95b 100644
>> --- a/Documentation/kernel-parameters.txt
>> +++ b/Documentation/kernel-parameters.txt
>> @@ -33,6 +33,21 @@ can also be entered as  Double-quotes can be used 
>> to protect spaces in values, e.g.:
>>  	param="spaces in here"
>>  
>> +Some of the kernel parameters takes list of CPUs as value e.g.:
>> +isolcpus, task_isolation, nohz_full, irqaffinity, rcu_nocbs.

>I don't think we have a "task_isolation".  What are you trying to refer to here?
Sorry, my glitch, it is another parameter I use which is still not accepted to mainline. See this url:
https://lkml.kernel.org/g/1471382376-5443-1-git-send-email-cmetcalf@mellanox.com

>> +The format of this list is:
>> +<cpu number>,...,<cpu number>
>> +or
>> +<cpu number>-<cpu number>
>> +(must be a positive range in ascending order) or a mixture <cpu 
>> +number>,...,<cpu number>-<cpu number> Note that for special case of 
>> +range one can split range into equal size of groups and for each 
>> +group to use some amount form the begin of that group.
>> +<cpu number>-cpu number>:<used size>/<group size> For example one can 
>> +add to its command line following parameter:
>> +isolcpus=1,2,10-20,100-2000:2/25
>> +

>I think we can do better here.  Please review:
Thanks, I reviewed and it looks great.

- Noam

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2016-09-14 21:24 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-16  7:57 [PATCH] lib/bitmap.c: enhance map pattern Noam Camus
2016-07-16 12:09 ` Ben Hutchings
2016-07-17  6:33 ` [PATCH v2] lib/bitmap.c: enhance bitmap syntax Noam Camus
2016-07-17  8:10   ` [PATCH v3] " Noam Camus
2016-07-17 13:50     ` Pan Xinhui
2016-07-17 13:59       ` Pan Xinhui
2016-07-18  7:06         ` Noam Camus
2016-08-01  4:53           ` Noam Camus
2016-09-06  9:12           ` Noam Camus
2016-09-06 13:36             ` Ben Hutchings
2016-09-08 15:33     ` [PATCH v4] " Noam Camus
2016-09-08 22:19       ` Andrew Morton
2016-09-11  7:40       ` [PATCH v5] " Noam Camus
2016-09-13 22:54         ` Andrew Morton
2016-09-14  6:52           ` Noam Camus

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.