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>
Šī revīzija ir iekļauta:

revīziju iesūtīja
Thomas Gleixner

vecāks
f1df280f53
revīzija
92cb7612ae
@@ -77,7 +77,7 @@ static unsigned int acpi_pstate_strict;
|
||||
|
||||
static int check_est_cpu(unsigned int cpuid)
|
||||
{
|
||||
struct cpuinfo_x86 *cpu = &cpu_data[cpuid];
|
||||
struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
|
||||
|
||||
if (cpu->x86_vendor != X86_VENDOR_INTEL ||
|
||||
!cpu_has(cpu, X86_FEATURE_EST))
|
||||
@@ -560,7 +560,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
unsigned int cpu = policy->cpu;
|
||||
struct acpi_cpufreq_data *data;
|
||||
unsigned int result = 0;
|
||||
struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
|
||||
struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
|
||||
struct acpi_processor_performance *perf;
|
||||
|
||||
dprintk("acpi_cpufreq_cpu_init\n");
|
||||
|
@@ -305,7 +305,7 @@ static struct cpufreq_driver eps_driver = {
|
||||
|
||||
static int __init eps_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
/* This driver will work only on Centaur C7 processors with
|
||||
* Enhanced SpeedStep/PowerSaver registers */
|
||||
|
@@ -199,7 +199,7 @@ static int elanfreq_target (struct cpufreq_policy *policy,
|
||||
|
||||
static int elanfreq_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
unsigned int i;
|
||||
int result;
|
||||
|
||||
@@ -280,7 +280,7 @@ static struct cpufreq_driver elanfreq_driver = {
|
||||
|
||||
static int __init elanfreq_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
/* Test if we have the right hardware */
|
||||
if ((c->x86_vendor != X86_VENDOR_AMD) ||
|
||||
|
@@ -780,7 +780,7 @@ static int longhaul_setup_southbridge(void)
|
||||
|
||||
static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
char *cpuname=NULL;
|
||||
int ret;
|
||||
u32 lo, hi;
|
||||
@@ -959,7 +959,7 @@ static struct cpufreq_driver longhaul_driver = {
|
||||
|
||||
static int __init longhaul_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
|
||||
return -ENODEV;
|
||||
|
@@ -172,7 +172,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
|
||||
u32 save_lo, save_hi;
|
||||
u32 eax, ebx, ecx, edx;
|
||||
u32 try_hi;
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
if (!low_freq || !high_freq)
|
||||
return -EINVAL;
|
||||
@@ -298,7 +298,7 @@ static struct cpufreq_driver longrun_driver = {
|
||||
*/
|
||||
static int __init longrun_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
|
||||
!cpu_has(c, X86_FEATURE_LONGRUN))
|
||||
|
@@ -195,7 +195,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
|
||||
|
||||
static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
|
||||
struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
|
||||
int cpuid = 0;
|
||||
unsigned int i;
|
||||
|
||||
@@ -279,7 +279,7 @@ static struct cpufreq_driver p4clockmod_driver = {
|
||||
|
||||
static int __init cpufreq_p4_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@@ -215,7 +215,7 @@ static struct cpufreq_driver powernow_k6_driver = {
|
||||
*/
|
||||
static int __init powernow_k6_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
|
||||
((c->x86_model != 12) && (c->x86_model != 13)))
|
||||
|
@@ -114,7 +114,7 @@ static int check_fsb(unsigned int fsbspeed)
|
||||
|
||||
static int check_powernow(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
unsigned int maxei, eax, ebx, ecx, edx;
|
||||
|
||||
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) {
|
||||
|
@@ -102,7 +102,7 @@ static int sc520_freq_target (struct cpufreq_policy *policy,
|
||||
|
||||
static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
int result;
|
||||
|
||||
/* capability check */
|
||||
@@ -151,7 +151,7 @@ static struct cpufreq_driver sc520_freq_driver = {
|
||||
|
||||
static int __init sc520_freq_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
int err;
|
||||
|
||||
/* Test if we have the right hardware */
|
||||
|
@@ -230,7 +230,7 @@ static struct cpu_model models[] =
|
||||
|
||||
static int centrino_cpu_init_table(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
|
||||
struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
|
||||
struct cpu_model *model;
|
||||
|
||||
for(model = models; model->cpu_id != NULL; model++)
|
||||
@@ -340,7 +340,7 @@ static unsigned int get_cur_freq(unsigned int cpu)
|
||||
|
||||
static int centrino_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
|
||||
struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
|
||||
unsigned freq;
|
||||
unsigned l, h;
|
||||
int ret;
|
||||
@@ -612,7 +612,7 @@ static struct cpufreq_driver centrino_driver = {
|
||||
*/
|
||||
static int __init centrino_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *cpu = cpu_data;
|
||||
struct cpuinfo_x86 *cpu = &cpu_data(0);
|
||||
|
||||
if (!cpu_has(cpu, X86_FEATURE_EST))
|
||||
return -ENODEV;
|
||||
|
@@ -228,7 +228,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency);
|
||||
|
||||
unsigned int speedstep_detect_processor (void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
u32 ebx, msr_lo, msr_hi;
|
||||
|
||||
dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);
|
||||
|
@@ -295,7 +295,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
|
||||
unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
|
||||
unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
|
||||
#ifdef CONFIG_X86_HT
|
||||
unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
|
||||
unsigned int cpu = c->cpu_index;
|
||||
#endif
|
||||
|
||||
if (c->cpuid_level > 3) {
|
||||
@@ -459,7 +459,7 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
|
||||
struct _cpuid4_info *this_leaf, *sibling_leaf;
|
||||
unsigned long num_threads_sharing;
|
||||
int index_msb, i;
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
|
||||
this_leaf = CPUID4_INFO_IDX(cpu, index);
|
||||
num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
|
||||
@@ -470,8 +470,8 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
|
||||
index_msb = get_count_order(num_threads_sharing);
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
if (c[i].apicid >> index_msb ==
|
||||
c[cpu].apicid >> index_msb) {
|
||||
if (cpu_data(i).apicid >> index_msb ==
|
||||
c->apicid >> index_msb) {
|
||||
cpu_set(i, this_leaf->shared_cpu_map);
|
||||
if (i != cpu && cpuid4_info[i]) {
|
||||
sibling_leaf = CPUID4_INFO_IDX(i, index);
|
||||
|
@@ -85,12 +85,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
/* nothing */
|
||||
};
|
||||
struct cpuinfo_x86 *c = v;
|
||||
int i, n = c - cpu_data;
|
||||
int i, n = 0;
|
||||
int fpu_exception;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (!cpu_online(n))
|
||||
return 0;
|
||||
n = c->cpu_index;
|
||||
#endif
|
||||
seq_printf(m, "processor\t: %d\n"
|
||||
"vendor_id\t: %s\n"
|
||||
@@ -175,11 +176,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
|
||||
static void *c_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
return *pos < NR_CPUS ? cpu_data + *pos : NULL;
|
||||
if (*pos == 0) /* just in case, cpu 0 is not the first */
|
||||
*pos = first_cpu(cpu_possible_map);
|
||||
if ((*pos) < NR_CPUS && cpu_possible(*pos))
|
||||
return &cpu_data(*pos);
|
||||
return NULL;
|
||||
}
|
||||
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
{
|
||||
++*pos;
|
||||
*pos = next_cpu(*pos, cpu_possible_map);
|
||||
return c_start(m, pos);
|
||||
}
|
||||
static void c_stop(struct seq_file *m, void *v)
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user