Merge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 4 Sep 2017 20:53:53 +0000 (13:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 4 Sep 2017 20:53:53 +0000 (13:53 -0700)
Pull CPU hotplug fix from Thomas Gleixner:
 "A single fix to handle the removal of the first dynamic CPU hotplug
  state correctly"

* 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  smp/hotplug: Handle removal correctly in cpuhp_store_callbacks()

1  2 
kernel/cpu.c

diff --combined kernel/cpu.c
@@@ -650,7 -650,6 +650,7 @@@ static int takedown_cpu(unsigned int cp
        __cpu_die(cpu);
  
        tick_cleanup_dead_cpu(cpu);
 +      rcutree_migrate_callbacks(cpu);
        return 0;
  }
  
@@@ -1253,7 -1252,17 +1253,17 @@@ static int cpuhp_store_callbacks(enum c
        struct cpuhp_step *sp;
        int ret = 0;
  
-       if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) {
+       /*
+        * If name is NULL, then the state gets removed.
+        *
+        * CPUHP_AP_ONLINE_DYN and CPUHP_BP_PREPARE_DYN are handed out on
+        * the first allocation from these dynamic ranges, so the removal
+        * would trigger a new allocation and clear the wrong (already
+        * empty) state, leaving the callbacks of the to be cleared state
+        * dangling, which causes wreckage on the next hotplug operation.
+        */
+       if (name && (state == CPUHP_AP_ONLINE_DYN ||
+                    state == CPUHP_BP_PREPARE_DYN)) {
                ret = cpuhp_reserve_state(state);
                if (ret < 0)
                        return ret;