diff options
Diffstat (limited to 'arch/i386/kernel/smpboot.c')
-rw-r--r-- | arch/i386/kernel/smpboot.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 332ee7a1d1a1..fd36d2f65f88 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -62,6 +62,8 @@ static int __initdata smp_b_stepping; | |||
62 | int smp_num_siblings = 1; | 62 | int smp_num_siblings = 1; |
63 | int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ | 63 | int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ |
64 | EXPORT_SYMBOL(phys_proc_id); | 64 | EXPORT_SYMBOL(phys_proc_id); |
65 | int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ | ||
66 | EXPORT_SYMBOL(cpu_core_id); | ||
65 | 67 | ||
66 | /* bitmap of online cpus */ | 68 | /* bitmap of online cpus */ |
67 | cpumask_t cpu_online_map; | 69 | cpumask_t cpu_online_map; |
@@ -885,6 +887,7 @@ static int boot_cpu_logical_apicid; | |||
885 | void *xquad_portio; | 887 | void *xquad_portio; |
886 | 888 | ||
887 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | 889 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; |
890 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | ||
888 | 891 | ||
889 | static void __init smp_boot_cpus(unsigned int max_cpus) | 892 | static void __init smp_boot_cpus(unsigned int max_cpus) |
890 | { | 893 | { |
@@ -907,6 +910,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
907 | cpus_clear(cpu_sibling_map[0]); | 910 | cpus_clear(cpu_sibling_map[0]); |
908 | cpu_set(0, cpu_sibling_map[0]); | 911 | cpu_set(0, cpu_sibling_map[0]); |
909 | 912 | ||
913 | cpus_clear(cpu_core_map[0]); | ||
914 | cpu_set(0, cpu_core_map[0]); | ||
915 | |||
910 | /* | 916 | /* |
911 | * If we couldn't find an SMP configuration at boot time, | 917 | * If we couldn't find an SMP configuration at boot time, |
912 | * get out of here now! | 918 | * get out of here now! |
@@ -919,6 +925,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
919 | printk(KERN_NOTICE "Local APIC not detected." | 925 | printk(KERN_NOTICE "Local APIC not detected." |
920 | " Using dummy APIC emulation.\n"); | 926 | " Using dummy APIC emulation.\n"); |
921 | map_cpu_to_logical_apicid(); | 927 | map_cpu_to_logical_apicid(); |
928 | cpu_set(0, cpu_sibling_map[0]); | ||
929 | cpu_set(0, cpu_core_map[0]); | ||
922 | return; | 930 | return; |
923 | } | 931 | } |
924 | 932 | ||
@@ -942,6 +950,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
942 | printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); | 950 | printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); |
943 | smpboot_clear_io_apic_irqs(); | 951 | smpboot_clear_io_apic_irqs(); |
944 | phys_cpu_present_map = physid_mask_of_physid(0); | 952 | phys_cpu_present_map = physid_mask_of_physid(0); |
953 | cpu_set(0, cpu_sibling_map[0]); | ||
954 | cpu_set(0, cpu_core_map[0]); | ||
945 | return; | 955 | return; |
946 | } | 956 | } |
947 | 957 | ||
@@ -955,6 +965,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
955 | printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); | 965 | printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); |
956 | smpboot_clear_io_apic_irqs(); | 966 | smpboot_clear_io_apic_irqs(); |
957 | phys_cpu_present_map = physid_mask_of_physid(0); | 967 | phys_cpu_present_map = physid_mask_of_physid(0); |
968 | cpu_set(0, cpu_sibling_map[0]); | ||
969 | cpu_set(0, cpu_core_map[0]); | ||
958 | return; | 970 | return; |
959 | } | 971 | } |
960 | 972 | ||
@@ -1035,10 +1047,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1035 | * construct cpu_sibling_map[], so that we can tell sibling CPUs | 1047 | * construct cpu_sibling_map[], so that we can tell sibling CPUs |
1036 | * efficiently. | 1048 | * efficiently. |
1037 | */ | 1049 | */ |
1038 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 1050 | for (cpu = 0; cpu < NR_CPUS; cpu++) { |
1039 | cpus_clear(cpu_sibling_map[cpu]); | 1051 | cpus_clear(cpu_sibling_map[cpu]); |
1052 | cpus_clear(cpu_core_map[cpu]); | ||
1053 | } | ||
1040 | 1054 | ||
1041 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 1055 | for (cpu = 0; cpu < NR_CPUS; cpu++) { |
1056 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
1042 | int siblings = 0; | 1057 | int siblings = 0; |
1043 | int i; | 1058 | int i; |
1044 | if (!cpu_isset(cpu, cpu_callout_map)) | 1059 | if (!cpu_isset(cpu, cpu_callout_map)) |
@@ -1048,7 +1063,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1048 | for (i = 0; i < NR_CPUS; i++) { | 1063 | for (i = 0; i < NR_CPUS; i++) { |
1049 | if (!cpu_isset(i, cpu_callout_map)) | 1064 | if (!cpu_isset(i, cpu_callout_map)) |
1050 | continue; | 1065 | continue; |
1051 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | 1066 | if (cpu_core_id[cpu] == cpu_core_id[i]) { |
1052 | siblings++; | 1067 | siblings++; |
1053 | cpu_set(i, cpu_sibling_map[cpu]); | 1068 | cpu_set(i, cpu_sibling_map[cpu]); |
1054 | } | 1069 | } |
@@ -1060,6 +1075,18 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1060 | 1075 | ||
1061 | if (siblings != smp_num_siblings) | 1076 | if (siblings != smp_num_siblings) |
1062 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); | 1077 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); |
1078 | |||
1079 | if (c->x86_num_cores > 1) { | ||
1080 | for (i = 0; i < NR_CPUS; i++) { | ||
1081 | if (!cpu_isset(i, cpu_callout_map)) | ||
1082 | continue; | ||
1083 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | ||
1084 | cpu_set(i, cpu_core_map[cpu]); | ||
1085 | } | ||
1086 | } | ||
1087 | } else { | ||
1088 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
1089 | } | ||
1063 | } | 1090 | } |
1064 | 1091 | ||
1065 | if (nmi_watchdog == NMI_LOCAL_APIC) | 1092 | if (nmi_watchdog == NMI_LOCAL_APIC) |