aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot_64.c
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2007-10-19 14:35:04 -0400
committerThomas Gleixner <tglx@linutronix.de>2007-10-19 14:35:04 -0400
commit92cb7612aee39642d109b8d935ad265e602c0563 (patch)
tree307f4183226f52418bd6842b5d970f03524ad1c1 /arch/x86/kernel/smpboot_64.c
parentf1df280f53d7c3ce8613a3b25d1efe009b9860dd (diff)
x86: convert cpuinfo_x86 array to a per_cpu array
cpu_data is currently an array defined using NR_CPUS. This means that we overallocate since we will rarely really use maximum configured cpus. When NR_CPU count is raised to 4096 the size of cpu_data becomes 3,145,728 bytes. These changes were adopted from the sparc64 (and ia64) code. An additional field was added to cpuinfo_x86 to be a non-ambiguous cpu index. This corresponds to the index into a cpumask_t as well as the per_cpu index. It's used in various places like show_cpuinfo(). cpu_data is defined to be the boot_cpu_data structure for the NON-SMP case. Signed-off-by: Mike Travis <travis@sgi.com> Acked-by: Christoph Lameter <clameter@sgi.com> Cc: Andi Kleen <ak@suse.de> Cc: James Bottomley <James.Bottomley@steeleye.com> Cc: Dmitry Torokhov <dtor@mail.ru> Cc: "Antonino A. Daplas" <adaplas@pol.net> Cc: Mark M. Hoffman <mhoffman@lightlink.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/smpboot_64.c')
-rw-r--r--arch/x86/kernel/smpboot_64.c45
1 files changed, 23 insertions, 22 deletions
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index 7c8f58643186..fd1fff6a35a2 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -84,8 +84,8 @@ cpumask_t cpu_possible_map;
84EXPORT_SYMBOL(cpu_possible_map); 84EXPORT_SYMBOL(cpu_possible_map);
85 85
86/* Per CPU bogomips and other parameters */ 86/* Per CPU bogomips and other parameters */
87struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; 87DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
88EXPORT_SYMBOL(cpu_data); 88EXPORT_PER_CPU_SYMBOL(cpu_info);
89 89
90/* Set when the idlers are all forked */ 90/* Set when the idlers are all forked */
91int smp_threads_ready; 91int smp_threads_ready;
@@ -138,9 +138,10 @@ static unsigned long __cpuinit setup_trampoline(void)
138 138
139static void __cpuinit smp_store_cpu_info(int id) 139static void __cpuinit smp_store_cpu_info(int id)
140{ 140{
141 struct cpuinfo_x86 *c = cpu_data + id; 141 struct cpuinfo_x86 *c = &cpu_data(id);
142 142
143 *c = boot_cpu_data; 143 *c = boot_cpu_data;
144 c->cpu_index = id;
144 identify_cpu(c); 145 identify_cpu(c);
145 print_cpu_info(c); 146 print_cpu_info(c);
146} 147}
@@ -237,7 +238,7 @@ void __cpuinit smp_callin(void)
237/* maps the cpu to the sched domain representing multi-core */ 238/* maps the cpu to the sched domain representing multi-core */
238cpumask_t cpu_coregroup_map(int cpu) 239cpumask_t cpu_coregroup_map(int cpu)
239{ 240{
240 struct cpuinfo_x86 *c = cpu_data + cpu; 241 struct cpuinfo_x86 *c = &cpu_data(cpu);
241 /* 242 /*
242 * For perf, we return last level cache shared map. 243 * For perf, we return last level cache shared map.
243 * And for power savings, we return cpu_core_map 244 * And for power savings, we return cpu_core_map
@@ -254,41 +255,41 @@ static cpumask_t cpu_sibling_setup_map;
254static inline void set_cpu_sibling_map(int cpu) 255static inline void set_cpu_sibling_map(int cpu)
255{ 256{
256 int i; 257 int i;
257 struct cpuinfo_x86 *c = cpu_data; 258 struct cpuinfo_x86 *c = &cpu_data(cpu);
258 259
259 cpu_set(cpu, cpu_sibling_setup_map); 260 cpu_set(cpu, cpu_sibling_setup_map);
260 261
261 if (smp_num_siblings > 1) { 262 if (smp_num_siblings > 1) {
262 for_each_cpu_mask(i, cpu_sibling_setup_map) { 263 for_each_cpu_mask(i, cpu_sibling_setup_map) {
263 if (c[cpu].phys_proc_id == c[i].phys_proc_id && 264 if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
264 c[cpu].cpu_core_id == c[i].cpu_core_id) { 265 c->cpu_core_id == cpu_data(i).cpu_core_id) {
265 cpu_set(i, per_cpu(cpu_sibling_map, cpu)); 266 cpu_set(i, per_cpu(cpu_sibling_map, cpu));
266 cpu_set(cpu, per_cpu(cpu_sibling_map, i)); 267 cpu_set(cpu, per_cpu(cpu_sibling_map, i));
267 cpu_set(i, per_cpu(cpu_core_map, cpu)); 268 cpu_set(i, per_cpu(cpu_core_map, cpu));
268 cpu_set(cpu, per_cpu(cpu_core_map, i)); 269 cpu_set(cpu, per_cpu(cpu_core_map, i));
269 cpu_set(i, c[cpu].llc_shared_map); 270 cpu_set(i, c->llc_shared_map);
270 cpu_set(cpu, c[i].llc_shared_map); 271 cpu_set(cpu, cpu_data(i).llc_shared_map);
271 } 272 }
272 } 273 }
273 } else { 274 } else {
274 cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); 275 cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
275 } 276 }
276 277
277 cpu_set(cpu, c[cpu].llc_shared_map); 278 cpu_set(cpu, c->llc_shared_map);
278 279
279 if (current_cpu_data.x86_max_cores == 1) { 280 if (current_cpu_data.x86_max_cores == 1) {
280 per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu); 281 per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
281 c[cpu].booted_cores = 1; 282 c->booted_cores = 1;
282 return; 283 return;
283 } 284 }
284 285
285 for_each_cpu_mask(i, cpu_sibling_setup_map) { 286 for_each_cpu_mask(i, cpu_sibling_setup_map) {
286 if (per_cpu(cpu_llc_id, cpu) != BAD_APICID && 287 if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
287 per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) { 288 per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
288 cpu_set(i, c[cpu].llc_shared_map); 289 cpu_set(i, c->llc_shared_map);
289 cpu_set(cpu, c[i].llc_shared_map); 290 cpu_set(cpu, cpu_data(i).llc_shared_map);
290 } 291 }
291 if (c[cpu].phys_proc_id == c[i].phys_proc_id) { 292 if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
292 cpu_set(i, per_cpu(cpu_core_map, cpu)); 293 cpu_set(i, per_cpu(cpu_core_map, cpu));
293 cpu_set(cpu, per_cpu(cpu_core_map, i)); 294 cpu_set(cpu, per_cpu(cpu_core_map, i));
294 /* 295 /*
@@ -300,15 +301,15 @@ static inline void set_cpu_sibling_map(int cpu)
300 * the booted_cores for this new cpu 301 * the booted_cores for this new cpu
301 */ 302 */
302 if (first_cpu(per_cpu(cpu_sibling_map, i)) == i) 303 if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
303 c[cpu].booted_cores++; 304 c->booted_cores++;
304 /* 305 /*
305 * increment the core count for all 306 * increment the core count for all
306 * the other cpus in this package 307 * the other cpus in this package
307 */ 308 */
308 if (i != cpu) 309 if (i != cpu)
309 c[i].booted_cores++; 310 cpu_data(i).booted_cores++;
310 } else if (i != cpu && !c[cpu].booted_cores) 311 } else if (i != cpu && !c->booted_cores)
311 c[cpu].booted_cores = c[i].booted_cores; 312 c->booted_cores = cpu_data(i).booted_cores;
312 } 313 }
313 } 314 }
314} 315}
@@ -989,7 +990,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
989static void remove_siblinginfo(int cpu) 990static void remove_siblinginfo(int cpu)
990{ 991{
991 int sibling; 992 int sibling;
992 struct cpuinfo_x86 *c = cpu_data; 993 struct cpuinfo_x86 *c = &cpu_data(cpu);
993 994
994 for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) { 995 for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
995 cpu_clear(cpu, per_cpu(cpu_core_map, sibling)); 996 cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -997,15 +998,15 @@ static void remove_siblinginfo(int cpu)
997 * last thread sibling in this cpu core going down 998 * last thread sibling in this cpu core going down
998 */ 999 */
999 if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) 1000 if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
1000 c[sibling].booted_cores--; 1001 cpu_data(sibling).booted_cores--;
1001 } 1002 }
1002 1003
1003 for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu)) 1004 for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
1004 cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling)); 1005 cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
1005 cpus_clear(per_cpu(cpu_sibling_map, cpu)); 1006 cpus_clear(per_cpu(cpu_sibling_map, cpu));
1006 cpus_clear(per_cpu(cpu_core_map, cpu)); 1007 cpus_clear(per_cpu(cpu_core_map, cpu));
1007 c[cpu].phys_proc_id = 0; 1008 c->phys_proc_id = 0;
1008 c[cpu].cpu_core_id = 0; 1009 c->cpu_core_id = 0;
1009 cpu_clear(cpu, cpu_sibling_setup_map); 1010 cpu_clear(cpu, cpu_sibling_setup_map);
1010} 1011}
1011 1012