[PATCH 3/3] x86_64: offset apicid_to_node before use it before init_cpu_to_node

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[PATCH 3/3] x86_64: offset apicid_to_node before use it before init_cpu_to_node

When acpi=off or there is no SRAT defined, apicid_to_node is got from K8
Northbridge PCI configuration space in k8_scan_nodes() in
arch/x86_64/mm/k8toplogy.c.
The problem is that it assumes bsp apic id is 0 at that point.
For four socket system with Quad core cpus installed, all cpus apic id
is offset by 4, and bsp apic id is 4.
For eight socket system with dual core cpus installed, all cpus apic id
is offset by 2, and bsp apic id is 2.
We need offset apicid_to_node array according to boot_cpu_id.--- bsp apic id.
before we use apicid_to_node array.
boot_cpu_id is only valid init_apic_mappings.

So do update_apicid_to_node and init_cpu_to_node after init_apic_mappings

Signed-off-by: Yinghai Lu <[email protected]>

arch/x86_64/kernel/setup.c |   10 ++++++++--
arch/x86_64/mm/numa.c      |   24 ++++++++++++++++++++++++
include/asm-x86_64/numa.h  |    2 ++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 33ef718..1862a91 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -385,8 +385,6 @@ void __init setup_arch(char **cmdline_p)
 	acpi_boot_init();
 #endif
 
-	init_cpu_to_node();
-
 	/*
 	 * get boot-time SMP configuration:
 	 */
@@ -395,6 +393,14 @@ void __init setup_arch(char **cmdline_p)
 	init_apic_mappings();
 
 	/*
+	 * need to put init_cpu_to_node after init_apic_mappings
+	 * we need to get boot_cpu_id (the BSP apic id) to modify
+	 * apicid_to_node array, before init_cpu_node
+	 */
+	update_apicid_to_node();
+	init_cpu_to_node();
+
+	/*
 	 * We trust e820 completely. No explicit ROM probing in memory.
  	 */
 	e820_reserve_resources(); 
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 5154894..91605aa 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -607,6 +607,30 @@ early_param("numa", numa_setup);
  * prior to this call, and this initialization is good enough
  * for the fake NUMA cases.
  */
+void __init update_apicid_to_node(void)
+{
+	/*
+	 * let modify apicid_to_node array when boot_cpu_id !=0
+	 * apicid_to_node[0] != NUMA_NODE
+	 */
+
+	int i;
+
+	/* there is no apic id offset */
+	if (!boot_cpu_id)
+		return;
+
+	/* check if it is already updated */
+	if (apicid_to_node[0] == NUMA_NO_NODE)
+		return;
+
+	for (i = NR_CPUS -1; i >= boot_cpu_id; i--)
+		apicid_to_node[i] = apicid_to_node[i - boot_cpu_id];
+
+	for (i = boot_cpu_id - 1; i >= 0; i--)
+		apicid_to_node[i] = NUMA_NO_NODE;
+
+}
 void __init init_cpu_to_node(void)
 {
 	int i;
diff --git a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h
index 933ff11..282b7a7 100644
--- a/include/asm-x86_64/numa.h
+++ b/include/asm-x86_64/numa.h
@@ -21,6 +21,7 @@ extern int hotadd_percent;
 
 extern unsigned char apicid_to_node[256];
 #ifdef CONFIG_NUMA
+extern void __init update_apicid_to_node(void);
 extern void __init init_cpu_to_node(void);
 
 static inline void clear_node_cpumask(int cpu)
@@ -29,6 +30,7 @@ static inline void clear_node_cpumask(int cpu)
 }
 
 #else
+#define update_apicid_to_node() do {} while (0)
 #define init_cpu_to_node() do {} while (0)
 #define clear_node_cpumask(cpu) do {} while (0)
 #endif

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux