diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 7e52f83d3a4b..7249dcf2cbcb 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -471,7 +471,7 @@ static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) | |||
471 | return false; | 471 | return false; |
472 | } | 472 | } |
473 | 473 | ||
474 | static struct sched_domain_topology_level numa_inside_package_topology[] = { | 474 | static struct sched_domain_topology_level x86_numa_in_package_topology[] = { |
475 | #ifdef CONFIG_SCHED_SMT | 475 | #ifdef CONFIG_SCHED_SMT |
476 | { cpu_smt_mask, cpu_smt_flags, SD_INIT_NAME(SMT) }, | 476 | { cpu_smt_mask, cpu_smt_flags, SD_INIT_NAME(SMT) }, |
477 | #endif | 477 | #endif |
@@ -480,22 +480,23 @@ static struct sched_domain_topology_level numa_inside_package_topology[] = { | |||
480 | #endif | 480 | #endif |
481 | { NULL, }, | 481 | { NULL, }, |
482 | }; | 482 | }; |
483 | |||
484 | static struct sched_domain_topology_level x86_topology[] = { | ||
485 | #ifdef CONFIG_SCHED_SMT | ||
486 | { cpu_smt_mask, cpu_smt_flags, SD_INIT_NAME(SMT) }, | ||
487 | #endif | ||
488 | #ifdef CONFIG_SCHED_MC | ||
489 | { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, | ||
490 | #endif | ||
491 | { cpu_cpu_mask, SD_INIT_NAME(DIE) }, | ||
492 | { NULL, }, | ||
493 | }; | ||
494 | |||
483 | /* | 495 | /* |
484 | * set_sched_topology() sets the topology internal to a CPU. The | 496 | * Set if a package/die has multiple NUMA nodes inside. |
485 | * NUMA topologies are layered on top of it to build the full | 497 | * AMD Magny-Cours and Intel Cluster-on-Die have this. |
486 | * system topology. | ||
487 | * | ||
488 | * If NUMA nodes are observed to occur within a CPU package, this | ||
489 | * function should be called. It forces the sched domain code to | ||
490 | * only use the SMT level for the CPU portion of the topology. | ||
491 | * This essentially falls back to relying on NUMA information | ||
492 | * from the SRAT table to describe the entire system topology | ||
493 | * (except for hyperthreads). | ||
494 | */ | 498 | */ |
495 | static void primarily_use_numa_for_topology(void) | 499 | static bool x86_has_numa_in_package; |
496 | { | ||
497 | set_sched_topology(numa_inside_package_topology); | ||
498 | } | ||
499 | 500 | ||
500 | void set_cpu_sibling_map(int cpu) | 501 | void set_cpu_sibling_map(int cpu) |
501 | { | 502 | { |
@@ -558,7 +559,7 @@ void set_cpu_sibling_map(int cpu) | |||
558 | c->booted_cores = cpu_data(i).booted_cores; | 559 | c->booted_cores = cpu_data(i).booted_cores; |
559 | } | 560 | } |
560 | if (match_die(c, o) && !topology_same_node(c, o)) | 561 | if (match_die(c, o) && !topology_same_node(c, o)) |
561 | primarily_use_numa_for_topology(); | 562 | x86_has_numa_in_package = true; |
562 | } | 563 | } |
563 | 564 | ||
564 | threads = cpumask_weight(topology_sibling_cpumask(cpu)); | 565 | threads = cpumask_weight(topology_sibling_cpumask(cpu)); |
@@ -690,7 +691,7 @@ wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip) | |||
690 | * Give the other CPU some time to accept the IPI. | 691 | * Give the other CPU some time to accept the IPI. |
691 | */ | 692 | */ |
692 | udelay(200); | 693 | udelay(200); |
693 | if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { | 694 | if (APIC_INTEGRATED(boot_cpu_apic_version)) { |
694 | maxlvt = lapic_get_maxlvt(); | 695 | maxlvt = lapic_get_maxlvt(); |
695 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ | 696 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
696 | apic_write(APIC_ESR, 0); | 697 | apic_write(APIC_ESR, 0); |
@@ -717,7 +718,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
717 | /* | 718 | /* |
718 | * Be paranoid about clearing APIC errors. | 719 | * Be paranoid about clearing APIC errors. |
719 | */ | 720 | */ |
720 | if (APIC_INTEGRATED(apic_version[phys_apicid])) { | 721 | if (APIC_INTEGRATED(boot_cpu_apic_version)) { |
721 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ | 722 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
722 | apic_write(APIC_ESR, 0); | 723 | apic_write(APIC_ESR, 0); |
723 | apic_read(APIC_ESR); | 724 | apic_read(APIC_ESR); |
@@ -756,7 +757,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
756 | * Determine this based on the APIC version. | 757 | * Determine this based on the APIC version. |
757 | * If we don't have an integrated APIC, don't send the STARTUP IPIs. | 758 | * If we don't have an integrated APIC, don't send the STARTUP IPIs. |
758 | */ | 759 | */ |
759 | if (APIC_INTEGRATED(apic_version[phys_apicid])) | 760 | if (APIC_INTEGRATED(boot_cpu_apic_version)) |
760 | num_starts = 2; | 761 | num_starts = 2; |
761 | else | 762 | else |
762 | num_starts = 0; | 763 | num_starts = 0; |
@@ -993,7 +994,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle) | |||
993 | /* | 994 | /* |
994 | * Be paranoid about clearing APIC errors. | 995 | * Be paranoid about clearing APIC errors. |
995 | */ | 996 | */ |
996 | if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { | 997 | if (APIC_INTEGRATED(boot_cpu_apic_version)) { |
997 | apic_write(APIC_ESR, 0); | 998 | apic_write(APIC_ESR, 0); |
998 | apic_read(APIC_ESR); | 999 | apic_read(APIC_ESR); |
999 | } | 1000 | } |
@@ -1248,7 +1249,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
1248 | /* | 1249 | /* |
1249 | * If we couldn't find a local APIC, then get out of here now! | 1250 | * If we couldn't find a local APIC, then get out of here now! |
1250 | */ | 1251 | */ |
1251 | if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && | 1252 | if (APIC_INTEGRATED(boot_cpu_apic_version) && |
1252 | !boot_cpu_has(X86_FEATURE_APIC)) { | 1253 | !boot_cpu_has(X86_FEATURE_APIC)) { |
1253 | if (!disable_apic) { | 1254 | if (!disable_apic) { |
1254 | pr_err("BIOS bug, local APIC #%d not detected!...\n", | 1255 | pr_err("BIOS bug, local APIC #%d not detected!...\n", |
@@ -1303,6 +1304,16 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1303 | zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL); | 1304 | zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL); |
1304 | zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL); | 1305 | zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL); |
1305 | } | 1306 | } |
1307 | |||
1308 | /* | ||
1309 | * Set 'default' x86 topology, this matches default_topology() in that | ||
1310 | * it has NUMA nodes as a topology level. See also | ||
1311 | * native_smp_cpus_done(). | ||
1312 | * | ||
1313 | * Must be done before set_cpus_sibling_map() is ran. | ||
1314 | */ | ||
1315 | set_sched_topology(x86_topology); | ||
1316 | |||
1306 | set_cpu_sibling_map(0); | 1317 | set_cpu_sibling_map(0); |
1307 | 1318 | ||
1308 | switch (smp_sanity_check(max_cpus)) { | 1319 | switch (smp_sanity_check(max_cpus)) { |
@@ -1322,14 +1333,13 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1322 | break; | 1333 | break; |
1323 | } | 1334 | } |
1324 | 1335 | ||
1325 | default_setup_apic_routing(); | ||
1326 | |||
1327 | if (read_apic_id() != boot_cpu_physical_apicid) { | 1336 | if (read_apic_id() != boot_cpu_physical_apicid) { |
1328 | panic("Boot APIC ID in local APIC unexpected (%d vs %d)", | 1337 | panic("Boot APIC ID in local APIC unexpected (%d vs %d)", |
1329 | read_apic_id(), boot_cpu_physical_apicid); | 1338 | read_apic_id(), boot_cpu_physical_apicid); |
1330 | /* Or can we switch back to PIC here? */ | 1339 | /* Or can we switch back to PIC here? */ |
1331 | } | 1340 | } |
1332 | 1341 | ||
1342 | default_setup_apic_routing(); | ||
1333 | cpu0_logical_apicid = apic_bsp_setup(false); | 1343 | cpu0_logical_apicid = apic_bsp_setup(false); |
1334 | 1344 | ||
1335 | pr_info("CPU%d: ", 0); | 1345 | pr_info("CPU%d: ", 0); |
@@ -1369,6 +1379,9 @@ void __init native_smp_cpus_done(unsigned int max_cpus) | |||
1369 | { | 1379 | { |
1370 | pr_debug("Boot done\n"); | 1380 | pr_debug("Boot done\n"); |
1371 | 1381 | ||
1382 | if (x86_has_numa_in_package) | ||
1383 | set_sched_topology(x86_numa_in_package_topology); | ||
1384 | |||
1372 | nmi_selftest(); | 1385 | nmi_selftest(); |
1373 | impress_friends(); | 1386 | impress_friends(); |
1374 | setup_ioapic_dest(); | 1387 | setup_ioapic_dest(); |