diff options
Diffstat (limited to 'arch/x86/kernel/smpboot_32.c')
-rw-r--r-- | arch/x86/kernel/smpboot_32.c | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c index be3faac04719..7b8fdfa169dd 100644 --- a/arch/x86/kernel/smpboot_32.c +++ b/arch/x86/kernel/smpboot_32.c | |||
@@ -67,7 +67,7 @@ int smp_num_siblings = 1; | |||
67 | EXPORT_SYMBOL(smp_num_siblings); | 67 | EXPORT_SYMBOL(smp_num_siblings); |
68 | 68 | ||
69 | /* Last level cache ID of each logical CPU */ | 69 | /* Last level cache ID of each logical CPU */ |
70 | int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; | 70 | DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID; |
71 | 71 | ||
72 | /* representing HT siblings of each logical CPU */ | 72 | /* representing HT siblings of each logical CPU */ |
73 | DEFINE_PER_CPU(cpumask_t, cpu_sibling_map); | 73 | DEFINE_PER_CPU(cpumask_t, cpu_sibling_map); |
@@ -89,12 +89,20 @@ EXPORT_SYMBOL(cpu_possible_map); | |||
89 | static cpumask_t smp_commenced_mask; | 89 | static cpumask_t smp_commenced_mask; |
90 | 90 | ||
91 | /* Per CPU bogomips and other parameters */ | 91 | /* Per CPU bogomips and other parameters */ |
92 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; | 92 | DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); |
93 | EXPORT_SYMBOL(cpu_data); | 93 | EXPORT_PER_CPU_SYMBOL(cpu_info); |
94 | 94 | ||
95 | u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = | 95 | /* |
96 | { [0 ... NR_CPUS-1] = 0xff }; | 96 | * The following static array is used during kernel startup |
97 | EXPORT_SYMBOL(x86_cpu_to_apicid); | 97 | * and the x86_cpu_to_apicid_ptr contains the address of the |
98 | * array during this time. Is it zeroed when the per_cpu | ||
99 | * data area is removed. | ||
100 | */ | ||
101 | u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata = | ||
102 | { [0 ... NR_CPUS-1] = BAD_APICID }; | ||
103 | void *x86_cpu_to_apicid_ptr; | ||
104 | DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID; | ||
105 | EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid); | ||
98 | 106 | ||
99 | u8 apicid_2_node[MAX_APICID]; | 107 | u8 apicid_2_node[MAX_APICID]; |
100 | 108 | ||
@@ -150,9 +158,10 @@ void __init smp_alloc_memory(void) | |||
150 | 158 | ||
151 | void __cpuinit smp_store_cpu_info(int id) | 159 | void __cpuinit smp_store_cpu_info(int id) |
152 | { | 160 | { |
153 | struct cpuinfo_x86 *c = cpu_data + id; | 161 | struct cpuinfo_x86 *c = &cpu_data(id); |
154 | 162 | ||
155 | *c = boot_cpu_data; | 163 | *c = boot_cpu_data; |
164 | c->cpu_index = id; | ||
156 | if (id!=0) | 165 | if (id!=0) |
157 | identify_secondary_cpu(c); | 166 | identify_secondary_cpu(c); |
158 | /* | 167 | /* |
@@ -294,7 +303,7 @@ static int cpucount; | |||
294 | /* maps the cpu to the sched domain representing multi-core */ | 303 | /* maps the cpu to the sched domain representing multi-core */ |
295 | cpumask_t cpu_coregroup_map(int cpu) | 304 | cpumask_t cpu_coregroup_map(int cpu) |
296 | { | 305 | { |
297 | struct cpuinfo_x86 *c = cpu_data + cpu; | 306 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
298 | /* | 307 | /* |
299 | * For perf, we return last level cache shared map. | 308 | * For perf, we return last level cache shared map. |
300 | * And for power savings, we return cpu_core_map | 309 | * And for power savings, we return cpu_core_map |
@@ -311,41 +320,41 @@ static cpumask_t cpu_sibling_setup_map; | |||
311 | void __cpuinit set_cpu_sibling_map(int cpu) | 320 | void __cpuinit set_cpu_sibling_map(int cpu) |
312 | { | 321 | { |
313 | int i; | 322 | int i; |
314 | struct cpuinfo_x86 *c = cpu_data; | 323 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
315 | 324 | ||
316 | cpu_set(cpu, cpu_sibling_setup_map); | 325 | cpu_set(cpu, cpu_sibling_setup_map); |
317 | 326 | ||
318 | if (smp_num_siblings > 1) { | 327 | if (smp_num_siblings > 1) { |
319 | for_each_cpu_mask(i, cpu_sibling_setup_map) { | 328 | for_each_cpu_mask(i, cpu_sibling_setup_map) { |
320 | if (c[cpu].phys_proc_id == c[i].phys_proc_id && | 329 | if (c->phys_proc_id == cpu_data(i).phys_proc_id && |
321 | c[cpu].cpu_core_id == c[i].cpu_core_id) { | 330 | c->cpu_core_id == cpu_data(i).cpu_core_id) { |
322 | cpu_set(i, per_cpu(cpu_sibling_map, cpu)); | 331 | cpu_set(i, per_cpu(cpu_sibling_map, cpu)); |
323 | cpu_set(cpu, per_cpu(cpu_sibling_map, i)); | 332 | cpu_set(cpu, per_cpu(cpu_sibling_map, i)); |
324 | cpu_set(i, per_cpu(cpu_core_map, cpu)); | 333 | cpu_set(i, per_cpu(cpu_core_map, cpu)); |
325 | cpu_set(cpu, per_cpu(cpu_core_map, i)); | 334 | cpu_set(cpu, per_cpu(cpu_core_map, i)); |
326 | cpu_set(i, c[cpu].llc_shared_map); | 335 | cpu_set(i, c->llc_shared_map); |
327 | cpu_set(cpu, c[i].llc_shared_map); | 336 | cpu_set(cpu, cpu_data(i).llc_shared_map); |
328 | } | 337 | } |
329 | } | 338 | } |
330 | } else { | 339 | } else { |
331 | cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); | 340 | cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); |
332 | } | 341 | } |
333 | 342 | ||
334 | cpu_set(cpu, c[cpu].llc_shared_map); | 343 | cpu_set(cpu, c->llc_shared_map); |
335 | 344 | ||
336 | if (current_cpu_data.x86_max_cores == 1) { | 345 | if (current_cpu_data.x86_max_cores == 1) { |
337 | per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu); | 346 | per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu); |
338 | c[cpu].booted_cores = 1; | 347 | c->booted_cores = 1; |
339 | return; | 348 | return; |
340 | } | 349 | } |
341 | 350 | ||
342 | for_each_cpu_mask(i, cpu_sibling_setup_map) { | 351 | for_each_cpu_mask(i, cpu_sibling_setup_map) { |
343 | if (cpu_llc_id[cpu] != BAD_APICID && | 352 | if (per_cpu(cpu_llc_id, cpu) != BAD_APICID && |
344 | cpu_llc_id[cpu] == cpu_llc_id[i]) { | 353 | per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) { |
345 | cpu_set(i, c[cpu].llc_shared_map); | 354 | cpu_set(i, c->llc_shared_map); |
346 | cpu_set(cpu, c[i].llc_shared_map); | 355 | cpu_set(cpu, cpu_data(i).llc_shared_map); |
347 | } | 356 | } |
348 | if (c[cpu].phys_proc_id == c[i].phys_proc_id) { | 357 | if (c->phys_proc_id == cpu_data(i).phys_proc_id) { |
349 | cpu_set(i, per_cpu(cpu_core_map, cpu)); | 358 | cpu_set(i, per_cpu(cpu_core_map, cpu)); |
350 | cpu_set(cpu, per_cpu(cpu_core_map, i)); | 359 | cpu_set(cpu, per_cpu(cpu_core_map, i)); |
351 | /* | 360 | /* |
@@ -357,15 +366,15 @@ void __cpuinit set_cpu_sibling_map(int cpu) | |||
357 | * the booted_cores for this new cpu | 366 | * the booted_cores for this new cpu |
358 | */ | 367 | */ |
359 | if (first_cpu(per_cpu(cpu_sibling_map, i)) == i) | 368 | if (first_cpu(per_cpu(cpu_sibling_map, i)) == i) |
360 | c[cpu].booted_cores++; | 369 | c->booted_cores++; |
361 | /* | 370 | /* |
362 | * increment the core count for all | 371 | * increment the core count for all |
363 | * the other cpus in this package | 372 | * the other cpus in this package |
364 | */ | 373 | */ |
365 | if (i != cpu) | 374 | if (i != cpu) |
366 | c[i].booted_cores++; | 375 | cpu_data(i).booted_cores++; |
367 | } else if (i != cpu && !c[cpu].booted_cores) | 376 | } else if (i != cpu && !c->booted_cores) |
368 | c[cpu].booted_cores = c[i].booted_cores; | 377 | c->booted_cores = cpu_data(i).booted_cores; |
369 | } | 378 | } |
370 | } | 379 | } |
371 | } | 380 | } |
@@ -804,7 +813,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
804 | 813 | ||
805 | irq_ctx_init(cpu); | 814 | irq_ctx_init(cpu); |
806 | 815 | ||
807 | x86_cpu_to_apicid[cpu] = apicid; | 816 | per_cpu(x86_cpu_to_apicid, cpu) = apicid; |
808 | /* | 817 | /* |
809 | * This grunge runs the startup process for | 818 | * This grunge runs the startup process for |
810 | * the targeted processor. | 819 | * the targeted processor. |
@@ -844,7 +853,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
844 | /* number CPUs logically, starting from 1 (BSP is 0) */ | 853 | /* number CPUs logically, starting from 1 (BSP is 0) */ |
845 | Dprintk("OK.\n"); | 854 | Dprintk("OK.\n"); |
846 | printk("CPU%d: ", cpu); | 855 | printk("CPU%d: ", cpu); |
847 | print_cpu_info(&cpu_data[cpu]); | 856 | print_cpu_info(&cpu_data(cpu)); |
848 | Dprintk("CPU has booted.\n"); | 857 | Dprintk("CPU has booted.\n"); |
849 | } else { | 858 | } else { |
850 | boot_error= 1; | 859 | boot_error= 1; |
@@ -866,7 +875,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
866 | cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ | 875 | cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ |
867 | cpucount--; | 876 | cpucount--; |
868 | } else { | 877 | } else { |
869 | x86_cpu_to_apicid[cpu] = apicid; | 878 | per_cpu(x86_cpu_to_apicid, cpu) = apicid; |
870 | cpu_set(cpu, cpu_present_map); | 879 | cpu_set(cpu, cpu_present_map); |
871 | } | 880 | } |
872 | 881 | ||
@@ -915,7 +924,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) | |||
915 | struct warm_boot_cpu_info info; | 924 | struct warm_boot_cpu_info info; |
916 | int apicid, ret; | 925 | int apicid, ret; |
917 | 926 | ||
918 | apicid = x86_cpu_to_apicid[cpu]; | 927 | apicid = per_cpu(x86_cpu_to_apicid, cpu); |
919 | if (apicid == BAD_APICID) { | 928 | if (apicid == BAD_APICID) { |
920 | ret = -ENODEV; | 929 | ret = -ENODEV; |
921 | goto exit; | 930 | goto exit; |
@@ -961,11 +970,11 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
961 | */ | 970 | */ |
962 | smp_store_cpu_info(0); /* Final full version of the data */ | 971 | smp_store_cpu_info(0); /* Final full version of the data */ |
963 | printk("CPU%d: ", 0); | 972 | printk("CPU%d: ", 0); |
964 | print_cpu_info(&cpu_data[0]); | 973 | print_cpu_info(&cpu_data(0)); |
965 | 974 | ||
966 | boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); | 975 | boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); |
967 | boot_cpu_logical_apicid = logical_smp_processor_id(); | 976 | boot_cpu_logical_apicid = logical_smp_processor_id(); |
968 | x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; | 977 | per_cpu(x86_cpu_to_apicid, 0) = boot_cpu_physical_apicid; |
969 | 978 | ||
970 | current_thread_info()->cpu = 0; | 979 | current_thread_info()->cpu = 0; |
971 | 980 | ||
@@ -1008,6 +1017,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1008 | printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); | 1017 | printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); |
1009 | smpboot_clear_io_apic_irqs(); | 1018 | smpboot_clear_io_apic_irqs(); |
1010 | phys_cpu_present_map = physid_mask_of_physid(0); | 1019 | phys_cpu_present_map = physid_mask_of_physid(0); |
1020 | map_cpu_to_logical_apicid(); | ||
1011 | cpu_set(0, per_cpu(cpu_sibling_map, 0)); | 1021 | cpu_set(0, per_cpu(cpu_sibling_map, 0)); |
1012 | cpu_set(0, per_cpu(cpu_core_map, 0)); | 1022 | cpu_set(0, per_cpu(cpu_core_map, 0)); |
1013 | return; | 1023 | return; |
@@ -1029,6 +1039,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1029 | } | 1039 | } |
1030 | smpboot_clear_io_apic_irqs(); | 1040 | smpboot_clear_io_apic_irqs(); |
1031 | phys_cpu_present_map = physid_mask_of_physid(0); | 1041 | phys_cpu_present_map = physid_mask_of_physid(0); |
1042 | map_cpu_to_logical_apicid(); | ||
1032 | cpu_set(0, per_cpu(cpu_sibling_map, 0)); | 1043 | cpu_set(0, per_cpu(cpu_sibling_map, 0)); |
1033 | cpu_set(0, per_cpu(cpu_core_map, 0)); | 1044 | cpu_set(0, per_cpu(cpu_core_map, 0)); |
1034 | return; | 1045 | return; |
@@ -1082,7 +1093,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1082 | Dprintk("Before bogomips.\n"); | 1093 | Dprintk("Before bogomips.\n"); |
1083 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 1094 | for (cpu = 0; cpu < NR_CPUS; cpu++) |
1084 | if (cpu_isset(cpu, cpu_callout_map)) | 1095 | if (cpu_isset(cpu, cpu_callout_map)) |
1085 | bogosum += cpu_data[cpu].loops_per_jiffy; | 1096 | bogosum += cpu_data(cpu).loops_per_jiffy; |
1086 | printk(KERN_INFO | 1097 | printk(KERN_INFO |
1087 | "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", | 1098 | "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", |
1088 | cpucount+1, | 1099 | cpucount+1, |
@@ -1152,7 +1163,7 @@ void __init native_smp_prepare_boot_cpu(void) | |||
1152 | void remove_siblinginfo(int cpu) | 1163 | void remove_siblinginfo(int cpu) |
1153 | { | 1164 | { |
1154 | int sibling; | 1165 | int sibling; |
1155 | struct cpuinfo_x86 *c = cpu_data; | 1166 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
1156 | 1167 | ||
1157 | for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) { | 1168 | for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) { |
1158 | cpu_clear(cpu, per_cpu(cpu_core_map, sibling)); | 1169 | cpu_clear(cpu, per_cpu(cpu_core_map, sibling)); |
@@ -1160,15 +1171,15 @@ void remove_siblinginfo(int cpu) | |||
1160 | * last thread sibling in this cpu core going down | 1171 | * last thread sibling in this cpu core going down |
1161 | */ | 1172 | */ |
1162 | if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) | 1173 | if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) |
1163 | c[sibling].booted_cores--; | 1174 | cpu_data(sibling).booted_cores--; |
1164 | } | 1175 | } |
1165 | 1176 | ||
1166 | for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu)) | 1177 | for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu)) |
1167 | cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling)); | 1178 | cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling)); |
1168 | cpus_clear(per_cpu(cpu_sibling_map, cpu)); | 1179 | cpus_clear(per_cpu(cpu_sibling_map, cpu)); |
1169 | cpus_clear(per_cpu(cpu_core_map, cpu)); | 1180 | cpus_clear(per_cpu(cpu_core_map, cpu)); |
1170 | c[cpu].phys_proc_id = 0; | 1181 | c->phys_proc_id = 0; |
1171 | c[cpu].cpu_core_id = 0; | 1182 | c->cpu_core_id = 0; |
1172 | cpu_clear(cpu, cpu_sibling_setup_map); | 1183 | cpu_clear(cpu, cpu_sibling_setup_map); |
1173 | } | 1184 | } |
1174 | 1185 | ||