Commit 28c8f9fe authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'smp-core-2022-05-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull CPU hotplug updates from Thomas Gleixner:

 - Initialize the per-CPU structures during early boot so that the state
   is consistent from the very beginning.

 - Make the virtualization hotplug state handling more robust and let
   the core bringup CPUs which timed out in an earlier attempt again.

 - Make the x86/xen CPU state tracking consistent on a failed online
   attempt, so a consecutive bringup does not fall over the inconsistent
   state.

* tag 'smp-core-2022-05-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  cpu/hotplug: Initialise all cpuhp_cpu_state structs earlier
  cpu/hotplug: Allow the CPU in CPU_UP_PREPARE state to be brought up again.
  x86/xen: Allow to retry if cpu_initialize_context() failed.
parents 985564eb d308077e
...@@ -260,8 +260,11 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) ...@@ -260,8 +260,11 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
return 0; return 0;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (ctxt == NULL) if (ctxt == NULL) {
cpumask_clear_cpu(cpu, xen_cpu_initialized_map);
cpumask_clear_cpu(cpu, cpu_callout_mask);
return -ENOMEM; return -ENOMEM;
}
gdt = get_cpu_gdt_rw(cpu); gdt = get_cpu_gdt_rw(cpu);
......
...@@ -716,14 +716,6 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, ...@@ -716,14 +716,6 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
/* /*
* The cpu hotplug threads manage the bringup and teardown of the cpus * The cpu hotplug threads manage the bringup and teardown of the cpus
*/ */
static void cpuhp_create(unsigned int cpu)
{
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
init_completion(&st->done_up);
init_completion(&st->done_down);
}
static int cpuhp_should_run(unsigned int cpu) static int cpuhp_should_run(unsigned int cpu)
{ {
struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
...@@ -883,15 +875,27 @@ static int cpuhp_kick_ap_work(unsigned int cpu) ...@@ -883,15 +875,27 @@ static int cpuhp_kick_ap_work(unsigned int cpu)
static struct smp_hotplug_thread cpuhp_threads = { static struct smp_hotplug_thread cpuhp_threads = {
.store = &cpuhp_state.thread, .store = &cpuhp_state.thread,
.create = &cpuhp_create,
.thread_should_run = cpuhp_should_run, .thread_should_run = cpuhp_should_run,
.thread_fn = cpuhp_thread_fun, .thread_fn = cpuhp_thread_fun,
.thread_comm = "cpuhp/%u", .thread_comm = "cpuhp/%u",
.selfparking = true, .selfparking = true,
}; };
static __init void cpuhp_init_state(void)
{
struct cpuhp_cpu_state *st;
int cpu;
for_each_possible_cpu(cpu) {
st = per_cpu_ptr(&cpuhp_state, cpu);
init_completion(&st->done_up);
init_completion(&st->done_down);
}
}
void __init cpuhp_threads_init(void) void __init cpuhp_threads_init(void)
{ {
cpuhp_init_state();
BUG_ON(smpboot_register_percpu_thread(&cpuhp_threads)); BUG_ON(smpboot_register_percpu_thread(&cpuhp_threads));
kthread_unpark(this_cpu_read(cpuhp_state.thread)); kthread_unpark(this_cpu_read(cpuhp_state.thread));
} }
......
...@@ -392,6 +392,13 @@ int cpu_check_up_prepare(int cpu) ...@@ -392,6 +392,13 @@ int cpu_check_up_prepare(int cpu)
*/ */
return -EAGAIN; return -EAGAIN;
case CPU_UP_PREPARE:
/*
* Timeout while waiting for the CPU to show up. Allow to try
* again later.
*/
return 0;
default: default:
/* Should not happen. Famous last words. */ /* Should not happen. Famous last words. */
......
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