mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v4 0/2] rcu/nocb: Delete local variable 'need_rcu_nocb_mask' in rcu_init_nohz()
@ 2022-08-17  1:42 Zhen Lei
  2022-08-17  1:42 ` [PATCH v4 1/2] rcu: Eliminate rcu_state.nocb_is_setup Zhen Lei
  2022-08-17  1:42 ` [PATCH v4 2/2] rcu: Simplify the code logic of rcu_init_nohz() Zhen Lei
  0 siblings, 2 replies; 8+ messages in thread
From: Zhen Lei @ 2022-08-17  1:42 UTC (permalink / raw)
  To: Paul E . McKenney, Frederic Weisbecker, Neeraj Upadhyay,
	Josh Triplett, Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan,
	Joel Fernandes, rcu, linux-kernel
  Cc: Zhen Lei

v3 --> v4:
Fix a build warning.
-       struct cpumask *cpumask = NULL;
+       const struct cpumask *cpumask = NULL;

v2 --> v3:
1. Eliminate rcu_state.nocb_is_setup
2. Update the code based on the above patch and commit b37a667c6242
   ("rcu/nocb: Add an option to offload all CPUs on boot").

Test cases and test results as below:

 ----------------------------------------------------------------------
| CONFIG_NO_HZ_FULL  | CONFIG_RCU_NOCB_CPU_DEFAULT_ALL |    cmdline    |
 ----------------------------------------------------------------------
1)         N         |                 N               |     none      |
2)         N         |                 N               | rcu_nocbs=1-2 |
3)         Y         |                 N               | nohz_full=1-2 |
4)         Y         |                 Y               |     none      |
 ----------------------------------------------------------------------

1)
[ 1085.691770] rcu-torture:--- End of test: SUCCESS: (default)
root@genericarmv8:~# dmesg | grep "Offload RCU callbacks"
[    0.000000] rcu:     Offload RCU callbacks from CPUs: (none).
root@genericarmv8:~# zcat /proc/config.gz | grep NOCB
CONFIG_RCU_NOCB_CPU=y
# CONFIG_RCU_NOCB_CPU_DEFAULT_ALL is not set
root@genericarmv8:~# zcat /proc/config.gz | grep NO_HZ_FULL
# CONFIG_NO_HZ_FULL is not set
root@genericarmv8:~# cat /proc/cmdline
console=ttyAMA0 root=/dev/vda2 crashkernel=256M@ee000000

2)
[ 1022.532198] rcu-torture:--- End of test: SUCCESS: (default)
root@genericarmv8:~# dmesg | grep "Offload RCU callbacks"
[    0.000000] rcu:     Offload RCU callbacks from CPUs: 1-2.
root@genericarmv8:~# zcat /proc/config.gz | grep NOCB
CONFIG_RCU_NOCB_CPU=y
# CONFIG_RCU_NOCB_CPU_DEFAULT_ALL is not set
root@genericarmv8:~# zcat /proc/config.gz | grep NO_HZ_FULL
# CONFIG_NO_HZ_FULL is not set
root@genericarmv8:~# cat /proc/cmdline
console=ttyAMA0 root=/dev/vda2 crashkernel=256M@ee000000 rcu_nocbs=1-2

3)
[ 1011.714712] rcu-torture:--- End of test: SUCCESS: (default)
root@genericarmv8:~# dmesg | grep "Offload RCU callbacks"
[    0.000000] rcu:     Offload RCU callbacks from CPUs: 1-2.
root@genericarmv8:~# zcat /proc/config.gz | grep NOCB
CONFIG_RCU_NOCB_CPU=y
# CONFIG_RCU_NOCB_CPU_DEFAULT_ALL is not set
root@genericarmv8:~# zcat /proc/config.gz | grep NO_HZ_FULL
CONFIG_NO_HZ_FULL=y
root@genericarmv8:~# cat /proc/cmdline
console=ttyAMA0 root=/dev/vda2 crashkernel=256M@ee000000 nohz_full=1-2

4)
[ 1031.047094] rcu-torture:--- End of test: SUCCESS: (default)
root@genericarmv8:~# dmesg | grep "Offload RCU callbacks"
[    0.000000] rcu:     Offload RCU callbacks from CPUs: 0-3.
root@genericarmv8:~# zcat /proc/config.gz | grep NOCB
CONFIG_RCU_NOCB_CPU=y
CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y
root@genericarmv8:~# zcat /proc/config.gz | grep NO_HZ_FULL
CONFIG_NO_HZ_FULL=y
root@genericarmv8:~# cat /proc/cmdline
console=ttyAMA0 root=/dev/vda2 crashkernel=256M@ee000000


v1 --> v2:
Update commit message.

Zhen Lei (2):
  rcu: Eliminate rcu_state.nocb_is_setup
  rcu: Simplify the code logic of rcu_init_nohz()

 kernel/rcu/tree.h      |  1 -
 kernel/rcu/tree_nocb.h | 38 +++++++++++---------------------------
 2 files changed, 11 insertions(+), 28 deletions(-)

-- 
2.25.1


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

* [PATCH v4 1/2] rcu: Eliminate rcu_state.nocb_is_setup
  2022-08-17  1:42 [PATCH v4 0/2] rcu/nocb: Delete local variable 'need_rcu_nocb_mask' in rcu_init_nohz() Zhen Lei
@ 2022-08-17  1:42 ` Zhen Lei
  2022-08-22 16:34   ` Paul E. McKenney
  2022-08-17  1:42 ` [PATCH v4 2/2] rcu: Simplify the code logic of rcu_init_nohz() Zhen Lei
  1 sibling, 1 reply; 8+ messages in thread
From: Zhen Lei @ 2022-08-17  1:42 UTC (permalink / raw)
  To: Paul E . McKenney, Frederic Weisbecker, Neeraj Upadhyay,
	Josh Triplett, Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan,
	Joel Fernandes, rcu, linux-kernel
  Cc: Zhen Lei

'rcu_state.nocb_is_setup' is initialized to true only if 'rcu_nocb_mask'
successfully allocates memory. So it can be replaced by
'cpumask_available(rcu_nocb_mask)'. More importantly, the latter is more
intuitive, and it has been used in several places.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
 kernel/rcu/tree.h      | 1 -
 kernel/rcu/tree_nocb.h | 8 +++-----
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index d4a97e40ea9c3e2..06f659c63d2d192 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -375,7 +375,6 @@ struct rcu_state {
 	arch_spinlock_t ofl_lock ____cacheline_internodealigned_in_smp;
 						/* Synchronize offline with */
 						/*  GP pre-initialization. */
-	int nocb_is_setup;			/* nocb is setup from boot */
 };
 
 /* Values for rcu_state structure's gp_flags field. */
diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
index 0a5f0ef41484518..ff763e7dc53551f 100644
--- a/kernel/rcu/tree_nocb.h
+++ b/kernel/rcu/tree_nocb.h
@@ -69,7 +69,6 @@ static int __init rcu_nocb_setup(char *str)
 			cpumask_setall(rcu_nocb_mask);
 		}
 	}
-	rcu_state.nocb_is_setup = true;
 	return 1;
 }
 __setup("rcu_nocbs", rcu_nocb_setup);
@@ -1215,7 +1214,7 @@ void __init rcu_init_nohz(void)
 	struct rcu_data *rdp;
 
 #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL)
-	if (!rcu_state.nocb_is_setup) {
+	if (!cpumask_available(rcu_nocb_mask)) {
 		need_rcu_nocb_mask = true;
 		offload_all = true;
 	}
@@ -1235,10 +1234,9 @@ void __init rcu_init_nohz(void)
 				return;
 			}
 		}
-		rcu_state.nocb_is_setup = true;
 	}
 
-	if (!rcu_state.nocb_is_setup)
+	if (!cpumask_available(rcu_nocb_mask))
 		return;
 
 #if defined(CONFIG_NO_HZ_FULL)
@@ -1299,7 +1297,7 @@ static void rcu_spawn_cpu_nocb_kthread(int cpu)
 	struct task_struct *t;
 	struct sched_param sp;
 
-	if (!rcu_scheduler_fully_active || !rcu_state.nocb_is_setup)
+	if (!rcu_scheduler_fully_active || !cpumask_available(rcu_nocb_mask))
 		return;
 
 	/* If there already is an rcuo kthread, then nothing to do. */
-- 
2.25.1


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

* [PATCH v4 2/2] rcu: Simplify the code logic of rcu_init_nohz()
  2022-08-17  1:42 [PATCH v4 0/2] rcu/nocb: Delete local variable 'need_rcu_nocb_mask' in rcu_init_nohz() Zhen Lei
  2022-08-17  1:42 ` [PATCH v4 1/2] rcu: Eliminate rcu_state.nocb_is_setup Zhen Lei
@ 2022-08-17  1:42 ` Zhen Lei
  2022-08-22 16:35   ` Paul E. McKenney
  1 sibling, 1 reply; 8+ messages in thread
From: Zhen Lei @ 2022-08-17  1:42 UTC (permalink / raw)
  To: Paul E . McKenney, Frederic Weisbecker, Neeraj Upadhyay,
	Josh Triplett, Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan,
	Joel Fernandes, rcu, linux-kernel
  Cc: Zhen Lei

When CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y or CONFIG_NO_HZ_FULL=y, additional
CPUs need to be added to 'rcu_nocb_mask'. But 'rcu_nocb_mask' may be not
available now, due to 'rcu_nocbs' is not specified. Check and initialize
'rcu_nocb_mask' before using it. This code simplification strictly follows
this logic, compared with old implementations, unnecessary crossovers are
avoided and easy to understand.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
 kernel/rcu/tree_nocb.h | 32 +++++++++-----------------------
 1 file changed, 9 insertions(+), 23 deletions(-)

diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
index ff763e7dc53551f..3c59b12f4465af1 100644
--- a/kernel/rcu/tree_nocb.h
+++ b/kernel/rcu/tree_nocb.h
@@ -1209,44 +1209,30 @@ EXPORT_SYMBOL_GPL(rcu_nocb_cpu_offload);
 void __init rcu_init_nohz(void)
 {
 	int cpu;
-	bool need_rcu_nocb_mask = false;
-	bool offload_all = false;
 	struct rcu_data *rdp;
+	const struct cpumask *cpumask = NULL;
 
 #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL)
-	if (!cpumask_available(rcu_nocb_mask)) {
-		need_rcu_nocb_mask = true;
-		offload_all = true;
-	}
-#endif /* #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL) */
-
-#if defined(CONFIG_NO_HZ_FULL)
-	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask)) {
-		need_rcu_nocb_mask = true;
-		offload_all = false; /* NO_HZ_FULL has its own mask. */
-	}
-#endif /* #if defined(CONFIG_NO_HZ_FULL) */
+	cpumask = cpu_possible_mask;
+#elif defined(CONFIG_NO_HZ_FULL)
+	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask))
+		cpumask = tick_nohz_full_mask;
+#endif
 
-	if (need_rcu_nocb_mask) {
+	if (cpumask) {
 		if (!cpumask_available(rcu_nocb_mask)) {
 			if (!zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL)) {
 				pr_info("rcu_nocb_mask allocation failed, callback offloading disabled.\n");
 				return;
 			}
 		}
+
+		cpumask_or(rcu_nocb_mask, rcu_nocb_mask, cpumask);
 	}
 
 	if (!cpumask_available(rcu_nocb_mask))
 		return;
 
-#if defined(CONFIG_NO_HZ_FULL)
-	if (tick_nohz_full_running)
-		cpumask_or(rcu_nocb_mask, rcu_nocb_mask, tick_nohz_full_mask);
-#endif /* #if defined(CONFIG_NO_HZ_FULL) */
-
-	if (offload_all)
-		cpumask_setall(rcu_nocb_mask);
-
 	if (!cpumask_subset(rcu_nocb_mask, cpu_possible_mask)) {
 		pr_info("\tNote: kernel parameter 'rcu_nocbs=', 'nohz_full', or 'isolcpus=' contains nonexistent CPUs.\n");
 		cpumask_and(rcu_nocb_mask, cpu_possible_mask,
-- 
2.25.1


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

* Re: [PATCH v4 1/2] rcu: Eliminate rcu_state.nocb_is_setup
  2022-08-17  1:42 ` [PATCH v4 1/2] rcu: Eliminate rcu_state.nocb_is_setup Zhen Lei
@ 2022-08-22 16:34   ` Paul E. McKenney
  2022-08-23 12:00     ` Leizhen (ThunderTown)
  0 siblings, 1 reply; 8+ messages in thread
From: Paul E. McKenney @ 2022-08-22 16:34 UTC (permalink / raw)
  To: Zhen Lei
  Cc: Frederic Weisbecker, Neeraj Upadhyay, Josh Triplett,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes,
	rcu, linux-kernel

On Wed, Aug 17, 2022 at 09:42:52AM +0800, Zhen Lei wrote:
> 'rcu_state.nocb_is_setup' is initialized to true only if 'rcu_nocb_mask'
> successfully allocates memory. So it can be replaced by
> 'cpumask_available(rcu_nocb_mask)'. More importantly, the latter is more
> intuitive, and it has been used in several places.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>

One of the implementations of cpumask_available() does indeed check
for NULL.  But here is the other one:

static inline bool cpumask_available(cpumask_var_t mask)
{
	return true;
}

So I have to ask...  In a kernel built with CONFIG_CPUMASK_OFFSTACK=n,
will this change really work?

Another important question is "Do all of the existing uses of
cpumask_available() really work?"  Yes, I do believe that they do
work, but it would be good to get another set of eyes on that code.
"All software developers are blind!"  ;-)

							Thanx, Paul

> ---
>  kernel/rcu/tree.h      | 1 -
>  kernel/rcu/tree_nocb.h | 8 +++-----
>  2 files changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
> index d4a97e40ea9c3e2..06f659c63d2d192 100644
> --- a/kernel/rcu/tree.h
> +++ b/kernel/rcu/tree.h
> @@ -375,7 +375,6 @@ struct rcu_state {
>  	arch_spinlock_t ofl_lock ____cacheline_internodealigned_in_smp;
>  						/* Synchronize offline with */
>  						/*  GP pre-initialization. */
> -	int nocb_is_setup;			/* nocb is setup from boot */
>  };
>  
>  /* Values for rcu_state structure's gp_flags field. */
> diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
> index 0a5f0ef41484518..ff763e7dc53551f 100644
> --- a/kernel/rcu/tree_nocb.h
> +++ b/kernel/rcu/tree_nocb.h
> @@ -69,7 +69,6 @@ static int __init rcu_nocb_setup(char *str)
>  			cpumask_setall(rcu_nocb_mask);
>  		}
>  	}
> -	rcu_state.nocb_is_setup = true;
>  	return 1;
>  }
>  __setup("rcu_nocbs", rcu_nocb_setup);
> @@ -1215,7 +1214,7 @@ void __init rcu_init_nohz(void)
>  	struct rcu_data *rdp;
>  
>  #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL)
> -	if (!rcu_state.nocb_is_setup) {
> +	if (!cpumask_available(rcu_nocb_mask)) {
>  		need_rcu_nocb_mask = true;
>  		offload_all = true;
>  	}
> @@ -1235,10 +1234,9 @@ void __init rcu_init_nohz(void)
>  				return;
>  			}
>  		}
> -		rcu_state.nocb_is_setup = true;
>  	}
>  
> -	if (!rcu_state.nocb_is_setup)
> +	if (!cpumask_available(rcu_nocb_mask))
>  		return;
>  
>  #if defined(CONFIG_NO_HZ_FULL)
> @@ -1299,7 +1297,7 @@ static void rcu_spawn_cpu_nocb_kthread(int cpu)
>  	struct task_struct *t;
>  	struct sched_param sp;
>  
> -	if (!rcu_scheduler_fully_active || !rcu_state.nocb_is_setup)
> +	if (!rcu_scheduler_fully_active || !cpumask_available(rcu_nocb_mask))
>  		return;
>  
>  	/* If there already is an rcuo kthread, then nothing to do. */
> -- 
> 2.25.1
> 

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

* Re: [PATCH v4 2/2] rcu: Simplify the code logic of rcu_init_nohz()
  2022-08-17  1:42 ` [PATCH v4 2/2] rcu: Simplify the code logic of rcu_init_nohz() Zhen Lei
@ 2022-08-22 16:35   ` Paul E. McKenney
  2022-08-23 12:13     ` Leizhen (ThunderTown)
  0 siblings, 1 reply; 8+ messages in thread
From: Paul E. McKenney @ 2022-08-22 16:35 UTC (permalink / raw)
  To: Zhen Lei
  Cc: Frederic Weisbecker, Neeraj Upadhyay, Josh Triplett,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes,
	rcu, linux-kernel

On Wed, Aug 17, 2022 at 09:42:53AM +0800, Zhen Lei wrote:
> When CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y or CONFIG_NO_HZ_FULL=y, additional
> CPUs need to be added to 'rcu_nocb_mask'. But 'rcu_nocb_mask' may be not
> available now, due to 'rcu_nocbs' is not specified. Check and initialize
> 'rcu_nocb_mask' before using it. This code simplification strictly follows
> this logic, compared with old implementations, unnecessary crossovers are
> avoided and easy to understand.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>

This looks like a nice simplification, but I will wait for your response
on Patch 1/1 before trying it out.

							Thanx, Paul

> ---
>  kernel/rcu/tree_nocb.h | 32 +++++++++-----------------------
>  1 file changed, 9 insertions(+), 23 deletions(-)
> 
> diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
> index ff763e7dc53551f..3c59b12f4465af1 100644
> --- a/kernel/rcu/tree_nocb.h
> +++ b/kernel/rcu/tree_nocb.h
> @@ -1209,44 +1209,30 @@ EXPORT_SYMBOL_GPL(rcu_nocb_cpu_offload);
>  void __init rcu_init_nohz(void)
>  {
>  	int cpu;
> -	bool need_rcu_nocb_mask = false;
> -	bool offload_all = false;
>  	struct rcu_data *rdp;
> +	const struct cpumask *cpumask = NULL;
>  
>  #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL)
> -	if (!cpumask_available(rcu_nocb_mask)) {
> -		need_rcu_nocb_mask = true;
> -		offload_all = true;
> -	}
> -#endif /* #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL) */
> -
> -#if defined(CONFIG_NO_HZ_FULL)
> -	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask)) {
> -		need_rcu_nocb_mask = true;
> -		offload_all = false; /* NO_HZ_FULL has its own mask. */
> -	}
> -#endif /* #if defined(CONFIG_NO_HZ_FULL) */
> +	cpumask = cpu_possible_mask;
> +#elif defined(CONFIG_NO_HZ_FULL)
> +	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask))
> +		cpumask = tick_nohz_full_mask;
> +#endif
>  
> -	if (need_rcu_nocb_mask) {
> +	if (cpumask) {
>  		if (!cpumask_available(rcu_nocb_mask)) {
>  			if (!zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL)) {
>  				pr_info("rcu_nocb_mask allocation failed, callback offloading disabled.\n");
>  				return;
>  			}
>  		}
> +
> +		cpumask_or(rcu_nocb_mask, rcu_nocb_mask, cpumask);
>  	}
>  
>  	if (!cpumask_available(rcu_nocb_mask))
>  		return;
>  
> -#if defined(CONFIG_NO_HZ_FULL)
> -	if (tick_nohz_full_running)
> -		cpumask_or(rcu_nocb_mask, rcu_nocb_mask, tick_nohz_full_mask);
> -#endif /* #if defined(CONFIG_NO_HZ_FULL) */
> -
> -	if (offload_all)
> -		cpumask_setall(rcu_nocb_mask);
> -
>  	if (!cpumask_subset(rcu_nocb_mask, cpu_possible_mask)) {
>  		pr_info("\tNote: kernel parameter 'rcu_nocbs=', 'nohz_full', or 'isolcpus=' contains nonexistent CPUs.\n");
>  		cpumask_and(rcu_nocb_mask, cpu_possible_mask,
> -- 
> 2.25.1
> 

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

* Re: [PATCH v4 1/2] rcu: Eliminate rcu_state.nocb_is_setup
  2022-08-22 16:34   ` Paul E. McKenney
@ 2022-08-23 12:00     ` Leizhen (ThunderTown)
  0 siblings, 0 replies; 8+ messages in thread
From: Leizhen (ThunderTown) @ 2022-08-23 12:00 UTC (permalink / raw)
  To: paulmck
  Cc: Frederic Weisbecker, Neeraj Upadhyay, Josh Triplett,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes,
	rcu, linux-kernel



On 2022/8/23 0:34, Paul E. McKenney wrote:
> On Wed, Aug 17, 2022 at 09:42:52AM +0800, Zhen Lei wrote:
>> 'rcu_state.nocb_is_setup' is initialized to true only if 'rcu_nocb_mask'
>> successfully allocates memory. So it can be replaced by
>> 'cpumask_available(rcu_nocb_mask)'. More importantly, the latter is more
>> intuitive, and it has been used in several places.
>>
>> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
> 
> One of the implementations of cpumask_available() does indeed check
> for NULL.  But here is the other one:
> 
> static inline bool cpumask_available(cpumask_var_t mask)
> {
> 	return true;
> }

Thanks for the heads-up.

> 
> So I have to ask...  In a kernel built with CONFIG_CPUMASK_OFFSTACK=n,
> will this change really work?

Yes, I run the test cases on arm64, which does not turn on option
CONFIG_CPUMASK_OFFSTACK by default.

I've listed a combination of build options in the cover-letter. In
this case, cpumask_empty(rcu_nocb_mask) is true.
----
CONFIG_NO_HZ_FULL=n, CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=n, cmdline without rcu_nocbs
[    0.000000] rcu:     Offload RCU callbacks from CPUs: (none).
----

> 
> Another important question is "Do all of the existing uses of
> cpumask_available() really work?"  Yes, I do believe that they do

The only functional change caused by this patch is:
For clarity, CONFIG_RCU_NOCB_CPU=y and CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=n are
omitted from the following conditions.

When
  CONFIG_NO_HZ_FULL=n and boot cmdline without 'rcu_nocbs='.
or
  CONFIG_NO_HZ_FULL=y and boot cmdline without 'nohz_full='.

The rdp->nocb_gp_kthread and rdp->nocb_cb_kthread threads are still created.

But we have provided EXPORT_SYMBOL_GPL functions rcu_nocb_cpu_deoffload() and
rcu_nocb_cpu_offload(), which can dynamically modify 'rcu_nocb_mask'. So it
seems appropriate to prepare these threads in advance. Of course, it looks like
only 'rcutorture' currently uses these two functions now.

Otherwise, we can do some optimization:
If none of the CPUs in a 'nocb_gp' group is marked in rcu_nocb_mask, this
grouping does not need to create corresponding threads "rcuog/%d" and "rcuo%c/%d".

And in rcu_init_nohz():
-       if (!rcu_state.nocb_is_setup)
+       if (!cpumask_available(rcu_nocb_mask) || cpumask_empty(rcu_nocb_mask))
                return;



> work, but it would be good to get another set of eyes on that code.
> "All software developers are blind!"  ;-)
> 
> 							Thanx, Paul
> 
>> ---
>>  kernel/rcu/tree.h      | 1 -
>>  kernel/rcu/tree_nocb.h | 8 +++-----
>>  2 files changed, 3 insertions(+), 6 deletions(-)
>>
>> diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
>> index d4a97e40ea9c3e2..06f659c63d2d192 100644
>> --- a/kernel/rcu/tree.h
>> +++ b/kernel/rcu/tree.h
>> @@ -375,7 +375,6 @@ struct rcu_state {
>>  	arch_spinlock_t ofl_lock ____cacheline_internodealigned_in_smp;
>>  						/* Synchronize offline with */
>>  						/*  GP pre-initialization. */
>> -	int nocb_is_setup;			/* nocb is setup from boot */
>>  };
>>  
>>  /* Values for rcu_state structure's gp_flags field. */
>> diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
>> index 0a5f0ef41484518..ff763e7dc53551f 100644
>> --- a/kernel/rcu/tree_nocb.h
>> +++ b/kernel/rcu/tree_nocb.h
>> @@ -69,7 +69,6 @@ static int __init rcu_nocb_setup(char *str)
>>  			cpumask_setall(rcu_nocb_mask);
>>  		}
>>  	}
>> -	rcu_state.nocb_is_setup = true;
>>  	return 1;
>>  }
>>  __setup("rcu_nocbs", rcu_nocb_setup);
>> @@ -1215,7 +1214,7 @@ void __init rcu_init_nohz(void)
>>  	struct rcu_data *rdp;
>>  
>>  #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL)
>> -	if (!rcu_state.nocb_is_setup) {
>> +	if (!cpumask_available(rcu_nocb_mask)) {
>>  		need_rcu_nocb_mask = true;
>>  		offload_all = true;
>>  	}
>> @@ -1235,10 +1234,9 @@ void __init rcu_init_nohz(void)
>>  				return;
>>  			}
>>  		}
>> -		rcu_state.nocb_is_setup = true;
>>  	}
>>  
>> -	if (!rcu_state.nocb_is_setup)
>> +	if (!cpumask_available(rcu_nocb_mask))
>>  		return;
>>  
>>  #if defined(CONFIG_NO_HZ_FULL)
>> @@ -1299,7 +1297,7 @@ static void rcu_spawn_cpu_nocb_kthread(int cpu)
>>  	struct task_struct *t;
>>  	struct sched_param sp;
>>  
>> -	if (!rcu_scheduler_fully_active || !rcu_state.nocb_is_setup)
>> +	if (!rcu_scheduler_fully_active || !cpumask_available(rcu_nocb_mask))
>>  		return;
>>  
>>  	/* If there already is an rcuo kthread, then nothing to do. */
>> -- 
>> 2.25.1
>>
> .
> 

-- 
Regards,
  Zhen Lei

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

* Re: [PATCH v4 2/2] rcu: Simplify the code logic of rcu_init_nohz()
  2022-08-22 16:35   ` Paul E. McKenney
@ 2022-08-23 12:13     ` Leizhen (ThunderTown)
  2022-08-25 16:19       ` Paul E. McKenney
  0 siblings, 1 reply; 8+ messages in thread
From: Leizhen (ThunderTown) @ 2022-08-23 12:13 UTC (permalink / raw)
  To: paulmck
  Cc: Frederic Weisbecker, Neeraj Upadhyay, Josh Triplett,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes,
	rcu, linux-kernel



On 2022/8/23 0:35, Paul E. McKenney wrote:
> On Wed, Aug 17, 2022 at 09:42:53AM +0800, Zhen Lei wrote:
>> When CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y or CONFIG_NO_HZ_FULL=y, additional
>> CPUs need to be added to 'rcu_nocb_mask'. But 'rcu_nocb_mask' may be not
>> available now, due to 'rcu_nocbs' is not specified. Check and initialize
>> 'rcu_nocb_mask' before using it. This code simplification strictly follows
>> this logic, compared with old implementations, unnecessary crossovers are
>> avoided and easy to understand.
>>
>> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
> 
> This looks like a nice simplification, but I will wait for your response
> on Patch 1/1 before trying it out.

How about I post v5 and just do this simplification? Patch 1/2 seems to require
further discussion and in-depth analysis, which may take a long time.

> 
> 							Thanx, Paul
> 
>> ---
>>  kernel/rcu/tree_nocb.h | 32 +++++++++-----------------------
>>  1 file changed, 9 insertions(+), 23 deletions(-)
>>
>> diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
>> index ff763e7dc53551f..3c59b12f4465af1 100644
>> --- a/kernel/rcu/tree_nocb.h
>> +++ b/kernel/rcu/tree_nocb.h
>> @@ -1209,44 +1209,30 @@ EXPORT_SYMBOL_GPL(rcu_nocb_cpu_offload);
>>  void __init rcu_init_nohz(void)
>>  {
>>  	int cpu;
>> -	bool need_rcu_nocb_mask = false;
>> -	bool offload_all = false;
>>  	struct rcu_data *rdp;
>> +	const struct cpumask *cpumask = NULL;
>>  
>>  #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL)
>> -	if (!cpumask_available(rcu_nocb_mask)) {
>> -		need_rcu_nocb_mask = true;
>> -		offload_all = true;
>> -	}
>> -#endif /* #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL) */
>> -
>> -#if defined(CONFIG_NO_HZ_FULL)
>> -	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask)) {
>> -		need_rcu_nocb_mask = true;
>> -		offload_all = false; /* NO_HZ_FULL has its own mask. */
>> -	}
>> -#endif /* #if defined(CONFIG_NO_HZ_FULL) */
>> +	cpumask = cpu_possible_mask;
>> +#elif defined(CONFIG_NO_HZ_FULL)
>> +	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask))
>> +		cpumask = tick_nohz_full_mask;
>> +#endif
>>  
>> -	if (need_rcu_nocb_mask) {
>> +	if (cpumask) {
>>  		if (!cpumask_available(rcu_nocb_mask)) {
>>  			if (!zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL)) {
>>  				pr_info("rcu_nocb_mask allocation failed, callback offloading disabled.\n");
>>  				return;
>>  			}
>>  		}
>> +
>> +		cpumask_or(rcu_nocb_mask, rcu_nocb_mask, cpumask);
>>  	}
>>  
>>  	if (!cpumask_available(rcu_nocb_mask))
>>  		return;
>>  
>> -#if defined(CONFIG_NO_HZ_FULL)
>> -	if (tick_nohz_full_running)
>> -		cpumask_or(rcu_nocb_mask, rcu_nocb_mask, tick_nohz_full_mask);
>> -#endif /* #if defined(CONFIG_NO_HZ_FULL) */
>> -
>> -	if (offload_all)
>> -		cpumask_setall(rcu_nocb_mask);
>> -
>>  	if (!cpumask_subset(rcu_nocb_mask, cpu_possible_mask)) {
>>  		pr_info("\tNote: kernel parameter 'rcu_nocbs=', 'nohz_full', or 'isolcpus=' contains nonexistent CPUs.\n");
>>  		cpumask_and(rcu_nocb_mask, cpu_possible_mask,
>> -- 
>> 2.25.1
>>
> .
> 

-- 
Regards,
  Zhen Lei

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

* Re: [PATCH v4 2/2] rcu: Simplify the code logic of rcu_init_nohz()
  2022-08-23 12:13     ` Leizhen (ThunderTown)
@ 2022-08-25 16:19       ` Paul E. McKenney
  0 siblings, 0 replies; 8+ messages in thread
From: Paul E. McKenney @ 2022-08-25 16:19 UTC (permalink / raw)
  To: Leizhen (ThunderTown)
  Cc: Frederic Weisbecker, Neeraj Upadhyay, Josh Triplett,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes,
	rcu, linux-kernel

On Tue, Aug 23, 2022 at 08:13:00PM +0800, Leizhen (ThunderTown) wrote:
> 
> 
> On 2022/8/23 0:35, Paul E. McKenney wrote:
> > On Wed, Aug 17, 2022 at 09:42:53AM +0800, Zhen Lei wrote:
> >> When CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y or CONFIG_NO_HZ_FULL=y, additional
> >> CPUs need to be added to 'rcu_nocb_mask'. But 'rcu_nocb_mask' may be not
> >> available now, due to 'rcu_nocbs' is not specified. Check and initialize
> >> 'rcu_nocb_mask' before using it. This code simplification strictly follows
> >> this logic, compared with old implementations, unnecessary crossovers are
> >> avoided and easy to understand.
> >>
> >> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
> > 
> > This looks like a nice simplification, but I will wait for your response
> > on Patch 1/1 before trying it out.
> 
> How about I post v5 and just do this simplification? Patch 1/2 seems to require
> further discussion and in-depth analysis, which may take a long time.

Excellent choice, thank you!


							Thanx, Paul

> >> ---
> >>  kernel/rcu/tree_nocb.h | 32 +++++++++-----------------------
> >>  1 file changed, 9 insertions(+), 23 deletions(-)
> >>
> >> diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
> >> index ff763e7dc53551f..3c59b12f4465af1 100644
> >> --- a/kernel/rcu/tree_nocb.h
> >> +++ b/kernel/rcu/tree_nocb.h
> >> @@ -1209,44 +1209,30 @@ EXPORT_SYMBOL_GPL(rcu_nocb_cpu_offload);
> >>  void __init rcu_init_nohz(void)
> >>  {
> >>  	int cpu;
> >> -	bool need_rcu_nocb_mask = false;
> >> -	bool offload_all = false;
> >>  	struct rcu_data *rdp;
> >> +	const struct cpumask *cpumask = NULL;
> >>  
> >>  #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL)
> >> -	if (!cpumask_available(rcu_nocb_mask)) {
> >> -		need_rcu_nocb_mask = true;
> >> -		offload_all = true;
> >> -	}
> >> -#endif /* #if defined(CONFIG_RCU_NOCB_CPU_DEFAULT_ALL) */
> >> -
> >> -#if defined(CONFIG_NO_HZ_FULL)
> >> -	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask)) {
> >> -		need_rcu_nocb_mask = true;
> >> -		offload_all = false; /* NO_HZ_FULL has its own mask. */
> >> -	}
> >> -#endif /* #if defined(CONFIG_NO_HZ_FULL) */
> >> +	cpumask = cpu_possible_mask;
> >> +#elif defined(CONFIG_NO_HZ_FULL)
> >> +	if (tick_nohz_full_running && !cpumask_empty(tick_nohz_full_mask))
> >> +		cpumask = tick_nohz_full_mask;
> >> +#endif
> >>  
> >> -	if (need_rcu_nocb_mask) {
> >> +	if (cpumask) {
> >>  		if (!cpumask_available(rcu_nocb_mask)) {
> >>  			if (!zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL)) {
> >>  				pr_info("rcu_nocb_mask allocation failed, callback offloading disabled.\n");
> >>  				return;
> >>  			}
> >>  		}
> >> +
> >> +		cpumask_or(rcu_nocb_mask, rcu_nocb_mask, cpumask);
> >>  	}
> >>  
> >>  	if (!cpumask_available(rcu_nocb_mask))
> >>  		return;
> >>  
> >> -#if defined(CONFIG_NO_HZ_FULL)
> >> -	if (tick_nohz_full_running)
> >> -		cpumask_or(rcu_nocb_mask, rcu_nocb_mask, tick_nohz_full_mask);
> >> -#endif /* #if defined(CONFIG_NO_HZ_FULL) */
> >> -
> >> -	if (offload_all)
> >> -		cpumask_setall(rcu_nocb_mask);
> >> -
> >>  	if (!cpumask_subset(rcu_nocb_mask, cpu_possible_mask)) {
> >>  		pr_info("\tNote: kernel parameter 'rcu_nocbs=', 'nohz_full', or 'isolcpus=' contains nonexistent CPUs.\n");
> >>  		cpumask_and(rcu_nocb_mask, cpu_possible_mask,
> >> -- 
> >> 2.25.1
> >>
> > .
> > 
> 
> -- 
> Regards,
>   Zhen Lei

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

end of thread, other threads:[~2022-08-25 16:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-17  1:42 [PATCH v4 0/2] rcu/nocb: Delete local variable 'need_rcu_nocb_mask' in rcu_init_nohz() Zhen Lei
2022-08-17  1:42 ` [PATCH v4 1/2] rcu: Eliminate rcu_state.nocb_is_setup Zhen Lei
2022-08-22 16:34   ` Paul E. McKenney
2022-08-23 12:00     ` Leizhen (ThunderTown)
2022-08-17  1:42 ` [PATCH v4 2/2] rcu: Simplify the code logic of rcu_init_nohz() Zhen Lei
2022-08-22 16:35   ` Paul E. McKenney
2022-08-23 12:13     ` Leizhen (ThunderTown)
2022-08-25 16:19       ` Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®