Commit 36bbbd0e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu

Pull RCU fix from Paul McKenney:
 "This is a fix for a regression in the v5.10 merge window, but it was
  reported quite late in the v5.10 process, plus generating and testing
  the fix took some time.

  The regression is due to commit 36dadef2 ("kprobes: Init kprobes
  in early_initcall") which on powerpc can use RCU Tasks before
  initialization, resulting in boot failures.

  The fix is straightforward, simply moving initialization of RCU Tasks
  before the early_initcall()s. The fix has been exposed to -next and
  kbuild test robot testing, and has been tested by the PowerPC guys"

* 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu:
  rcu-tasks: Move RCU-tasks initialization to before early_initcall()
parents f4f6a2e3 1b04fa99
...@@ -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);
......
...@@ -1518,6 +1518,7 @@ static noinline void __init kernel_init_freeable(void) ...@@ -1518,6 +1518,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;
...@@ -564,7 +564,6 @@ static int __init rcu_spawn_tasks_kthread(void) ...@@ -564,7 +564,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);
#if !defined(CONFIG_TINY_RCU) #if !defined(CONFIG_TINY_RCU)
void show_rcu_tasks_classic_gp_kthread(void) void show_rcu_tasks_classic_gp_kthread(void)
...@@ -692,7 +691,6 @@ static int __init rcu_spawn_tasks_rude_kthread(void) ...@@ -692,7 +691,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);
#if !defined(CONFIG_TINY_RCU) #if !defined(CONFIG_TINY_RCU)
void show_rcu_tasks_rude_gp_kthread(void) void show_rcu_tasks_rude_gp_kthread(void)
...@@ -968,6 +966,11 @@ static void rcu_tasks_trace_pregp_step(void) ...@@ -968,6 +966,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;
...@@ -1193,7 +1196,6 @@ static int __init rcu_spawn_tasks_trace_kthread(void) ...@@ -1193,7 +1196,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);
#if !defined(CONFIG_TINY_RCU) #if !defined(CONFIG_TINY_RCU)
void show_rcu_tasks_trace_gp_kthread(void) void show_rcu_tasks_trace_gp_kthread(void)
...@@ -1222,6 +1224,21 @@ void show_rcu_tasks_gp_kthreads(void) ...@@ -1222,6 +1224,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