diff options
author | Daniel J Blueman <daniel@numascale-asia.com> | 2011-12-05 03:20:37 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-12-05 11:17:21 -0500 |
commit | 64be4c1c2428e148de6081af235e2418e6a66dda (patch) | |
tree | 40c9e75b84e5deae48a3012da59c2c64be1fe369 | |
parent | 9a0ebfbe3f1007008d198ccc6b86783cdb312fec (diff) |
x86: Add x86_init platform override to fix up NUMA core numbering
Add an x86_init vector for handling inconsistent core numbering.
This is useful for multi-fabric platforms, such as Numascale
NumaConnect.
v2:
- use struct x86_cpuinit_ops
- provide default fall-back function to warn
Signed-off-by: Daniel J Blueman <daniel@numascale-asia.com>
Cc: Steffen Persvold <sp@numascale.com>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Link: http://lkml.kernel.org/r/1323073238-32686-2-git-send-email-daniel@numascale-asia.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/include/asm/x86_init.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/amd.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 9 | ||||
-rw-r--r-- | arch/x86/kernel/x86_init.c | 1 |
4 files changed, 20 insertions, 0 deletions
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index 1971e652d24b..1ac860a09849 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h | |||
@@ -7,6 +7,7 @@ | |||
7 | struct mpc_bus; | 7 | struct mpc_bus; |
8 | struct mpc_cpu; | 8 | struct mpc_cpu; |
9 | struct mpc_table; | 9 | struct mpc_table; |
10 | struct cpuinfo_x86; | ||
10 | 11 | ||
11 | /** | 12 | /** |
12 | * struct x86_init_mpparse - platform specific mpparse ops | 13 | * struct x86_init_mpparse - platform specific mpparse ops |
@@ -147,6 +148,7 @@ struct x86_init_ops { | |||
147 | */ | 148 | */ |
148 | struct x86_cpuinit_ops { | 149 | struct x86_cpuinit_ops { |
149 | void (*setup_percpu_clockev)(void); | 150 | void (*setup_percpu_clockev)(void); |
151 | void (*fixup_cpu_id)(struct cpuinfo_x86 *c, int node); | ||
150 | }; | 152 | }; |
151 | 153 | ||
152 | /** | 154 | /** |
@@ -186,5 +188,6 @@ extern struct x86_msi_ops x86_msi; | |||
186 | 188 | ||
187 | extern void x86_init_noop(void); | 189 | extern void x86_init_noop(void); |
188 | extern void x86_init_uint_noop(unsigned int unused); | 190 | extern void x86_init_uint_noop(unsigned int unused); |
191 | extern void x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node); | ||
189 | 192 | ||
190 | #endif | 193 | #endif |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 0bab2b18bb20..ef21bdccd674 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -353,6 +353,13 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c) | |||
353 | if (node == NUMA_NO_NODE) | 353 | if (node == NUMA_NO_NODE) |
354 | node = per_cpu(cpu_llc_id, cpu); | 354 | node = per_cpu(cpu_llc_id, cpu); |
355 | 355 | ||
356 | /* | ||
357 | * If core numbers are inconsistent, it's likely a multi-fabric platform, | ||
358 | * so invoke platform-specific handler | ||
359 | */ | ||
360 | if (c->phys_proc_id != node) | ||
361 | x86_cpuinit.fixup_cpu_id(c, node); | ||
362 | |||
356 | if (!node_online(node)) { | 363 | if (!node_online(node)) { |
357 | /* | 364 | /* |
358 | * Two possibilities here: | 365 | * Two possibilities here: |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index aa003b13a831..ad4da45effb9 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1141,6 +1141,15 @@ static void dbg_restore_debug_regs(void) | |||
1141 | #endif /* ! CONFIG_KGDB */ | 1141 | #endif /* ! CONFIG_KGDB */ |
1142 | 1142 | ||
1143 | /* | 1143 | /* |
1144 | * Prints an error where the NUMA and configured core-number mismatch and the | ||
1145 | * platform didn't override this to fix it up | ||
1146 | */ | ||
1147 | void __cpuinit x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node) | ||
1148 | { | ||
1149 | pr_err("NUMA core number %d differs from configured core number %d\n", node, c->phys_proc_id); | ||
1150 | } | ||
1151 | |||
1152 | /* | ||
1144 | * cpu_init() initializes state that is per-CPU. Some data is already | 1153 | * cpu_init() initializes state that is per-CPU. Some data is already |
1145 | * initialized (naturally) in the bootstrap process, such as the GDT | 1154 | * initialized (naturally) in the bootstrap process, such as the GDT |
1146 | * and IDT. We reload them nevertheless, this function acts as a | 1155 | * and IDT. We reload them nevertheless, this function acts as a |
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index c1d6cd549397..91f83e21b989 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c | |||
@@ -92,6 +92,7 @@ struct x86_init_ops x86_init __initdata = { | |||
92 | 92 | ||
93 | struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = { | 93 | struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = { |
94 | .setup_percpu_clockev = setup_secondary_APIC_clock, | 94 | .setup_percpu_clockev = setup_secondary_APIC_clock, |
95 | .fixup_cpu_id = x86_default_fixup_cpu_id, | ||
95 | }; | 96 | }; |
96 | 97 | ||
97 | static void default_nmi_init(void) { }; | 98 | static void default_nmi_init(void) { }; |