CPU_DOWN_PREPARE or CPU_DOWN_PREPARE_FROZEN, depending on whether or not the
   CPU is being offlined while tasks are frozen due to a suspend operation in
   progress
-- All process is migrated away from this outgoing CPU to a new CPU
+- All processes are migrated away from this outgoing CPU to new CPUs.
+  The new CPU is chosen from each process' current cpuset, which may be
+  a subset of all online CPUs.
 - All interrupts targeted to this CPU is migrated to a new CPU
 - timers/bottom half/task lets are also migrated to a new CPU
 - Once all services are migrated, kernel calls an arch specific routine
 
 extern int cpuset_init(void);
 extern void cpuset_init_smp(void);
 extern cpumask_t cpuset_cpus_allowed(struct task_struct *p);
+extern cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
 #define cpuset_current_mems_allowed (current->mems_allowed)
 void cpuset_init_current_mems_allowed(void);
 {
        return cpu_possible_map;
 }
+static inline cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p)
+{
+       return cpu_possible_map;
+}
 
 static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
 {
 
        cpumask_t mask;
 
        mutex_lock(&callback_mutex);
+       mask = cpuset_cpus_allowed_locked(tsk);
+       mutex_unlock(&callback_mutex);
+
+       return mask;
+}
+
+/**
+ * cpuset_cpus_allowed_locked - return cpus_allowed mask from a tasks cpuset.
+ * Must be  called with callback_mutex held.
+ **/
+cpumask_t cpuset_cpus_allowed_locked(struct task_struct *tsk)
+{
+       cpumask_t mask;
+
        task_lock(tsk);
        guarantee_online_cpus(task_cs(tsk), &mask);
        task_unlock(tsk);
-       mutex_unlock(&callback_mutex);
 
        return mask;
 }
 
 
                /* No more Mr. Nice Guy. */
                if (dest_cpu == NR_CPUS) {
+                       cpumask_t cpus_allowed = cpuset_cpus_allowed_locked(p);
+                       /*
+                        * Try to stay on the same cpuset, where the
+                        * current cpuset may be a subset of all cpus.
+                        * The cpuset_cpus_allowed_locked() variant of
+                        * cpuset_cpus_allowed() will not block.  It must be
+                        * called within calls to cpuset_lock/cpuset_unlock.
+                        */
                        rq = task_rq_lock(p, &flags);
-                       cpus_setall(p->cpus_allowed);
+                       p->cpus_allowed = cpus_allowed;
                        dest_cpu = any_online_cpu(p->cpus_allowed);
                        task_rq_unlock(rq, &flags);
 
 
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
+               cpuset_lock(); /* around calls to cpuset_cpus_allowed_lock() */
                migrate_live_tasks(cpu);
                rq = cpu_rq(cpu);
                kthread_stop(rq->migration_thread);
                rq->idle->sched_class = &idle_sched_class;
                migrate_dead_tasks(cpu);
                spin_unlock_irq(&rq->lock);
+               cpuset_unlock();
                migrate_nr_uninterruptible(rq);
                BUG_ON(rq->nr_running != 0);