diff options
author | Gu Zheng <guz.fnst@cn.fujitsu.com> | 2016-08-25 04:35:18 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-21 15:18:39 -0400 |
commit | dc6db24d2476cd09c0ecf2b8d80313539f737a89 (patch) | |
tree | a42cb20e94757560eeabaf8ebe800254e166e8b2 | |
parent | 8ad893faf2eaedb710a3073afbb5d569df2c3e41 (diff) |
x86/acpi: Set persistent cpuid <-> nodeid mapping when booting
The whole patch-set aims at making cpuid <-> nodeid mapping persistent. So that,
when node online/offline happens, cache based on cpuid <-> nodeid mapping such as
wq_numa_possible_cpumask will not cause any problem.
It contains 4 steps:
1. Enable apic registeration flow to handle both enabled and disabled cpus.
2. Introduce a new array storing all possible cpuid <-> apicid mapping.
3. Enable _MAT and MADT relative apis to return non-present or disabled cpus' apicid.
4. Establish all possible cpuid <-> nodeid mapping.
This patch finishes step 4.
This patch set the persistent cpuid <-> nodeid mapping for all enabled/disabled
processors at boot time via an additional acpi namespace walk for processors.
[ tglx: Remove the unneeded exports ]
Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
Signed-off-by: Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: mika.j.penttila@gmail.com
Cc: len.brown@intel.com
Cc: rafael@kernel.org
Cc: rjw@rjwysocki.net
Cc: yasu.isimatu@gmail.com
Cc: linux-mm@kvack.org
Cc: linux-acpi@vger.kernel.org
Cc: isimatu.yasuaki@jp.fujitsu.com
Cc: gongzhaogang@inspur.com
Cc: tj@kernel.org
Cc: izumi.taku@jp.fujitsu.com
Cc: cl@linux.com
Cc: chen.tang@easystack.cn
Cc: akpm@linux-foundation.org
Cc: kamezawa.hiroyu@jp.fujitsu.com
Cc: lenb@kernel.org
Link: http://lkml.kernel.org/r/1472114120-3281-6-git-send-email-douly.fnst@cn.fujitsu.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/ia64/kernel/acpi.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 3 | ||||
-rw-r--r-- | drivers/acpi/acpi_processor.c | 5 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 1 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 68 | ||||
-rw-r--r-- | include/linux/acpi.h | 3 |
6 files changed, 80 insertions, 2 deletions
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 92b7bc956795..9273e034b730 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -796,7 +796,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi) | |||
796 | * ACPI based hotplug CPU support | 796 | * ACPI based hotplug CPU support |
797 | */ | 797 | */ |
798 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 798 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
799 | static int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | 799 | int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) |
800 | { | 800 | { |
801 | #ifdef CONFIG_ACPI_NUMA | 801 | #ifdef CONFIG_ACPI_NUMA |
802 | /* | 802 | /* |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 7d668d172fce..fc8841016116 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -702,7 +702,7 @@ static void __init acpi_set_irq_model_ioapic(void) | |||
702 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 702 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
703 | #include <acpi/processor.h> | 703 | #include <acpi/processor.h> |
704 | 704 | ||
705 | static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | 705 | int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) |
706 | { | 706 | { |
707 | #ifdef CONFIG_ACPI_NUMA | 707 | #ifdef CONFIG_ACPI_NUMA |
708 | int nid; | 708 | int nid; |
@@ -713,6 +713,7 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | |||
713 | numa_set_node(cpu, nid); | 713 | numa_set_node(cpu, nid); |
714 | } | 714 | } |
715 | #endif | 715 | #endif |
716 | return 0; | ||
716 | } | 717 | } |
717 | 718 | ||
718 | int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, int *pcpu) | 719 | int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, int *pcpu) |
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 02b84aa69fa4..f9f23fdd96a1 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -182,6 +182,11 @@ int __weak arch_register_cpu(int cpu) | |||
182 | 182 | ||
183 | void __weak arch_unregister_cpu(int cpu) {} | 183 | void __weak arch_unregister_cpu(int cpu) {} |
184 | 184 | ||
185 | int __weak acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | ||
186 | { | ||
187 | return -ENODEV; | ||
188 | } | ||
189 | |||
185 | static int acpi_processor_hotadd_init(struct acpi_processor *pr) | 190 | static int acpi_processor_hotadd_init(struct acpi_processor *pr) |
186 | { | 191 | { |
187 | unsigned long long sta; | 192 | unsigned long long sta; |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 85b7d07fe5c8..a760dac656ea 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -1193,6 +1193,7 @@ static int __init acpi_init(void) | |||
1193 | acpi_wakeup_device_init(); | 1193 | acpi_wakeup_device_init(); |
1194 | acpi_debugger_init(); | 1194 | acpi_debugger_init(); |
1195 | acpi_setup_sb_notify_handler(); | 1195 | acpi_setup_sb_notify_handler(); |
1196 | acpi_set_processor_mapping(); | ||
1196 | return 0; | 1197 | return 0; |
1197 | } | 1198 | } |
1198 | 1199 | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index fd59ae871db3..88019766a59a 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -280,6 +280,74 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | |||
280 | } | 280 | } |
281 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 281 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
282 | 282 | ||
283 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | ||
284 | static bool __init | ||
285 | map_processor(acpi_handle handle, phys_cpuid_t *phys_id, int *cpuid) | ||
286 | { | ||
287 | int type; | ||
288 | u32 acpi_id; | ||
289 | acpi_status status; | ||
290 | acpi_object_type acpi_type; | ||
291 | unsigned long long tmp; | ||
292 | union acpi_object object = { 0 }; | ||
293 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | ||
294 | |||
295 | status = acpi_get_type(handle, &acpi_type); | ||
296 | if (ACPI_FAILURE(status)) | ||
297 | return false; | ||
298 | |||
299 | switch (acpi_type) { | ||
300 | case ACPI_TYPE_PROCESSOR: | ||
301 | status = acpi_evaluate_object(handle, NULL, NULL, &buffer); | ||
302 | if (ACPI_FAILURE(status)) | ||
303 | return false; | ||
304 | acpi_id = object.processor.proc_id; | ||
305 | break; | ||
306 | case ACPI_TYPE_DEVICE: | ||
307 | status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); | ||
308 | if (ACPI_FAILURE(status)) | ||
309 | return false; | ||
310 | acpi_id = tmp; | ||
311 | break; | ||
312 | default: | ||
313 | return false; | ||
314 | } | ||
315 | |||
316 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; | ||
317 | |||
318 | *phys_id = __acpi_get_phys_id(handle, type, acpi_id, false); | ||
319 | *cpuid = acpi_map_cpuid(*phys_id, acpi_id); | ||
320 | if (*cpuid == -1) | ||
321 | return false; | ||
322 | |||
323 | return true; | ||
324 | } | ||
325 | |||
326 | static acpi_status __init | ||
327 | set_processor_node_mapping(acpi_handle handle, u32 lvl, void *context, | ||
328 | void **rv) | ||
329 | { | ||
330 | phys_cpuid_t phys_id; | ||
331 | int cpu_id; | ||
332 | |||
333 | if (!map_processor(handle, &phys_id, &cpu_id)) | ||
334 | return AE_ERROR; | ||
335 | |||
336 | acpi_map_cpu2node(handle, cpu_id, phys_id); | ||
337 | return AE_OK; | ||
338 | } | ||
339 | |||
340 | void __init acpi_set_processor_mapping(void) | ||
341 | { | ||
342 | /* Set persistent cpu <-> node mapping for all processors. */ | ||
343 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | ||
344 | ACPI_UINT32_MAX, set_processor_node_mapping, | ||
345 | NULL, NULL, NULL); | ||
346 | } | ||
347 | #else | ||
348 | void __init acpi_set_processor_mapping(void) {} | ||
349 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | ||
350 | |||
283 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC | 351 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC |
284 | static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base, | 352 | static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base, |
285 | u64 *phys_addr, int *ioapic_id) | 353 | u64 *phys_addr, int *ioapic_id) |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index c9a596b9535c..5b4f9accf96b 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -271,8 +271,11 @@ static inline bool invalid_phys_cpuid(phys_cpuid_t phys_id) | |||
271 | /* Arch dependent functions for cpu hotplug support */ | 271 | /* Arch dependent functions for cpu hotplug support */ |
272 | int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, int *pcpu); | 272 | int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, int *pcpu); |
273 | int acpi_unmap_cpu(int cpu); | 273 | int acpi_unmap_cpu(int cpu); |
274 | int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid); | ||
274 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 275 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
275 | 276 | ||
277 | void acpi_set_processor_mapping(void); | ||
278 | |||
276 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC | 279 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC |
277 | int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr); | 280 | int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr); |
278 | #endif | 281 | #endif |