Commit a81aeaf7 authored by Frederic Weisbecker's avatar Frederic Weisbecker Committed by Paul E. McKenney
Browse files

rcu/nocb: Optimize kthreads and rdp initialization



Currently cpumask_available() is used to prevent from unwanted NOCB
initialization.  However if neither "rcu_nocbs=" nor "nohz_full="
parameters are passed to a kernel built with CONFIG_CPUMASK_OFFSTACK=n,
the initialization path is still taken, running through all sorts of
needless operations and iterations on an empty cpumask.

Fix this by relying on a real initialization state instead.  This also
optimizes kthread creation, preventing needless iteration over all online
CPUs when the kernel is booted without any offloaded CPUs.

Reviewed-by: default avatarNeeraj Upadhyay <quic_neeraju@quicinc.com>
Signed-off-by: default avatarFrederic 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: default avatarJuri Lelli <juri.lelli@redhat.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent 8d970396
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -60,6 +60,9 @@ static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
 * Parse the boot-time rcu_nocb_mask CPU list from the kernel parameters.
 * If the list is invalid, a warning is emitted and all CPUs are offloaded.
 */

static bool rcu_nocb_is_setup;

static int __init rcu_nocb_setup(char *str)
{
	alloc_bootmem_cpumask_var(&rcu_nocb_mask);
@@ -67,6 +70,7 @@ static int __init rcu_nocb_setup(char *str)
		pr_warn("rcu_nocbs= bad CPU range, all CPUs set\n");
		cpumask_setall(rcu_nocb_mask);
	}
	rcu_nocb_is_setup = true;
	return 1;
}
__setup("rcu_nocbs=", rcu_nocb_setup);
@@ -1167,13 +1171,17 @@ void __init rcu_init_nohz(void)
		need_rcu_nocb_mask = true;
#endif /* #if defined(CONFIG_NO_HZ_FULL) */

	if (!cpumask_available(rcu_nocb_mask) && need_rcu_nocb_mask) {
	if (need_rcu_nocb_mask) {
		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;
			}
		}
	if (!cpumask_available(rcu_nocb_mask))
		rcu_nocb_is_setup = true;
	}

	if (!rcu_nocb_is_setup)
		return;

#if defined(CONFIG_NO_HZ_FULL)
@@ -1275,9 +1283,11 @@ static void __init rcu_spawn_nocb_kthreads(void)
{
	int cpu;

	if (rcu_nocb_is_setup) {
		for_each_online_cpu(cpu)
			rcu_spawn_cpu_nocb_kthread(cpu);
	}
}

/* How many CB CPU IDs per GP kthread?  Default of -1 for sqrt(nr_cpu_ids). */
static int rcu_nocb_gp_stride = -1;