Commit e94cd150 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Peter Zijlstra
Browse files

x86/smpboot: Get rid of cpu_init_secondary()



The synchronization of the AP with the control CPU is a SMP boot problem
and has nothing to do with cpu_init().

Open code cpu_init_secondary() in start_secondary() and move
wait_for_master_cpu() into the SMP boot code.

No functional change.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: default avatarMichael Kelley <mikelley@microsoft.com>
Tested-by: default avatarOleksandr Natalenko <oleksandr@natalenko.name>
Tested-by: Helge Deller <deller@gmx.de> # parisc
Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com> # Steam Deck
Link: https://lore.kernel.org/r/20230512205255.981999763@linutronix.de
parent 2b3be65d
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -551,7 +551,6 @@ extern void switch_gdt_and_percpu_base(int);
extern void load_direct_gdt(int);
extern void load_fixmap_gdt(int);
extern void cpu_init(void);
extern void cpu_init_secondary(void);
extern void cpu_init_exception_handling(void);
extern void cr4_init(void);

+0 −27
Original line number Diff line number Diff line
@@ -2123,19 +2123,6 @@ static void dbg_restore_debug_regs(void)
#define dbg_restore_debug_regs()
#endif /* ! CONFIG_KGDB */

static void wait_for_master_cpu(int cpu)
{
#ifdef CONFIG_SMP
	/*
	 * wait for ACK from master CPU before continuing
	 * with AP initialization
	 */
	WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask));
	while (!cpumask_test_cpu(cpu, cpu_callout_mask))
		cpu_relax();
#endif
}

static inline void setup_getcpu(int cpu)
{
	unsigned long cpudata = vdso_encode_cpunode(cpu, early_cpu_to_node(cpu));
@@ -2239,8 +2226,6 @@ void cpu_init(void)
	struct task_struct *cur = current;
	int cpu = raw_smp_processor_id();

	wait_for_master_cpu(cpu);

	ucode_cpu_init(cpu);

#ifdef CONFIG_NUMA
@@ -2293,18 +2278,6 @@ void cpu_init(void)
	load_fixmap_gdt(cpu);
}

#ifdef CONFIG_SMP
void cpu_init_secondary(void)
{
	/*
	 * Relies on the BP having set-up the IDT tables, which are loaded
	 * on this CPU in cpu_init_exception_handling().
	 */
	cpu_init_exception_handling();
	cpu_init();
}
#endif

#ifdef CONFIG_MICROCODE_LATE_LOADING
/**
 * store_cpu_caps() - Store a snapshot of CPU capabilities
+19 −5
Original line number Diff line number Diff line
@@ -220,6 +220,17 @@ static void ap_calibrate_delay(void)
	cpu_data(smp_processor_id()).loops_per_jiffy = loops_per_jiffy;
}

static void wait_for_master_cpu(int cpu)
{
	/*
	 * Wait for release by control CPU before continuing with AP
	 * initialization.
	 */
	WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask));
	while (!cpumask_test_cpu(cpu, cpu_callout_mask))
		cpu_relax();
}

/*
 * Activate a secondary processor.
 */
@@ -237,13 +248,16 @@ static void notrace start_secondary(void *unused)
	load_cr3(swapper_pg_dir);
	__flush_tlb_all();
#endif
	cpu_init_exception_handling();

	/*
	 * Sync point with wait_cpu_initialized(). Before proceeding through
	 * cpu_init(), the AP will call wait_for_master_cpu() which sets its
	 * own bit in cpu_initialized_mask and then waits for the BSP to set
	 * its bit in cpu_callout_mask to release it.
	 * Sync point with wait_cpu_initialized(). Sets AP in
	 * cpu_initialized_mask and then waits for the control CPU
	 * to release it.
	 */
	cpu_init_secondary();
	wait_for_master_cpu(raw_smp_processor_id());

	cpu_init();
	rcu_cpu_starting(raw_smp_processor_id());
	x86_cpuinit.early_percpu_clock_init();