Commit 1b04fa99 authored by Uladzislau Rezki (Sony)'s avatar Uladzislau Rezki (Sony) Committed by Paul E. McKenney

rcu-tasks: Move RCU-tasks initialization to before early_initcall()

PowerPC testing encountered boot failures due to RCU Tasks not being
fully initialized until core_initcall() time.  This commit therefore
initializes RCU Tasks (along with Rude RCU and RCU Tasks Trace) just
before early_initcall() time, thus allowing waiting on RCU Tasks grace
periods from early_initcall() handlers.

Link: https://lore.kernel.org/rcu/87eekfh80a.fsf@dja-thinkpad.axtens.net/
Fixes: 36dadef2 ("kprobes: Init kprobes in early_initcall")
Tested-by: default avatarDaniel Axtens <dja@axtens.net>
Signed-off-by: default avatarUladzislau Rezki (Sony) <urezki@gmail.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent 0477e928
...@@ -86,6 +86,12 @@ void rcu_sched_clock_irq(int user); ...@@ -86,6 +86,12 @@ void rcu_sched_clock_irq(int user);
void rcu_report_dead(unsigned int cpu); void rcu_report_dead(unsigned int cpu);
void rcutree_migrate_callbacks(int cpu); void rcutree_migrate_callbacks(int cpu);
#ifdef CONFIG_TASKS_RCU_GENERIC
void rcu_init_tasks_generic(void);
#else
static inline void rcu_init_tasks_generic(void) { }
#endif
#ifdef CONFIG_RCU_STALL_COMMON #ifdef CONFIG_RCU_STALL_COMMON
void rcu_sysrq_start(void); void rcu_sysrq_start(void);
void rcu_sysrq_end(void); void rcu_sysrq_end(void);
......
...@@ -1512,6 +1512,7 @@ static noinline void __init kernel_init_freeable(void) ...@@ -1512,6 +1512,7 @@ static noinline void __init kernel_init_freeable(void)
init_mm_internals(); init_mm_internals();
rcu_init_tasks_generic();
do_pre_smp_initcalls(); do_pre_smp_initcalls();
lockup_detector_init(); lockup_detector_init();
......
...@@ -241,7 +241,7 @@ static int __noreturn rcu_tasks_kthread(void *arg) ...@@ -241,7 +241,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)
} }
} }
/* Spawn RCU-tasks grace-period kthread, e.g., at core_initcall() time. */ /* Spawn RCU-tasks grace-period kthread. */
static void __init rcu_spawn_tasks_kthread_generic(struct rcu_tasks *rtp) static void __init rcu_spawn_tasks_kthread_generic(struct rcu_tasks *rtp)
{ {
struct task_struct *t; struct task_struct *t;
...@@ -569,7 +569,6 @@ static int __init rcu_spawn_tasks_kthread(void) ...@@ -569,7 +569,6 @@ static int __init rcu_spawn_tasks_kthread(void)
rcu_spawn_tasks_kthread_generic(&rcu_tasks); rcu_spawn_tasks_kthread_generic(&rcu_tasks);
return 0; return 0;
} }
core_initcall(rcu_spawn_tasks_kthread);
#ifndef CONFIG_TINY_RCU #ifndef CONFIG_TINY_RCU
static void show_rcu_tasks_classic_gp_kthread(void) static void show_rcu_tasks_classic_gp_kthread(void)
...@@ -697,7 +696,6 @@ static int __init rcu_spawn_tasks_rude_kthread(void) ...@@ -697,7 +696,6 @@ static int __init rcu_spawn_tasks_rude_kthread(void)
rcu_spawn_tasks_kthread_generic(&rcu_tasks_rude); rcu_spawn_tasks_kthread_generic(&rcu_tasks_rude);
return 0; return 0;
} }
core_initcall(rcu_spawn_tasks_rude_kthread);
#ifndef CONFIG_TINY_RCU #ifndef CONFIG_TINY_RCU
static void show_rcu_tasks_rude_gp_kthread(void) static void show_rcu_tasks_rude_gp_kthread(void)
...@@ -975,6 +973,11 @@ static void rcu_tasks_trace_pregp_step(void) ...@@ -975,6 +973,11 @@ static void rcu_tasks_trace_pregp_step(void)
static void rcu_tasks_trace_pertask(struct task_struct *t, static void rcu_tasks_trace_pertask(struct task_struct *t,
struct list_head *hop) struct list_head *hop)
{ {
// During early boot when there is only the one boot CPU, there
// is no idle task for the other CPUs. Just return.
if (unlikely(t == NULL))
return;
WRITE_ONCE(t->trc_reader_special.b.need_qs, false); WRITE_ONCE(t->trc_reader_special.b.need_qs, false);
WRITE_ONCE(t->trc_reader_checked, false); WRITE_ONCE(t->trc_reader_checked, false);
t->trc_ipi_to_cpu = -1; t->trc_ipi_to_cpu = -1;
...@@ -1200,7 +1203,6 @@ static int __init rcu_spawn_tasks_trace_kthread(void) ...@@ -1200,7 +1203,6 @@ static int __init rcu_spawn_tasks_trace_kthread(void)
rcu_spawn_tasks_kthread_generic(&rcu_tasks_trace); rcu_spawn_tasks_kthread_generic(&rcu_tasks_trace);
return 0; return 0;
} }
core_initcall(rcu_spawn_tasks_trace_kthread);
#ifndef CONFIG_TINY_RCU #ifndef CONFIG_TINY_RCU
static void show_rcu_tasks_trace_gp_kthread(void) static void show_rcu_tasks_trace_gp_kthread(void)
...@@ -1229,6 +1231,21 @@ void show_rcu_tasks_gp_kthreads(void) ...@@ -1229,6 +1231,21 @@ void show_rcu_tasks_gp_kthreads(void)
} }
#endif /* #ifndef CONFIG_TINY_RCU */ #endif /* #ifndef CONFIG_TINY_RCU */
void __init rcu_init_tasks_generic(void)
{
#ifdef CONFIG_TASKS_RCU
rcu_spawn_tasks_kthread();
#endif
#ifdef CONFIG_TASKS_RUDE_RCU
rcu_spawn_tasks_rude_kthread();
#endif
#ifdef CONFIG_TASKS_TRACE_RCU
rcu_spawn_tasks_trace_kthread();
#endif
}
#else /* #ifdef CONFIG_TASKS_RCU_GENERIC */ #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */
static inline void rcu_tasks_bootup_oddness(void) {} static inline void rcu_tasks_bootup_oddness(void) {}
void show_rcu_tasks_gp_kthreads(void) {} void show_rcu_tasks_gp_kthreads(void) {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment