aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/smpboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/smpboot.c')
-rw-r--r--arch/x86_64/kernel/smpboot.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index e5714090b00..7e2de8925b0 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -58,7 +58,10 @@
58int smp_num_siblings = 1; 58int smp_num_siblings = 1;
59/* Package ID of each logical CPU */ 59/* Package ID of each logical CPU */
60u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; 60u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
61/* Core ID of each logical CPU */
62u8 cpu_core_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
61EXPORT_SYMBOL(phys_proc_id); 63EXPORT_SYMBOL(phys_proc_id);
64EXPORT_SYMBOL(cpu_core_id);
62 65
63/* Bitmask of currently online CPUs */ 66/* Bitmask of currently online CPUs */
64cpumask_t cpu_online_map; 67cpumask_t cpu_online_map;
@@ -71,6 +74,7 @@ static cpumask_t smp_commenced_mask;
71struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; 74struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
72 75
73cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 76cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
77cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
74 78
75/* 79/*
76 * Trampoline 80x86 program as an array. 80 * Trampoline 80x86 program as an array.
@@ -713,6 +717,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
713 io_apic_irqs = 0; 717 io_apic_irqs = 0;
714 cpu_online_map = cpumask_of_cpu(0); 718 cpu_online_map = cpumask_of_cpu(0);
715 cpu_set(0, cpu_sibling_map[0]); 719 cpu_set(0, cpu_sibling_map[0]);
720 cpu_set(0, cpu_core_map[0]);
716 phys_cpu_present_map = physid_mask_of_physid(0); 721 phys_cpu_present_map = physid_mask_of_physid(0);
717 if (APIC_init_uniprocessor()) 722 if (APIC_init_uniprocessor())
718 printk(KERN_NOTICE "Local APIC not detected." 723 printk(KERN_NOTICE "Local APIC not detected."
@@ -740,6 +745,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
740 io_apic_irqs = 0; 745 io_apic_irqs = 0;
741 cpu_online_map = cpumask_of_cpu(0); 746 cpu_online_map = cpumask_of_cpu(0);
742 cpu_set(0, cpu_sibling_map[0]); 747 cpu_set(0, cpu_sibling_map[0]);
748 cpu_set(0, cpu_core_map[0]);
743 phys_cpu_present_map = physid_mask_of_physid(0); 749 phys_cpu_present_map = physid_mask_of_physid(0);
744 disable_apic = 1; 750 disable_apic = 1;
745 goto smp_done; 751 goto smp_done;
@@ -756,6 +762,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
756 io_apic_irqs = 0; 762 io_apic_irqs = 0;
757 cpu_online_map = cpumask_of_cpu(0); 763 cpu_online_map = cpumask_of_cpu(0);
758 cpu_set(0, cpu_sibling_map[0]); 764 cpu_set(0, cpu_sibling_map[0]);
765 cpu_set(0, cpu_core_map[0]);
759 phys_cpu_present_map = physid_mask_of_physid(0); 766 phys_cpu_present_map = physid_mask_of_physid(0);
760 disable_apic = 1; 767 disable_apic = 1;
761 goto smp_done; 768 goto smp_done;
@@ -833,10 +840,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
833 * Construct cpu_sibling_map[], so that we can tell the 840 * Construct cpu_sibling_map[], so that we can tell the
834 * sibling CPU efficiently. 841 * sibling CPU efficiently.
835 */ 842 */
836 for (cpu = 0; cpu < NR_CPUS; cpu++) 843 for (cpu = 0; cpu < NR_CPUS; cpu++) {
837 cpus_clear(cpu_sibling_map[cpu]); 844 cpus_clear(cpu_sibling_map[cpu]);
845 cpus_clear(cpu_core_map[cpu]);
846 }
838 847
839 for (cpu = 0; cpu < NR_CPUS; cpu++) { 848 for (cpu = 0; cpu < NR_CPUS; cpu++) {
849 struct cpuinfo_x86 *c = cpu_data + cpu;
840 int siblings = 0; 850 int siblings = 0;
841 int i; 851 int i;
842 if (!cpu_isset(cpu, cpu_callout_map)) 852 if (!cpu_isset(cpu, cpu_callout_map))
@@ -846,7 +856,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
846 for (i = 0; i < NR_CPUS; i++) { 856 for (i = 0; i < NR_CPUS; i++) {
847 if (!cpu_isset(i, cpu_callout_map)) 857 if (!cpu_isset(i, cpu_callout_map))
848 continue; 858 continue;
849 if (phys_proc_id[cpu] == phys_proc_id[i]) { 859 if (phys_proc_id[cpu] == cpu_core_id[i]) {
850 siblings++; 860 siblings++;
851 cpu_set(i, cpu_sibling_map[cpu]); 861 cpu_set(i, cpu_sibling_map[cpu]);
852 } 862 }
@@ -862,6 +872,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
862 siblings, cpu, smp_num_siblings); 872 siblings, cpu, smp_num_siblings);
863 smp_num_siblings = siblings; 873 smp_num_siblings = siblings;
864 } 874 }
875 if (c->x86_num_cores > 1) {
876 for (i = 0; i < NR_CPUS; i++) {
877 if (!cpu_isset(i, cpu_callout_map))
878 continue;
879 if (phys_proc_id[cpu] == phys_proc_id[i]) {
880 cpu_set(i, cpu_core_map[cpu]);
881 }
882 }
883 } else
884 cpu_core_map[cpu] = cpu_sibling_map[cpu];
865 } 885 }
866 886
867 Dprintk("Boot done.\n"); 887 Dprintk("Boot done.\n");