CPUHP_BP_PREPARE_DYN,
CPUHP_BP_PREPARE_DYN_END = CPUHP_BP_PREPARE_DYN + 20,
+ CPUHP_BP_KICK_AP,
CPUHP_BRINGUP_CPU,
/*
static inline void cpuhp_online_idle(enum cpuhp_state state) { }
#endif
+struct task_struct;
+
void cpuhp_ap_sync_alive(void);
void cpuhp_ap_report_dead(void);
+int arch_cpuhp_kick_ap_alive(unsigned int cpu, struct task_struct *tidle);
void arch_cpuhp_cleanup_kick_cpu(unsigned int cpu);
void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu);
*/
irq_lock_sparse();
- /* Arch-specific enabling code. */
- ret = __cpu_up(cpu, idle);
- if (ret)
- goto out_unlock;
+ /*
+ * If split startup is not enabled, use the all-in-one architecture
+ * specific __cpu_up() function to kick the CPU alive and eventually
+ * do their own synchronization.
+ */
+ if (!IS_ENABLED(CONFIG_HOTPLUG_SPLIT_STARTUP)) {
+ ret = __cpu_up(cpu, idle);
+ if (ret)
+ goto out_unlock;
+ }
ret = cpuhp_bp_sync_alive(cpu);
if (ret)
return ret;
}
+#ifdef CONFIG_HOTPLUG_SPLIT_STARTUP
+static int cpuhp_kick_ap_alive(unsigned int cpu)
+{
+ int ret = cpuhp_can_boot_ap(cpu);
+
+ if (ret)
+ return ret;
+
+ return arch_cpuhp_kick_ap_alive(cpu, idle_thread_get(cpu));
+}
+#endif
+
static int finish_cpu(unsigned int cpu)
{
struct task_struct *idle = idle_thread_get(cpu);
.teardown.single = timers_dead_cpu,
},
- /* Kicks the plugged cpu into life */
+#ifdef CONFIG_HOTPLUG_SPLIT_STARTUP
+ /*
+ * Kicks the AP alive. AP will wait in cpuhp_ap_sync_alive() until
+ * the next step will release it.
+ */
+ [CPUHP_BP_KICK_AP] = {
+ .name = "cpu:kick_ap",
+ .startup.single = cpuhp_kick_ap_alive,
+ },
+
+ /*
+ * Waits for the AP to reach cpuhp_ap_sync_alive() and then
+ * releases it for the complete bringup.
+ *
+ * Deliberately separate from the below for the non-split case for
+ * documentation purposes and in preparation for possible further
+ * split ups.
+ */
[CPUHP_BRINGUP_CPU] = {
.name = "cpu:bringup",
.startup.single = bringup_cpu,
.teardown.single = finish_cpu,
.cant_stop = true,
},
+#else
+ /*
+ * All-in-one CPU bringup state which includes the kick alive.
+ */
+ [CPUHP_BRINGUP_CPU] = {
+ .name = "cpu:bringup",
+ .startup.single = bringup_cpu,
+ .teardown.single = finish_cpu,
+ .cant_stop = true,
+ },
+#endif
/* Final state before CPU kills itself */
[CPUHP_AP_IDLE_DEAD] = {
.name = "idle:dead",