}
 }
 
+/*
+ * Called from the idle task. We need to set active here, so we can kick off
+ * the stopper thread.
+ */
+static int cpuhp_set_cpu_active(unsigned int cpu)
+{
+       /* The cpu is marked online, set it active now */
+       set_cpu_active(cpu, true);
+       /* Unpark the stopper thread */
+       stop_machine_unpark(cpu);
+       return 0;
+}
+
 static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st)
 {
        for (st->state--; st->state > st->target; st->state--) {
                .teardown               = takedown_cpu,
                .cant_stop              = true,
        },
+       [CPUHP_CPU_SET_ACTIVE] = {
+               .name                   = "cpu:active",
+               .startup                = cpuhp_set_cpu_active,
+               .teardown               = NULL,
+       },
        [CPUHP_NOTIFY_ONLINE] = {
                .name                   = "notify:online",
                .startup                = notify_online,
 
                set_cpu_rq_start_time();
                return NOTIFY_OK;
 
-       case CPU_ONLINE:
-               /*
-                * At this point a starting CPU has marked itself as online via
-                * set_cpu_online(). But it might not yet have marked itself
-                * as active, which is essential from here on.
-                */
-               set_cpu_active(cpu, true);
-               stop_machine_unpark(cpu);
-               return NOTIFY_OK;
-
        case CPU_DOWN_FAILED:
                set_cpu_active(cpu, true);
                return NOTIFY_OK;