diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2013-06-14 17:16:35 +0200 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2017-02-08 10:03:13 -0500 |
commit | 451378b0b07e453d96eb4c2395b5836c355f06f0 (patch) | |
tree | cfa9d5a001233d79eeed9572e4e98b1063a8f975 | |
parent | d9fb21550cb920d43d1733c6810821d587e13d9f (diff) | |
download | linux-stable-rt-451378b0b07e453d96eb4c2395b5836c355f06f0.tar.gz |
kernel/hotplug: restore original cpu mask oncpu/down
If a task which is allowed to run only on CPU X puts CPU Y down then it
will be allowed on all CPUs but the on CPU Y after it comes back from
kernel. This patch ensures that we don't lose the initial setting unless
the CPU the task is running is going down.
Cc: stable-rt@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r-- | kernel/cpu.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 25788ecb533452..1463d0c961d565 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -572,6 +572,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) .hcpu = hcpu, }; cpumask_var_t cpumask; + cpumask_var_t cpumask_org; if (num_online_cpus() == 1) return -EBUSY; @@ -582,6 +583,12 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) /* Move the downtaker off the unplug cpu */ if (!alloc_cpumask_var(&cpumask, GFP_KERNEL)) return -ENOMEM; + if (!alloc_cpumask_var(&cpumask_org, GFP_KERNEL)) { + free_cpumask_var(cpumask); + return -ENOMEM; + } + + cpumask_copy(cpumask_org, tsk_cpus_allowed(current)); cpumask_andnot(cpumask, cpu_online_mask, cpumask_of(cpu)); set_cpus_allowed_ptr(current, cpumask); free_cpumask_var(cpumask); @@ -590,7 +597,8 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) if (mycpu == cpu) { printk(KERN_ERR "Yuck! Still on unplug CPU\n!"); migrate_enable(); - return -EBUSY; + err = -EBUSY; + goto restore_cpus; } cpu_hotplug_begin(); @@ -649,6 +657,9 @@ out_cancel: cpu_hotplug_done(); if (!err) cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu); +restore_cpus: + set_cpus_allowed_ptr(current, cpumask_org); + free_cpumask_var(cpumask_org); return err; } |