summaryrefslogtreecommitdiff
path: root/kernel/rcu
diff options
context:
space:
mode:
authorFrederic Weisbecker <frederic@kernel.org>2021-11-23 03:37:06 +0300
committerPaul E. McKenney <paulmck@kernel.org>2021-12-09 22:35:06 +0300
commit2cf4528d6dd6f5a7f34ae07e26176a7932310eeb (patch)
tree0dc4af21b31e4e9505ca3e1f48c5b7fa4de2606c /kernel/rcu
parenta81aeaf7a1de51400374a8e3982a3cc3ff130dd1 (diff)
downloadlinux-2cf4528d6dd6f5a7f34ae07e26176a7932310eeb.tar.xz
rcu/nocb: Create kthreads on all CPUs if "rcu_nocbs=" or "nohz_full=" are passed
In order to be able to (de-)offload any CPU using cpusets in the future, create the NOCB data structures for all possible CPUs. For now this is done only as long as the "rcu_nocbs=" or "nohz_full=" kernel parameters are passed to avoid the unnecessary overhead for most users. Note that the rcuog and rcuoc kthreads are not created until at least one of the corresponding CPUs comes online. This approach avoids the creation of excess kthreads when firmware lies about the number of CPUs present on the system. Reviewed-by: Neeraj Upadhyay <quic_neeraju@quicinc.com> Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Uladzislau Rezki <urezki@gmail.com> Cc: Josh Triplett <josh@joshtriplett.org> Cc: Joel Fernandes <joel@joelfernandes.org> Tested-by: Juri Lelli <juri.lelli@redhat.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Diffstat (limited to 'kernel/rcu')
-rw-r--r--kernel/rcu/tree_nocb.h14
1 files changed, 6 insertions, 8 deletions
diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
index 42092de67705..f580a6b2e74e 100644
--- a/kernel/rcu/tree_nocb.h
+++ b/kernel/rcu/tree_nocb.h
@@ -1237,11 +1237,8 @@ static void rcu_spawn_one_nocb_kthread(int cpu)
struct rcu_data *rdp_gp;
struct task_struct *t;
- /*
- * If this isn't a no-CBs CPU or if it already has an rcuo kthread,
- * then nothing to do.
- */
- if (!rcu_is_nocb_cpu(cpu) || rdp->nocb_cb_kthread)
+ /* If there already is an rcuo kthread, then nothing to do. */
+ if (rdp->nocb_cb_kthread)
return;
/* If we didn't spawn the GP kthread first, reorganize! */
@@ -1269,7 +1266,7 @@ static void rcu_spawn_one_nocb_kthread(int cpu)
*/
static void rcu_spawn_cpu_nocb_kthread(int cpu)
{
- if (rcu_scheduler_fully_active)
+ if (rcu_scheduler_fully_active && rcu_nocb_is_setup)
rcu_spawn_one_nocb_kthread(cpu);
}
@@ -1319,7 +1316,7 @@ static void __init rcu_organize_nocb_kthreads(void)
* Should the corresponding CPU come online in the future, then
* we will spawn the needed set of rcu_nocb_kthread() kthreads.
*/
- for_each_cpu(cpu, rcu_nocb_mask) {
+ for_each_possible_cpu(cpu) {
rdp = per_cpu_ptr(&rcu_data, cpu);
if (rdp->cpu >= nl) {
/* New GP kthread, set up for CBs & next GP. */
@@ -1343,7 +1340,8 @@ static void __init rcu_organize_nocb_kthreads(void)
pr_cont(" %d", cpu);
}
rdp->nocb_gp_rdp = rdp_gp;
- list_add_tail(&rdp->nocb_entry_rdp, &rdp_gp->nocb_head_rdp);
+ if (cpumask_test_cpu(cpu, rcu_nocb_mask))
+ list_add_tail(&rdp->nocb_entry_rdp, &rdp_gp->nocb_head_rdp);
}
if (gotnocbs && dump_tree)
pr_cont("%s\n", gotnocbscbs ? "" : " (self only)");