aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu')
-rw-r--r--arch/x86/kernel/cpu/amd.c47
-rw-r--r--arch/x86/kernel/cpu/intel.c3
2 files changed, 31 insertions, 19 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 7c7bedb83c5a..3cce8f2bb2e1 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -234,17 +234,21 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
234#endif 234#endif
235 235
236#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) 236#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
237/*
238 * To workaround broken NUMA config. Read the comment in
239 * srat_detect_node().
240 */
237static int __cpuinit nearby_node(int apicid) 241static int __cpuinit nearby_node(int apicid)
238{ 242{
239 int i, node; 243 int i, node;
240 244
241 for (i = apicid - 1; i >= 0; i--) { 245 for (i = apicid - 1; i >= 0; i--) {
242 node = apicid_to_node[i]; 246 node = __apicid_to_node[i];
243 if (node != NUMA_NO_NODE && node_online(node)) 247 if (node != NUMA_NO_NODE && node_online(node))
244 return node; 248 return node;
245 } 249 }
246 for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { 250 for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
247 node = apicid_to_node[i]; 251 node = __apicid_to_node[i];
248 if (node != NUMA_NO_NODE && node_online(node)) 252 if (node != NUMA_NO_NODE && node_online(node))
249 return node; 253 return node;
250 } 254 }
@@ -339,26 +343,35 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
339 int node; 343 int node;
340 unsigned apicid = c->apicid; 344 unsigned apicid = c->apicid;
341 345
342 node = per_cpu(cpu_llc_id, cpu); 346 node = numa_cpu_node(cpu);
347 if (node == NUMA_NO_NODE)
348 node = per_cpu(cpu_llc_id, cpu);
343 349
344 if (apicid_to_node[apicid] != NUMA_NO_NODE)
345 node = apicid_to_node[apicid];
346 if (!node_online(node)) { 350 if (!node_online(node)) {
347 /* Two possibilities here: 351 /*
348 - The CPU is missing memory and no node was created. 352 * Two possibilities here:
349 In that case try picking one from a nearby CPU 353 *
350 - The APIC IDs differ from the HyperTransport node IDs 354 * - The CPU is missing memory and no node was created. In
351 which the K8 northbridge parsing fills in. 355 * that case try picking one from a nearby CPU.
352 Assume they are all increased by a constant offset, 356 *
353 but in the same order as the HT nodeids. 357 * - The APIC IDs differ from the HyperTransport node IDs
354 If that doesn't result in a usable node fall back to the 358 * which the K8 northbridge parsing fills in. Assume
355 path for the previous case. */ 359 * they are all increased by a constant offset, but in
356 360 * the same order as the HT nodeids. If that doesn't
361 * result in a usable node fall back to the path for the
362 * previous case.
363 *
364 * This workaround operates directly on the mapping between
365 * APIC ID and NUMA node, assuming certain relationship
366 * between APIC ID, HT node ID and NUMA topology. As going
367 * through CPU mapping may alter the outcome, directly
368 * access __apicid_to_node[].
369 */
357 int ht_nodeid = c->initial_apicid; 370 int ht_nodeid = c->initial_apicid;
358 371
359 if (ht_nodeid >= 0 && 372 if (ht_nodeid >= 0 &&
360 apicid_to_node[ht_nodeid] != NUMA_NO_NODE) 373 __apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
361 node = apicid_to_node[ht_nodeid]; 374 node = __apicid_to_node[ht_nodeid];
362 /* Pick a nearby node */ 375 /* Pick a nearby node */
363 if (!node_online(node)) 376 if (!node_online(node))
364 node = nearby_node(apicid); 377 node = nearby_node(apicid);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index d16c2c53d6bf..6052004bf4f4 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -279,11 +279,10 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
279#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) 279#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
280 unsigned node; 280 unsigned node;
281 int cpu = smp_processor_id(); 281 int cpu = smp_processor_id();
282 int apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid;
283 282
284 /* Don't do the funky fallback heuristics the AMD version employs 283 /* Don't do the funky fallback heuristics the AMD version employs
285 for now. */ 284 for now. */
286 node = apicid_to_node[apicid]; 285 node = numa_cpu_node(cpu);
287 if (node == NUMA_NO_NODE || !node_online(node)) { 286 if (node == NUMA_NO_NODE || !node_online(node)) {
288 /* reuse the value from init_cpu_to_node() */ 287 /* reuse the value from init_cpu_to_node() */
289 node = cpu_to_node(cpu); 288 node = cpu_to_node(cpu);