diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c2871d3c71b6..8ed8908cc9f7 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -312,6 +312,26 @@ void __cpuinit smp_store_cpu_info(int id) | |||
| 312 | identify_secondary_cpu(c); | 312 | identify_secondary_cpu(c); |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | static void __cpuinit check_cpu_siblings_on_same_node(int cpu1, int cpu2) | ||
| 316 | { | ||
| 317 | int node1 = early_cpu_to_node(cpu1); | ||
| 318 | int node2 = early_cpu_to_node(cpu2); | ||
| 319 | |||
| 320 | /* | ||
| 321 | * Our CPU scheduler assumes all logical cpus in the same physical cpu | ||
| 322 | * share the same node. But, buggy ACPI or NUMA emulation might assign | ||
| 323 | * them to different node. Fix it. | ||
| 324 | */ | ||
| 325 | if (node1 != node2) { | ||
| 326 | pr_warning("CPU %d in node %d and CPU %d in node %d are in the same physical CPU. forcing same node %d\n", | ||
| 327 | cpu1, node1, cpu2, node2, node2); | ||
| 328 | |||
| 329 | numa_remove_cpu(cpu1); | ||
| 330 | numa_set_node(cpu1, node2); | ||
| 331 | numa_add_cpu(cpu1); | ||
| 332 | } | ||
| 333 | } | ||
| 334 | |||
| 315 | static void __cpuinit link_thread_siblings(int cpu1, int cpu2) | 335 | static void __cpuinit link_thread_siblings(int cpu1, int cpu2) |
| 316 | { | 336 | { |
| 317 | cpumask_set_cpu(cpu1, cpu_sibling_mask(cpu2)); | 337 | cpumask_set_cpu(cpu1, cpu_sibling_mask(cpu2)); |
| @@ -320,6 +340,7 @@ static void __cpuinit link_thread_siblings(int cpu1, int cpu2) | |||
| 320 | cpumask_set_cpu(cpu2, cpu_core_mask(cpu1)); | 340 | cpumask_set_cpu(cpu2, cpu_core_mask(cpu1)); |
| 321 | cpumask_set_cpu(cpu1, cpu_llc_shared_mask(cpu2)); | 341 | cpumask_set_cpu(cpu1, cpu_llc_shared_mask(cpu2)); |
| 322 | cpumask_set_cpu(cpu2, cpu_llc_shared_mask(cpu1)); | 342 | cpumask_set_cpu(cpu2, cpu_llc_shared_mask(cpu1)); |
| 343 | check_cpu_siblings_on_same_node(cpu1, cpu2); | ||
| 323 | } | 344 | } |
| 324 | 345 | ||
| 325 | 346 | ||
| @@ -361,10 +382,12 @@ void __cpuinit set_cpu_sibling_map(int cpu) | |||
| 361 | per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) { | 382 | per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) { |
| 362 | cpumask_set_cpu(i, cpu_llc_shared_mask(cpu)); | 383 | cpumask_set_cpu(i, cpu_llc_shared_mask(cpu)); |
| 363 | cpumask_set_cpu(cpu, cpu_llc_shared_mask(i)); | 384 | cpumask_set_cpu(cpu, cpu_llc_shared_mask(i)); |
| 385 | check_cpu_siblings_on_same_node(cpu, i); | ||
| 364 | } | 386 | } |
| 365 | if (c->phys_proc_id == cpu_data(i).phys_proc_id) { | 387 | if (c->phys_proc_id == cpu_data(i).phys_proc_id) { |
| 366 | cpumask_set_cpu(i, cpu_core_mask(cpu)); | 388 | cpumask_set_cpu(i, cpu_core_mask(cpu)); |
| 367 | cpumask_set_cpu(cpu, cpu_core_mask(i)); | 389 | cpumask_set_cpu(cpu, cpu_core_mask(i)); |
| 390 | check_cpu_siblings_on_same_node(cpu, i); | ||
| 368 | /* | 391 | /* |
| 369 | * Does this new cpu bringup a new core? | 392 | * Does this new cpu bringup a new core? |
| 370 | */ | 393 | */ |
