aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/smpboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/smpboot.c')
-rw-r--r--arch/i386/kernel/smpboot.c31
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;
62int smp_num_siblings = 1; 62int smp_num_siblings = 1;
63int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ 63int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
64EXPORT_SYMBOL(phys_proc_id); 64EXPORT_SYMBOL(phys_proc_id);
65int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
66EXPORT_SYMBOL(cpu_core_id);
65 67
66/* bitmap of online cpus */ 68/* bitmap of online cpus */
67cpumask_t cpu_online_map; 69cpumask_t cpu_online_map;
@@ -885,6 +887,7 @@ static int boot_cpu_logical_apicid;
885void *xquad_portio; 887void *xquad_portio;
886 888
887cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 889cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
890cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
888 891
889static void __init smp_boot_cpus(unsigned int max_cpus) 892static 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)