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

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
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -260,8 +260,11 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
		return 0;

	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;
	}

	gdt = get_cpu_gdt_rw(cpu);

+13 −9
Original line number Diff line number Diff line
@@ -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
 */
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)
{
	struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
@@ -883,15 +875,27 @@ static int cpuhp_kick_ap_work(unsigned int cpu)

static struct smp_hotplug_thread cpuhp_threads = {
	.store			= &cpuhp_state.thread,
	.create			= &cpuhp_create,
	.thread_should_run	= cpuhp_should_run,
	.thread_fn		= cpuhp_thread_fun,
	.thread_comm		= "cpuhp/%u",
	.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)
{
	cpuhp_init_state();
	BUG_ON(smpboot_register_percpu_thread(&cpuhp_threads));
	kthread_unpark(this_cpu_read(cpuhp_state.thread));
}
+7 −0
Original line number Diff line number Diff line
@@ -392,6 +392,13 @@ int cpu_check_up_prepare(int cpu)
		 */
		return -EAGAIN;

	case CPU_UP_PREPARE:
		/*
		 * Timeout while waiting for the CPU to show up. Allow to try
		 * again later.
		 */
		return 0;

	default:

		/* Should not happen.  Famous last words. */