@@ -329,6 +329,14 @@ static int notify_starting(unsigned int cpu)
329329 return 0 ;
330330}
331331
332+ static int bringup_wait_for_ap (unsigned int cpu )
333+ {
334+ struct cpuhp_cpu_state * st = per_cpu_ptr (& cpuhp_state , cpu );
335+
336+ wait_for_completion (& st -> done );
337+ return st -> result ;
338+ }
339+
332340static int bringup_cpu (unsigned int cpu )
333341{
334342 struct task_struct * idle = idle_thread_get (cpu );
@@ -340,8 +348,9 @@ static int bringup_cpu(unsigned int cpu)
340348 cpu_notify (CPU_UP_CANCELED , cpu );
341349 return ret ;
342350 }
351+ ret = bringup_wait_for_ap (cpu );
343352 BUG_ON (!cpu_online (cpu ));
344- return 0 ;
353+ return ret ;
345354}
346355
347356/*
@@ -470,7 +479,7 @@ static void cpuhp_thread_fun(unsigned int cpu)
470479 }
471480 } else {
472481 /* Cannot happen .... */
473- BUG_ON (st -> state < CPUHP_KICK_AP_THREAD );
482+ BUG_ON (st -> state < CPUHP_AP_ONLINE_IDLE );
474483
475484 /* Regular hotplug work */
476485 if (st -> state < st -> target )
@@ -780,7 +789,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
780789 * If the current CPU state is in the range of the AP hotplug thread,
781790 * then we need to kick the thread.
782791 */
783- if (st -> state >= CPUHP_KICK_AP_THREAD ) {
792+ if (st -> state > CPUHP_TEARDOWN_CPU ) {
784793 ret = cpuhp_kick_ap_work (cpu );
785794 /*
786795 * The AP side has done the error rollback already. Just
@@ -793,11 +802,11 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
793802 * We might have stopped still in the range of the AP hotplug
794803 * thread. Nothing to do anymore.
795804 */
796- if (st -> state >= CPUHP_KICK_AP_THREAD )
805+ if (st -> state > CPUHP_TEARDOWN_CPU )
797806 goto out ;
798807 }
799808 /*
800- * The AP brought itself down below CPUHP_KICK_AP_THREAD . So we need
809+ * The AP brought itself down to CPUHP_TEARDOWN_CPU . So we need
801810 * to do the further cleanups.
802811 */
803812 ret = cpuhp_down_callbacks (cpu , st , cpuhp_bp_states , target );
@@ -859,18 +868,32 @@ void notify_cpu_starting(unsigned int cpu)
859868
860869/*
861870 * Called from the idle task. We need to set active here, so we can kick off
862- * the stopper thread.
871+ * the stopper thread and unpark the smpboot threads. If the target state is
872+ * beyond CPUHP_AP_ONLINE_IDLE we kick cpuhp thread and let it bring up the
873+ * cpu further.
863874 */
864- static int cpuhp_set_cpu_active ( unsigned int cpu )
875+ void cpuhp_online_idle ( enum cpuhp_state state )
865876{
866- struct cpuhp_cpu_state * st = per_cpu_ptr (& cpuhp_state , cpu );
877+ struct cpuhp_cpu_state * st = this_cpu_ptr (& cpuhp_state );
878+ unsigned int cpu = smp_processor_id ();
879+
880+ /* Happens for the boot cpu */
881+ if (state != CPUHP_AP_ONLINE_IDLE )
882+ return ;
883+
884+ st -> state = CPUHP_AP_ONLINE_IDLE ;
867885
868886 /* The cpu is marked online, set it active now */
869887 set_cpu_active (cpu , true);
870- /* Unpark the stopper thread and the hotplug thread */
888+ /* Unpark the stopper thread and the hotplug thread of this cpu */
871889 stop_machine_unpark (cpu );
872890 kthread_unpark (st -> thread );
873- return 0 ;
891+
892+ /* Should we go further up ? */
893+ if (st -> target > CPUHP_AP_ONLINE_IDLE )
894+ __cpuhp_kick_ap_work (st );
895+ else
896+ complete (& st -> done );
874897}
875898
876899/* Requires cpu_add_remove_lock to be held */
@@ -910,7 +933,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
910933 * If the current CPU state is in the range of the AP hotplug thread,
911934 * then we need to kick the thread once more.
912935 */
913- if (st -> state >= CPUHP_KICK_AP_THREAD ) {
936+ if (st -> state > CPUHP_BRINGUP_CPU ) {
914937 ret = cpuhp_kick_ap_work (cpu );
915938 /*
916939 * The AP side has done the error rollback already. Just
@@ -922,10 +945,10 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
922945
923946 /*
924947 * Try to reach the target state. We max out on the BP at
925- * CPUHP_KICK_AP_THREAD . After that the AP hotplug thread is
948+ * CPUHP_BRINGUP_CPU . After that the AP hotplug thread is
926949 * responsible for bringing it up to the target state.
927950 */
928- target = min ((int )target , CPUHP_KICK_AP_THREAD );
951+ target = min ((int )target , CPUHP_BRINGUP_CPU );
929952 ret = cpuhp_up_callbacks (cpu , st , cpuhp_bp_states , target );
930953out :
931954 cpu_hotplug_done ();
@@ -1146,22 +1169,7 @@ static struct cpuhp_step cpuhp_bp_states[] = {
11461169 .teardown = takedown_cpu ,
11471170 .cant_stop = true,
11481171 },
1149- [CPUHP_CPU_SET_ACTIVE ] = {
1150- .name = "cpu:active" ,
1151- .startup = cpuhp_set_cpu_active ,
1152- .teardown = NULL ,
1153- },
1154- [CPUHP_KICK_AP_THREAD ] = {
1155- .name = "cpuhp:kickthread" ,
1156- .startup = cpuhp_kick_ap_work ,
1157- .teardown = cpuhp_kick_ap_work ,
1158- },
11591172#endif
1160- [CPUHP_BP_ONLINE ] = {
1161- .name = "online" ,
1162- .startup = NULL ,
1163- .teardown = NULL ,
1164- },
11651173};
11661174
11671175/* Application processor state steps */
@@ -1204,7 +1212,7 @@ static bool cpuhp_is_ap_state(enum cpuhp_state state)
12041212{
12051213 if (state >= CPUHP_AP_OFFLINE && state <= CPUHP_AP_ONLINE )
12061214 return true;
1207- return state > CPUHP_BP_ONLINE ;
1215+ return state > CPUHP_BRINGUP_CPU ;
12081216}
12091217
12101218static struct cpuhp_step * cpuhp_get_step (enum cpuhp_state state )
0 commit comments