Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Gu Zheng and committed by
Thomas Gleixner
dc6db24d 8ad893fa

+80 -2
+1 -1
arch/ia64/kernel/acpi.c
··· 796 796 * ACPI based hotplug CPU support 797 797 */ 798 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 801 #ifdef CONFIG_ACPI_NUMA 802 802 /*
+2 -1
arch/x86/kernel/acpi/boot.c
··· 702 702 #ifdef CONFIG_ACPI_HOTPLUG_CPU 703 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 707 #ifdef CONFIG_ACPI_NUMA 708 708 int nid; ··· 713 713 numa_set_node(cpu, nid); 714 714 } 715 715 #endif 716 + return 0; 716 717 } 717 718 718 719 int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, int *pcpu)
+5
drivers/acpi/acpi_processor.c
··· 182 182 183 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 190 static int acpi_processor_hotadd_init(struct acpi_processor *pr) 186 191 { 187 192 unsigned long long sta;
+1
drivers/acpi/bus.c
··· 1193 1193 acpi_wakeup_device_init(); 1194 1194 acpi_debugger_init(); 1195 1195 acpi_setup_sb_notify_handler(); 1196 + acpi_set_processor_mapping(); 1196 1197 return 0; 1197 1198 } 1198 1199
+68
drivers/acpi/processor_core.c
··· 280 280 } 281 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 351 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC 284 352 static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base, 285 353 u64 *phys_addr, int *ioapic_id)
+3
include/linux/acpi.h
··· 271 271 /* Arch dependent functions for cpu hotplug support */ 272 272 int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, int *pcpu); 273 273 int acpi_unmap_cpu(int cpu); 274 + int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid); 274 275 #endif /* CONFIG_ACPI_HOTPLUG_CPU */ 276 + 277 + void acpi_set_processor_mapping(void); 275 278 276 279 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC 277 280 int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr);