sched/core: Fix illegal RCU from offline CPUs
[sfrench/cifs-2.6.git] / kernel / cpu.c
index 2371292f30b03daa463706a2d9150c9c3bae5861..244d30544377350ae5304a09eafc49ee80bd86db 100644 (file)
@@ -3,6 +3,7 @@
  *
  * This code is licenced under the GPL.
  */
+#include <linux/sched/mm.h>
 #include <linux/proc_fs.h>
 #include <linux/smp.h>
 #include <linux/init.h>
@@ -564,6 +565,21 @@ static int bringup_cpu(unsigned int cpu)
        return bringup_wait_for_ap(cpu);
 }
 
+static int finish_cpu(unsigned int cpu)
+{
+       struct task_struct *idle = idle_thread_get(cpu);
+       struct mm_struct *mm = idle->active_mm;
+
+       /*
+        * idle_task_exit() will have switched to &init_mm, now
+        * clean up any remaining active_mm state.
+        */
+       if (mm != &init_mm)
+               idle->active_mm = &init_mm;
+       mmdrop(mm);
+       return 0;
+}
+
 /*
  * Hotplug state machine related functions
  */
@@ -1549,7 +1565,7 @@ static struct cpuhp_step cpuhp_hp_states[] = {
        [CPUHP_BRINGUP_CPU] = {
                .name                   = "cpu:bringup",
                .startup.single         = bringup_cpu,
-               .teardown.single        = NULL,
+               .teardown.single        = finish_cpu,
                .cant_stop              = true,
        },
        /* Final state before CPU kills itself */