diff options
author | Mike Travis <travis@sgi.com> | 2007-10-19 14:35:04 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2007-10-19 14:35:04 -0400 |
commit | 92cb7612aee39642d109b8d935ad265e602c0563 (patch) | |
tree | 307f4183226f52418bd6842b5d970f03524ad1c1 /arch/x86/kernel/smpboot_64.c | |
parent | f1df280f53d7c3ce8613a3b25d1efe009b9860dd (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.c | 45 |
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; | |||
84 | EXPORT_SYMBOL(cpu_possible_map); | 84 | EXPORT_SYMBOL(cpu_possible_map); |
85 | 85 | ||
86 | /* Per CPU bogomips and other parameters */ | 86 | /* Per CPU bogomips and other parameters */ |
87 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; | 87 | DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); |
88 | EXPORT_SYMBOL(cpu_data); | 88 | EXPORT_PER_CPU_SYMBOL(cpu_info); |
89 | 89 | ||
90 | /* Set when the idlers are all forked */ | 90 | /* Set when the idlers are all forked */ |
91 | int smp_threads_ready; | 91 | int smp_threads_ready; |
@@ -138,9 +138,10 @@ static unsigned long __cpuinit setup_trampoline(void) | |||
138 | 138 | ||
139 | static void __cpuinit smp_store_cpu_info(int id) | 139 | static 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 */ |
238 | cpumask_t cpu_coregroup_map(int cpu) | 239 | cpumask_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; | |||
254 | static inline void set_cpu_sibling_map(int cpu) | 255 | static 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) | |||
989 | static void remove_siblinginfo(int cpu) | 990 | static 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 | ||