ACPI / processor: move try_offline_node() after acpi_unmap_lsapic()
try_offline_node() checks that all CPUs associated with the given
node have been removed by using cpu_present_bits. If all cpus
related to that node have been removed, try_offline_node() clears
the node information.
However, try_offline_node() called from acpi_processor_remove() never
clears the node information. For disabling cpu_present_bits,
acpi_unmap_lsapic() needs be called. Yet, acpi_unmap_lsapic() is
called after try_offline_node() has run. So when try_offline_node()
runs, the CPU's cpu_present_bits is always set.
Fix the issue by moving try_offline_node() after acpi_unmap_lsapic().
The problem fixed here was uncovered by commit cecdb19
"ACPI / scan:
Change the implementation of acpi_bus_trim()".
[rjw: Changelog]
Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Cc: 3.9+ <stable@vger.kernel.org> # 3.9+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
007ccfcf89
commit
1e385f6f97
|
@ -451,7 +451,6 @@ static void acpi_processor_remove(struct acpi_device *device)
|
||||||
/* Clean up. */
|
/* Clean up. */
|
||||||
per_cpu(processor_device_array, pr->id) = NULL;
|
per_cpu(processor_device_array, pr->id) = NULL;
|
||||||
per_cpu(processors, pr->id) = NULL;
|
per_cpu(processors, pr->id) = NULL;
|
||||||
try_offline_node(cpu_to_node(pr->id));
|
|
||||||
|
|
||||||
/* Remove the CPU. */
|
/* Remove the CPU. */
|
||||||
get_online_cpus();
|
get_online_cpus();
|
||||||
|
@ -459,6 +458,8 @@ static void acpi_processor_remove(struct acpi_device *device)
|
||||||
acpi_unmap_lsapic(pr->id);
|
acpi_unmap_lsapic(pr->id);
|
||||||
put_online_cpus();
|
put_online_cpus();
|
||||||
|
|
||||||
|
try_offline_node(cpu_to_node(pr->id));
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free_cpumask_var(pr->throttling.shared_cpu_map);
|
free_cpumask_var(pr->throttling.shared_cpu_map);
|
||||||
kfree(pr);
|
kfree(pr);
|
||||||
|
|
Loading…
Reference in New Issue