|
@@ -85,33 +85,6 @@ static void __init rcu_bootup_announce_oddness(void)
|
|
|
pr_info("\tBoot-time adjustment of leaf fanout to %d.\n", rcu_fanout_leaf);
|
|
|
if (nr_cpu_ids != NR_CPUS)
|
|
|
pr_info("\tRCU restricting CPUs from NR_CPUS=%d to nr_cpu_ids=%d.\n", NR_CPUS, nr_cpu_ids);
|
|
|
-#ifdef CONFIG_RCU_NOCB_CPU
|
|
|
-#ifndef CONFIG_RCU_NOCB_CPU_NONE
|
|
|
- if (!have_rcu_nocb_mask) {
|
|
|
- zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL);
|
|
|
- have_rcu_nocb_mask = true;
|
|
|
- }
|
|
|
-#ifdef CONFIG_RCU_NOCB_CPU_ZERO
|
|
|
- pr_info("\tOffload RCU callbacks from CPU 0\n");
|
|
|
- cpumask_set_cpu(0, rcu_nocb_mask);
|
|
|
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU_ZERO */
|
|
|
-#ifdef CONFIG_RCU_NOCB_CPU_ALL
|
|
|
- pr_info("\tOffload RCU callbacks from all CPUs\n");
|
|
|
- cpumask_copy(rcu_nocb_mask, cpu_possible_mask);
|
|
|
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU_ALL */
|
|
|
-#endif /* #ifndef CONFIG_RCU_NOCB_CPU_NONE */
|
|
|
- if (have_rcu_nocb_mask) {
|
|
|
- if (!cpumask_subset(rcu_nocb_mask, cpu_possible_mask)) {
|
|
|
- pr_info("\tNote: kernel parameter 'rcu_nocbs=' contains nonexistent CPUs.\n");
|
|
|
- cpumask_and(rcu_nocb_mask, cpu_possible_mask,
|
|
|
- rcu_nocb_mask);
|
|
|
- }
|
|
|
- cpulist_scnprintf(nocb_buf, sizeof(nocb_buf), rcu_nocb_mask);
|
|
|
- pr_info("\tOffload RCU callbacks from CPUs: %s.\n", nocb_buf);
|
|
|
- if (rcu_nocb_poll)
|
|
|
- pr_info("\tPoll for callbacks from no-CBs CPUs.\n");
|
|
|
- }
|
|
|
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_TREE_PREEMPT_RCU
|
|
@@ -2451,6 +2424,67 @@ static void do_nocb_deferred_wakeup(struct rcu_data *rdp)
|
|
|
trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("DeferredWakeEmpty"));
|
|
|
}
|
|
|
|
|
|
+void __init rcu_init_nohz(void)
|
|
|
+{
|
|
|
+ int cpu;
|
|
|
+ bool need_rcu_nocb_mask = true;
|
|
|
+ struct rcu_state *rsp;
|
|
|
+
|
|
|
+#ifdef CONFIG_RCU_NOCB_CPU_NONE
|
|
|
+ need_rcu_nocb_mask = false;
|
|
|
+#endif /* #ifndef CONFIG_RCU_NOCB_CPU_NONE */
|
|
|
+
|
|
|
+#if defined(CONFIG_NO_HZ_FULL)
|
|
|
+ if (tick_nohz_full_running && cpumask_weight(tick_nohz_full_mask))
|
|
|
+ need_rcu_nocb_mask = true;
|
|
|
+#endif /* #if defined(CONFIG_NO_HZ_FULL) */
|
|
|
+
|
|
|
+ if (!have_rcu_nocb_mask && need_rcu_nocb_mask) {
|
|
|
+ zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL);
|
|
|
+ have_rcu_nocb_mask = true;
|
|
|
+ }
|
|
|
+ if (!have_rcu_nocb_mask)
|
|
|
+ return;
|
|
|
+
|
|
|
+#ifdef CONFIG_RCU_NOCB_CPU_ZERO
|
|
|
+ pr_info("\tOffload RCU callbacks from CPU 0\n");
|
|
|
+ cpumask_set_cpu(0, rcu_nocb_mask);
|
|
|
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU_ZERO */
|
|
|
+#ifdef CONFIG_RCU_NOCB_CPU_ALL
|
|
|
+ pr_info("\tOffload RCU callbacks from all CPUs\n");
|
|
|
+ cpumask_copy(rcu_nocb_mask, cpu_possible_mask);
|
|
|
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU_ALL */
|
|
|
+#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 (!cpumask_subset(rcu_nocb_mask, cpu_possible_mask)) {
|
|
|
+ pr_info("\tNote: kernel parameter 'rcu_nocbs=' contains nonexistent CPUs.\n");
|
|
|
+ cpumask_and(rcu_nocb_mask, cpu_possible_mask,
|
|
|
+ rcu_nocb_mask);
|
|
|
+ }
|
|
|
+ cpulist_scnprintf(nocb_buf, sizeof(nocb_buf), rcu_nocb_mask);
|
|
|
+ pr_info("\tOffload RCU callbacks from CPUs: %s.\n", nocb_buf);
|
|
|
+ if (rcu_nocb_poll)
|
|
|
+ pr_info("\tPoll for callbacks from no-CBs CPUs.\n");
|
|
|
+
|
|
|
+ for_each_rcu_flavor(rsp) {
|
|
|
+ for_each_cpu(cpu, rcu_nocb_mask) {
|
|
|
+ struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If there are early callbacks, they will need
|
|
|
+ * to be moved to the nocb lists.
|
|
|
+ */
|
|
|
+ WARN_ON_ONCE(rdp->nxttail[RCU_NEXT_TAIL] !=
|
|
|
+ &rdp->nxtlist &&
|
|
|
+ rdp->nxttail[RCU_NEXT_TAIL] != NULL);
|
|
|
+ init_nocb_callback_list(rdp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/* Initialize per-rcu_data variables for no-CBs CPUs. */
|
|
|
static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp)
|
|
|
{
|
|
@@ -2479,10 +2513,6 @@ static void __init rcu_spawn_nocb_kthreads(struct rcu_state *rsp)
|
|
|
|
|
|
if (rcu_nocb_mask == NULL)
|
|
|
return;
|
|
|
-#if defined(CONFIG_NO_HZ_FULL) && !defined(CONFIG_NO_HZ_FULL_ALL)
|
|
|
- if (tick_nohz_full_running)
|
|
|
- cpumask_or(rcu_nocb_mask, rcu_nocb_mask, tick_nohz_full_mask);
|
|
|
-#endif /* #if defined(CONFIG_NO_HZ_FULL) && !defined(CONFIG_NO_HZ_FULL_ALL) */
|
|
|
if (ls == -1) {
|
|
|
ls = int_sqrt(nr_cpu_ids);
|
|
|
rcu_nocb_leader_stride = ls;
|