* Both the cpu-hotplug and stop task are in this case and are
         * required to complete the hotplug process.
         */
-       if (is_per_cpu_kthread(push_task))
+       if (is_per_cpu_kthread(push_task)) {
+               /*
+                * If this is the idle task on the outgoing CPU try to wake
+                * up the hotplug control thread which might wait for the
+                * last task to vanish. The rcuwait_active() check is
+                * accurate here because the waiter is pinned on this CPU
+                * and can't obviously be running in parallel.
+                */
+               if (!rq->nr_running && rcuwait_active(&rq->hotplug_wait)) {
+                       raw_spin_unlock(&rq->lock);
+                       rcuwait_wake_up(&rq->hotplug_wait);
+                       raw_spin_lock(&rq->lock);
+               }
                return;
+       }
 
        get_task_struct(push_task);
        /*
        rq_unlock_irqrestore(rq, &rf);
 }
 
+/*
+ * Invoked from a CPUs hotplug control thread after the CPU has been marked
+ * inactive. All tasks which are not per CPU kernel threads are either
+ * pushed off this CPU now via balance_push() or placed on a different CPU
+ * during wakeup. Wait until the CPU is quiescent.
+ */
+static void balance_hotplug_wait(void)
+{
+       struct rq *rq = this_rq();
+
+       rcuwait_wait_event(&rq->hotplug_wait, rq->nr_running == 1,
+                          TASK_UNINTERRUPTIBLE);
+}
+
 #else
 
 static inline void balance_push(struct rq *rq)
 {
 }
 
+static inline void balance_hotplug_wait(void)
+{
+}
+
 #endif /* CONFIG_HOTPLUG_CPU */
 
 void set_rq_online(struct rq *rq)
                return ret;
        }
        sched_domains_numa_masks_clear(cpu);
+
+       /* Wait for all non per CPU kernel threads to vanish. */
+       balance_hotplug_wait();
+
        return 0;
 }
 
 
                rq_csd_init(rq, &rq->nohz_csd, nohz_csd_func);
 #endif
+#ifdef CONFIG_HOTPLUG_CPU
+               rcuwait_init(&rq->hotplug_wait);
+#endif
 #endif /* CONFIG_SMP */
                hrtick_rq_init(rq);
                atomic_set(&rq->nr_iowait, 0);