cpu: Defer smpboot kthread unparking until CPU known to scheduler
[firefly-linux-kernel-4.4.55.git] / kernel / cpu.c
index d46b4dae0ca097130f78ffa39a5aada6931e5a95..57858cebd6b561939dbc5b1bbaeecf797ec56492 100644 (file)
@@ -448,6 +448,37 @@ out:
 EXPORT_SYMBOL(cpu_down);
 #endif /*CONFIG_HOTPLUG_CPU*/
 
+/*
+ * Unpark per-CPU smpboot kthreads at CPU-online time.
+ */
+static int smpboot_thread_call(struct notifier_block *nfb,
+                              unsigned long action, void *hcpu)
+{
+       int cpu = (long)hcpu;
+
+       switch (action & ~CPU_TASKS_FROZEN) {
+
+       case CPU_ONLINE:
+               smpboot_unpark_threads(cpu);
+               break;
+
+       default:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block smpboot_thread_notifier = {
+       .notifier_call = smpboot_thread_call,
+       .priority = CPU_PRI_SMPBOOT,
+};
+
+void __cpuinit smpboot_thread_init(void)
+{
+       register_cpu_notifier(&smpboot_thread_notifier);
+}
+
 /* Requires cpu_add_remove_lock to be held */
 static int _cpu_up(unsigned int cpu, int tasks_frozen)
 {
@@ -487,9 +518,6 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen)
                goto out_notify;
        BUG_ON(!cpu_online(cpu));
 
-       /* Wake the per cpu threads */
-       smpboot_unpark_threads(cpu);
-
        /* Now call notifier in preparation. */
        cpu_notify(CPU_ONLINE | mod, hcpu);