workqueue: Convert to state machine callbacks
[cascardo/linux.git] / kernel / cpu.c
index 3e3f6e4..af53f82 100644 (file)
@@ -517,6 +517,13 @@ static int cpuhp_invoke_ap_callback(int cpu, enum cpuhp_state state,
        if (!cpu_online(cpu))
                return 0;
 
+       /*
+        * If we are up and running, use the hotplug thread. For early calls
+        * we invoke the thread function directly.
+        */
+       if (!st->thread)
+               return cpuhp_invoke_callback(cpu, state, cb);
+
        st->cb_state = state;
        st->cb = cb;
        /*
@@ -703,21 +710,6 @@ static int takedown_cpu(unsigned int cpu)
        struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
        int err;
 
-       /*
-        * By now we've cleared cpu_active_mask, wait for all preempt-disabled
-        * and RCU users of this state to go away such that all new such users
-        * will observe it.
-        *
-        * For CONFIG_PREEMPT we have preemptible RCU and its sync_rcu() might
-        * not imply sync_sched(), so wait for both.
-        *
-        * Do sync before park smpboot threads to take care the rcu boost case.
-        */
-       if (IS_ENABLED(CONFIG_PREEMPT))
-               synchronize_rcu_mult(call_rcu, call_rcu_sched);
-       else
-               synchronize_rcu();
-
        /* Park the smpboot threads */
        kthread_park(per_cpu_ptr(&cpuhp_state, cpu)->thread);
        smpboot_park_threads(cpu);
@@ -923,8 +915,6 @@ void cpuhp_online_idle(enum cpuhp_state state)
 
        st->state = CPUHP_AP_ONLINE_IDLE;
 
-       /* The cpu is marked online, set it active now */
-       set_cpu_active(cpu, true);
        /* Unpark the stopper thread and the hotplug thread of this cpu */
        stop_machine_unpark(cpu);
        kthread_unpark(st->thread);
@@ -1190,6 +1180,16 @@ static struct cpuhp_step cpuhp_bp_states[] = {
                .teardown               = NULL,
                .cant_stop              = true,
        },
+       [CPUHP_PERF_PREPARE] = {
+               .name = "perf prepare",
+               .startup = perf_event_init_cpu,
+               .teardown = perf_event_exit_cpu,
+       },
+       [CPUHP_WORKQUEUE_PREP] = {
+               .name = "workqueue prepare",
+               .startup = workqueue_prepare_cpu,
+               .teardown = NULL,
+       },
        /*
         * Preparatory and dead notifiers. Will be replaced once the notifiers
         * are converted to states.
@@ -1218,6 +1218,8 @@ static struct cpuhp_step cpuhp_bp_states[] = {
                .teardown               = takedown_cpu,
                .cant_stop              = true,
        },
+#else
+       [CPUHP_BRINGUP_CPU] = { },
 #endif
 };
 
@@ -1236,6 +1238,12 @@ static struct cpuhp_step cpuhp_ap_states[] = {
                .name                   = "ap:offline",
                .cant_stop              = true,
        },
+       /* First state is scheduler control. Interrupts are disabled */
+       [CPUHP_AP_SCHED_STARTING] = {
+               .name                   = "sched:starting",
+               .startup                = sched_cpu_starting,
+               .teardown               = sched_cpu_dying,
+       },
        /*
         * Low level startup/teardown notifiers. Run with interrupts
         * disabled. Will be removed once the notifiers are converted to
@@ -1259,6 +1267,17 @@ static struct cpuhp_step cpuhp_ap_states[] = {
                .startup                = smpboot_unpark_threads,
                .teardown               = NULL,
        },
+       [CPUHP_AP_PERF_ONLINE] = {
+               .name = "perf online",
+               .startup = perf_event_init_cpu,
+               .teardown = perf_event_exit_cpu,
+       },
+       [CPUHP_AP_WORKQUEUE_ONLINE] = {
+               .name = "workqueue online",
+               .startup = workqueue_online_cpu,
+               .teardown = workqueue_offline_cpu,
+       },
+
        /*
         * Online/down_prepare notifiers. Will be removed once the notifiers
         * are converted to states.
@@ -1274,6 +1293,15 @@ static struct cpuhp_step cpuhp_ap_states[] = {
         * The dynamically registered state space is here
         */
 
+#ifdef CONFIG_SMP
+       /* Last state is scheduler control setting the cpu active */
+       [CPUHP_AP_ACTIVE] = {
+               .name                   = "sched:active",
+               .startup                = sched_cpu_activate,
+               .teardown               = sched_cpu_deactivate,
+       },
+#endif
+
        /* CPU is fully up and running. */
        [CPUHP_ONLINE] = {
                .name                   = "online",