diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-13 02:39:30 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-12 17:43:49 -0700 |
commit | c7991b0b720efa5e0a590f6359d36e09bd187b76 (patch) | |
tree | f601b37ad472f0818c06e18fd9fa5a4d40d702bd /drivers/base | |
parent | 910f5c7cdb1d4541997f01c17b731bdfe2e92eda (diff) | |
download | blackbird-op-linux-c7991b0b720efa5e0a590f6359d36e09bd187b76.tar.gz blackbird-op-linux-c7991b0b720efa5e0a590f6359d36e09bd187b76.zip |
driver core / cpu: Check if NUMA node is valid before bringing CPU up
There is a potential race condition between cpu_subsys_online()
and either acpi_processor_remove() or remove_memory() that execute
try_offline_node(). Namely, it is possible that cpu_subsys_online()
will run right after the CPUs NUMA node has been put offline and
cpu_to_node() executed by it will return NUMA_NO_NODE (-1). In
that case the CPU is gone and it doesn't make sense to call cpu_up()
for it, so make cpu_subsys_online() return -ENODEV then.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/cpu.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4c358bc44c72..6bfaaca6955e 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -43,11 +43,14 @@ static int __ref cpu_subsys_online(struct device *dev) struct cpu *cpu = container_of(dev, struct cpu, dev); int cpuid = dev->id; int from_nid, to_nid; - int ret; + int ret = -ENODEV; cpu_hotplug_driver_lock(); from_nid = cpu_to_node(cpuid); + if (from_nid == NUMA_NO_NODE) + goto out; + ret = cpu_up(cpuid); /* * When hot adding memory to memoryless node and enabling a cpu @@ -57,6 +60,7 @@ static int __ref cpu_subsys_online(struct device *dev) if (from_nid != to_nid) change_cpu_under_node(cpu, from_nid, to_nid); + out: cpu_hotplug_driver_unlock(); return ret; } |