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>
This commit is contained in:

committed by
Thomas Gleixner

parent
f1df280f53
commit
92cb7612ae
@@ -84,8 +84,8 @@ cpumask_t cpu_possible_map;
|
||||
EXPORT_SYMBOL(cpu_possible_map);
|
||||
|
||||
/* Per CPU bogomips and other parameters */
|
||||
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
|
||||
EXPORT_SYMBOL(cpu_data);
|
||||
DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
|
||||
EXPORT_PER_CPU_SYMBOL(cpu_info);
|
||||
|
||||
/* Set when the idlers are all forked */
|
||||
int smp_threads_ready;
|
||||
@@ -138,9 +138,10 @@ static unsigned long __cpuinit setup_trampoline(void)
|
||||
|
||||
static void __cpuinit smp_store_cpu_info(int id)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data + id;
|
||||
struct cpuinfo_x86 *c = &cpu_data(id);
|
||||
|
||||
*c = boot_cpu_data;
|
||||
c->cpu_index = id;
|
||||
identify_cpu(c);
|
||||
print_cpu_info(c);
|
||||
}
|
||||
@@ -237,7 +238,7 @@ void __cpuinit smp_callin(void)
|
||||
/* maps the cpu to the sched domain representing multi-core */
|
||||
cpumask_t cpu_coregroup_map(int cpu)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data + cpu;
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
/*
|
||||
* For perf, we return last level cache shared map.
|
||||
* And for power savings, we return cpu_core_map
|
||||
@@ -254,41 +255,41 @@ static cpumask_t cpu_sibling_setup_map;
|
||||
static inline void set_cpu_sibling_map(int cpu)
|
||||
{
|
||||
int i;
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
|
||||
cpu_set(cpu, cpu_sibling_setup_map);
|
||||
|
||||
if (smp_num_siblings > 1) {
|
||||
for_each_cpu_mask(i, cpu_sibling_setup_map) {
|
||||
if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
|
||||
c[cpu].cpu_core_id == c[i].cpu_core_id) {
|
||||
if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
|
||||
c->cpu_core_id == cpu_data(i).cpu_core_id) {
|
||||
cpu_set(i, per_cpu(cpu_sibling_map, cpu));
|
||||
cpu_set(cpu, per_cpu(cpu_sibling_map, i));
|
||||
cpu_set(i, per_cpu(cpu_core_map, cpu));
|
||||
cpu_set(cpu, per_cpu(cpu_core_map, i));
|
||||
cpu_set(i, c[cpu].llc_shared_map);
|
||||
cpu_set(cpu, c[i].llc_shared_map);
|
||||
cpu_set(i, c->llc_shared_map);
|
||||
cpu_set(cpu, cpu_data(i).llc_shared_map);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
|
||||
}
|
||||
|
||||
cpu_set(cpu, c[cpu].llc_shared_map);
|
||||
cpu_set(cpu, c->llc_shared_map);
|
||||
|
||||
if (current_cpu_data.x86_max_cores == 1) {
|
||||
per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
|
||||
c[cpu].booted_cores = 1;
|
||||
c->booted_cores = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for_each_cpu_mask(i, cpu_sibling_setup_map) {
|
||||
if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
|
||||
per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
|
||||
cpu_set(i, c[cpu].llc_shared_map);
|
||||
cpu_set(cpu, c[i].llc_shared_map);
|
||||
cpu_set(i, c->llc_shared_map);
|
||||
cpu_set(cpu, cpu_data(i).llc_shared_map);
|
||||
}
|
||||
if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
|
||||
if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
|
||||
cpu_set(i, per_cpu(cpu_core_map, cpu));
|
||||
cpu_set(cpu, per_cpu(cpu_core_map, i));
|
||||
/*
|
||||
@@ -300,15 +301,15 @@ static inline void set_cpu_sibling_map(int cpu)
|
||||
* the booted_cores for this new cpu
|
||||
*/
|
||||
if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
|
||||
c[cpu].booted_cores++;
|
||||
c->booted_cores++;
|
||||
/*
|
||||
* increment the core count for all
|
||||
* the other cpus in this package
|
||||
*/
|
||||
if (i != cpu)
|
||||
c[i].booted_cores++;
|
||||
} else if (i != cpu && !c[cpu].booted_cores)
|
||||
c[cpu].booted_cores = c[i].booted_cores;
|
||||
cpu_data(i).booted_cores++;
|
||||
} else if (i != cpu && !c->booted_cores)
|
||||
c->booted_cores = cpu_data(i).booted_cores;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -989,7 +990,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
|
||||
static void remove_siblinginfo(int cpu)
|
||||
{
|
||||
int sibling;
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
|
||||
for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
|
||||
cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
|
||||
@@ -997,15 +998,15 @@ static void remove_siblinginfo(int cpu)
|
||||
* last thread sibling in this cpu core going down
|
||||
*/
|
||||
if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
|
||||
c[sibling].booted_cores--;
|
||||
cpu_data(sibling).booted_cores--;
|
||||
}
|
||||
|
||||
for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
|
||||
cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
|
||||
cpus_clear(per_cpu(cpu_sibling_map, cpu));
|
||||
cpus_clear(per_cpu(cpu_core_map, cpu));
|
||||
c[cpu].phys_proc_id = 0;
|
||||
c[cpu].cpu_core_id = 0;
|
||||
c->phys_proc_id = 0;
|
||||
c->cpu_core_id = 0;
|
||||
cpu_clear(cpu, cpu_sibling_setup_map);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user