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.c97
1 files changed, 50 insertions, 47 deletions
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index c5517f332309..09b4ceb832b2 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -66,11 +66,21 @@ int smp_num_siblings = 1;
66#ifdef CONFIG_X86_HT 66#ifdef CONFIG_X86_HT
67EXPORT_SYMBOL(smp_num_siblings); 67EXPORT_SYMBOL(smp_num_siblings);
68#endif 68#endif
69int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ 69
70/* Package ID of each logical CPU */
71int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID};
70EXPORT_SYMBOL(phys_proc_id); 72EXPORT_SYMBOL(phys_proc_id);
71int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ 73
74/* Core ID of each logical CPU */
75int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID};
72EXPORT_SYMBOL(cpu_core_id); 76EXPORT_SYMBOL(cpu_core_id);
73 77
78cpumask_t cpu_sibling_map[NR_CPUS];
79EXPORT_SYMBOL(cpu_sibling_map);
80
81cpumask_t cpu_core_map[NR_CPUS];
82EXPORT_SYMBOL(cpu_core_map);
83
74/* bitmap of online cpus */ 84/* bitmap of online cpus */
75cpumask_t cpu_online_map; 85cpumask_t cpu_online_map;
76EXPORT_SYMBOL(cpu_online_map); 86EXPORT_SYMBOL(cpu_online_map);
@@ -423,6 +433,38 @@ static void __init smp_callin(void)
423 433
424static int cpucount; 434static int cpucount;
425 435
436static inline void
437set_cpu_sibling_map(int cpu)
438{
439 int i;
440
441 if (smp_num_siblings > 1) {
442 for (i = 0; i < NR_CPUS; i++) {
443 if (!cpu_isset(i, cpu_callout_map))
444 continue;
445 if (cpu_core_id[cpu] == cpu_core_id[i]) {
446 cpu_set(i, cpu_sibling_map[cpu]);
447 cpu_set(cpu, cpu_sibling_map[i]);
448 }
449 }
450 } else {
451 cpu_set(cpu, cpu_sibling_map[cpu]);
452 }
453
454 if (current_cpu_data.x86_num_cores > 1) {
455 for (i = 0; i < NR_CPUS; i++) {
456 if (!cpu_isset(i, cpu_callout_map))
457 continue;
458 if (phys_proc_id[cpu] == phys_proc_id[i]) {
459 cpu_set(i, cpu_core_map[cpu]);
460 cpu_set(cpu, cpu_core_map[i]);
461 }
462 }
463 } else {
464 cpu_core_map[cpu] = cpu_sibling_map[cpu];
465 }
466}
467
426/* 468/*
427 * Activate a secondary processor. 469 * Activate a secondary processor.
428 */ 470 */
@@ -450,6 +492,10 @@ static void __init start_secondary(void *unused)
450 */ 492 */
451 local_flush_tlb(); 493 local_flush_tlb();
452 494
495 /* This must be done before setting cpu_online_map */
496 set_cpu_sibling_map(raw_smp_processor_id());
497 wmb();
498
453 /* 499 /*
454 * We need to hold call_lock, so there is no inconsistency 500 * We need to hold call_lock, so there is no inconsistency
455 * between the time smp_call_function() determines number of 501 * between the time smp_call_function() determines number of
@@ -912,13 +958,6 @@ void *xquad_portio;
912EXPORT_SYMBOL(xquad_portio); 958EXPORT_SYMBOL(xquad_portio);
913#endif 959#endif
914 960
915cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
916#ifdef CONFIG_X86_HT
917EXPORT_SYMBOL(cpu_sibling_map);
918#endif
919cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
920EXPORT_SYMBOL(cpu_core_map);
921
922static void __init smp_boot_cpus(unsigned int max_cpus) 961static void __init smp_boot_cpus(unsigned int max_cpus)
923{ 962{
924 int apicid, cpu, bit, kicked; 963 int apicid, cpu, bit, kicked;
@@ -1082,44 +1121,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1082 cpus_clear(cpu_core_map[cpu]); 1121 cpus_clear(cpu_core_map[cpu]);
1083 } 1122 }
1084 1123
1085 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1124 cpu_set(0, cpu_sibling_map[0]);
1086 struct cpuinfo_x86 *c = cpu_data + cpu; 1125 cpu_set(0, cpu_core_map[0]);
1087 int siblings = 0;
1088 int i;
1089 if (!cpu_isset(cpu, cpu_callout_map))
1090 continue;
1091
1092 if (smp_num_siblings > 1) {
1093 for (i = 0; i < NR_CPUS; i++) {
1094 if (!cpu_isset(i, cpu_callout_map))
1095 continue;
1096 if (cpu_core_id[cpu] == cpu_core_id[i]) {
1097 siblings++;
1098 cpu_set(i, cpu_sibling_map[cpu]);
1099 }
1100 }
1101 } else {
1102 siblings++;
1103 cpu_set(cpu, cpu_sibling_map[cpu]);
1104 }
1105
1106 if (siblings != smp_num_siblings) {
1107 printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
1108 smp_num_siblings = siblings;
1109 }
1110
1111 if (c->x86_num_cores > 1) {
1112 for (i = 0; i < NR_CPUS; i++) {
1113 if (!cpu_isset(i, cpu_callout_map))
1114 continue;
1115 if (phys_proc_id[cpu] == phys_proc_id[i]) {
1116 cpu_set(i, cpu_core_map[cpu]);
1117 }
1118 }
1119 } else {
1120 cpu_core_map[cpu] = cpu_sibling_map[cpu];
1121 }
1122 }
1123 1126
1124 smpboot_setup_io_apic(); 1127 smpboot_setup_io_apic();
1125 1128