x86: Reduce Memory Usage for large CPU count systems
Subsystems (5)
cover x86: Reduce Memory Usage for large CPU count systems
Analyzing various data structures when NR_CPU count is raised to 4096 shows the following arrays over 128k. If the maximum number of cpus are not installed (about 99.99% of the time), then a large percentage of this memory is wasted. --
151289856 CALNDATA irq_desc 135530496 RMDATATA irq_cfg 3145728 CALNDATA cpu_data 2101248 BSS irq_lists 2097152 RMDATATA cpu_sibling_map 2097152 RMDATATA cpu_core_map 1575936 BSS irq_2_pin 1050624 BSS irq_timer_state 614400 INITDATA early_node_map 525376 PERCPU per_cpu__kstat 524608 DATA unix_proto 524608 DATA udpv6_prot 524608 DATA udplitev6_prot 524608 DATA udplite_prot 524608 DATA udp_prot 524608 DATA tcpv6_prot 524608 DATA tcp_prot 524608 DATA rawv6_prot 524608 DATA raw_prot 524608 DATA packet_proto 524608 DATA netlink_proto 524288 BSS cpu_devices 524288 BSS boot_pageset 524288 CALNDATA boot_cpu_pda 262144 RMDATATA node_to_cpumask 262144 BSS __log_buf 131072 BSS entries
cpu_sibling_map and cpu_core_map have been taken care of in a prior patch. This patch deals with the cpu_data array of cpuinfo_x86 structs. The model that was used in sparc64 architecture was adopted for x86.
Obviously, the IRQ arrays are of greater importance for size reduction. Any suggestions, or threads I should read are gratefully accecpted... ;-)
Signature · 5 lines
-- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/1 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.
This patch is based on 2.6.23-rc6 with the prior per_cpu patches applied. I can also provide a version based on 2.6.23-rc4-mm1 which has some different changes.
--- arch/i386/kernel/acpi/cstate.c | 4 - arch/i386/kernel/acpi/processor.c | 2 arch/i386/kernel/alternative.c | 6 +- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 4 - arch/i386/kernel/cpu/cpufreq/e_powersaver.c | 2 arch/i386/kernel/cpu/cpufreq/elanfreq.c | 4 - arch/i386/kernel/cpu/cpufreq/longhaul.c | 4 - arch/i386/kernel/cpu/cpufreq/longrun.c | 4 - arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 4 - arch/i386/kernel/cpu/cpufreq/powernow-k6.c | 2 arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 2 arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 2 arch/i386/kernel/cpu/cpufreq/sc520_freq.c | 4 - arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 6 +- arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | 2 arch/i386/kernel/cpu/intel_cacheinfo.c | 8 +-- arch/i386/kernel/cpu/proc.c | 9 ++-- arch/i386/kernel/cpuid.c | 2 arch/i386/kernel/microcode.c | 6 +- arch/i386/kernel/msr.c | 2 arch/i386/kernel/smp.c | 2 arch/i386/kernel/smpboot.c | 45 +++++++++++----------- arch/i386/kernel/tsc.c | 8 +-- arch/i386/lib/delay.c | 2 arch/i386/mach-voyager/voyager_smp.c | 12 ++--- arch/x86_64/kernel/mce.c | 2 arch/x86_64/kernel/mce_amd.c | 4 - arch/x86_64/kernel/setup.c | 18 +++++--- arch/x86_64/kernel/smpboot.c | 44 ++++++++++----------- arch/x86_64/kernel/tsc.c | 4 - arch/x86_64/kernel/vsyscall.c | 2 arch/x86_64/lib/delay.c | 2 drivers/hwmon/coretemp.c | 6 +- drivers/hwmon/hwmon-vid.c | 2 drivers/input/gameport/gameport.c | 2 drivers/video/geode/video_gx.c | 2 include/asm-i386/processor.h | 10 ++-- include/asm-i386/topology.h | 4 - include/asm-x86_64/processor.h | 10 ++-- include/asm-x86_64/topology.h | 4 - 40 files changed, 138 insertions(+), 126 deletions(-)
arch/x86_64/kernel/smpboot.c +22 -22
@@ -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_trastatic 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); }
@@ -239,7 +240,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
@@ -256,41 +257,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));/*
@@ -302,15 +303,15 @@ static inline void set_cpu_sibling_map(i* 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; } } }
@@ -996,7 +997,6 @@ void __init smp_cpus_done(unsigned int mstatic void remove_siblinginfo (int cpu) {int sibling; -struct cpuinfo_x86 *c = cpu_data;for_each_cpu_mask (sibling,per_cpu (cpu_core_map, cpu)) {cpu_clear (cpu,per_cpu (cpu_core_map, sibling));
@@ -1004,15 +1004,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 ; +cpu_data (cpu).phys_proc_id =0 ; +cpu_data (cpu).cpu_core_id =0 ;cpu_clear (cpu, cpu_sibling_setup_map); }
include/asm-x86_64/processor.h +6 -4
@@ -74,6 +74,7 @@ struct cpuinfo_x86 {__u8 booted_cores;/* number of cores as seen by OS */ __u8 phys_proc_id;/* Physical Processor id. */ __u8 cpu_core_id;/* Core id. */ +__u8 cpu_index;/* index into per_cpu list */ #endif }____cacheline_aligned ;
@@ -88,11 +89,12 @@ struct cpuinfo_x86 {#define X86_VENDOR_UNKNOWN 0xff#ifdef CONFIG_SMP -extern struct cpuinfo_x86 cpu_data[]; -#define current_cpu_data cpu_data[smp_processor_id()] +DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); +#define cpu_data (cpu) per_cpu(cpu_info, cpu) +#define current_cpu_data cpu_data(smp_processor_id())#else -#define cpu_data (&boot_cpu_data) -#define current_cpu_data boot_cpu_data +#define cpu_data (cpu) boot_cpu_data +#define current_cpu_data boot_cpu_data#endif extern char ignore_irq13;
arch/i386/kernel/acpi/cstate.c +2 -2
@@ -29,7 +29,7 @@void acpi_processor_power_init_bm_check (struct acpi_processor_flags *flags,unsigned int cpu) { -struct cpuinfo_x86 *c = cpu_data + cpu; +struct cpuinfo_x86 *c = &cpu_data (cpu); flags->bm_check =0 ;if (num_online_cpus () ==1 )
@@ -72,7 +72,7 @@ int acpi_processor_ffh_cstate_probe(unsi struct acpi_processor_cx *cx, struct acpi_power_register *reg) { struct cstate_entry *percpu_entry; -struct cpuinfo_x86 *c = cpu_data + cpu; +struct cpuinfo_x86 *c = &cpu_data (cpu);cpumask_t saved_mask;int retval;
arch/i386/kernel/acpi/processor.c +1 -1
@@ -63,7 +63,7 @@ static void init_intel_pdc(struct acpi_pvoid arch_acpi_processor_init_pdc (struct acpi_processor *pr) {unsigned int cpu = pr->id; -struct cpuinfo_x86 *c = cpu_data + cpu; +struct cpuinfo_x86 *c = &cpu_data (cpu); pr->pdc =NULL ;if (c->x86_vendor ==X86_VENDOR_INTEL )
arch/i386/kernel/alternative.c +3 -3
@@ -335,14 +335,14 @@ void alternatives_smp_switch(int smp)if (smp) {printk (KERN_INFO "SMP alternatives: switching to SMP code\n" );clear_bit (X86_FEATURE_UP , boot_cpu_data.x86_capability); -clear_bit (X86_FEATURE_UP , cpu_data[0 ].x86_capability); +clear_bit (X86_FEATURE_UP ,cpu_data (0 ).x86_capability);list_for_each_entry (mod, &smp_alt_modules, next)alternatives_smp_lock (mod->locks, mod->locks_end, mod->text, mod->text_end); }else {printk (KERN_INFO "SMP alternatives: switching to UP code\n" );set_bit (X86_FEATURE_UP , boot_cpu_data.x86_capability); -set_bit (X86_FEATURE_UP , cpu_data[0 ].x86_capability); +set_bit (X86_FEATURE_UP ,cpu_data (0 ).x86_capability);list_for_each_entry (mod, &smp_alt_modules, next)alternatives_smp_unlock (mod->locks, mod->locks_end, mod->text, mod->text_end);
@@ -410,7 +410,7 @@ void __init alternative_instructions(voiif (1 ==num_possible_cpus ()) {printk (KERN_INFO "SMP alternatives: switching to UP code\n" );set_bit (X86_FEATURE_UP , boot_cpu_data.x86_capability); -set_bit (X86_FEATURE_UP , cpu_data[0 ].x86_capability); +set_bit (X86_FEATURE_UP ,cpu_data (0 ).x86_capability);alternatives_smp_unlock (__smp_locks, __smp_locks_end, _text, _etext); }
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +2 -2
@@ -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(structunsigned 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" );
arch/i386/kernel/cpu/cpufreq/e_powersaver.c +1 -1
@@ -306,7 +306,7 @@ static struct cpufreq_driver eps_driverstatic int __init eps_init (void ) { -struct cpuinfo_x86 *c = cpu_data; +struct cpuinfo_x86 *c = &cpu_data (cpu);/* This driver will work only on Centaur C7 processors with * Enhanced SpeedStep/PowerSaver registers */
arch/i386/kernel/cpu/cpufreq/elanfreq.c +2 -2
@@ -199,7 +199,7 @@ static int elanfreq_target (struct cpufrstatic int elanfreq_cpu_init (struct cpufreq_policy *policy) { -struct cpuinfo_x86 *c = cpu_data; +struct cpuinfo_x86 *c = &cpu_data (cpu);unsigned int i;int result;
@@ -281,7 +281,7 @@ static struct cpufreq_driver elanfreq_drstatic int __init elanfreq_init (void ) { -struct cpuinfo_x86 *c = cpu_data; +struct cpuinfo_x86 *c = &cpu_data (cpu);/* Test if we have the right hardware */ if ((c->x86_vendor != X86_VENDOR_AMD) ||
arch/i386/kernel/cpu/cpufreq/longhaul.c +2 -2
@@ -731,7 +731,7 @@ static int longhaul_setup_southbridge(vostatic 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;
@@ -911,7 +911,7 @@ static struct cpufreq_driver longhaul_drstatic 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 ;
arch/i386/kernel/cpu/cpufreq/longrun.c +2 -2
@@ -172,7 +172,7 @@ static unsigned int __init longrun_deteru32 save_lo, save_hi;u32 eax, ebx, ecx, edx;u32 try_hi; -struct cpuinfo_x86 *c = cpu_data; +struct cpuinfo_x86 *c = &cpu_data (cpu);if (!low_freq || !high_freq)return -EINVAL ;
@@ -298,7 +298,7 @@ static struct cpufreq_driver longrun_dri*/ static int __init longrun_init (void ) { -struct cpuinfo_x86 *c = cpu_data; +struct cpuinfo_x86 *c = &cpu_data (cpu);if (c->x86_vendor !=X86_VENDOR_TRANSMETA || !cpu_has (c,X86_FEATURE_LONGRUN ))
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +2 -2
@@ -195,7 +195,7 @@ static unsigned int cpufreq_p4_get_frequstatic 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;
@@ -280,7 +280,7 @@ static struct cpufreq_driver p4clockmod_static int __init cpufreq_p4_init (void ) { -struct cpuinfo_x86 *c = cpu_data; +struct cpuinfo_x86 *c = &cpu_data (0 );int ret;/*
arch/i386/kernel/cpu/cpufreq/powernow-k6.c +1 -1
@@ -216,7 +216,7 @@ static struct cpufreq_driver powernow_k6*/ 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 )))
arch/i386/kernel/cpu/cpufreq/powernow-k7.c +1 -1
@@ -114,7 +114,7 @@ static int check_fsb(unsigned int fsbspestatic 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 )) {
arch/i386/kernel/cpu/cpufreq/powernow-k8.c +1 -1
@@ -1333,7 +1333,7 @@ static int __cpuinit powernowk8_init(voi }#ifdef CONFIG_SMP - booted_cores = cpu_data[0 ].booted_cores; + booted_cores =cpu_data (0 ).booted_cores;#endif if (supported_cpus ==num_online_cpus ()) {
arch/i386/kernel/cpu/cpufreq/sc520_freq.c +2 -2
@@ -102,7 +102,7 @@ static int sc520_freq_target (struct cpustatic 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 */
@@ -152,7 +152,7 @@ static struct cpufreq_driver sc520_freq_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 */
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +3 -3
@@ -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(unsignestatic 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;
@@ -613,7 +613,7 @@ static struct cpufreq_driver centrino_dr*/ 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 ;
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +1 -1
@@ -228,7 +228,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_processounsigned 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);
arch/i386/kernel/cpu/intel_cacheinfo.c +4 -4
@@ -295,7 +295,7 @@ unsigned int __cpuinit init_intel_cacheiunsigned 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_mstruct _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_m 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);
arch/i386/kernel/cpuid.c +1 -1
@@ -132,7 +132,7 @@ static ssize_t cpuid_read(struct file *fstatic int cpuid_open (struct inode *inode,struct file *file) {unsigned int cpu =iminor (file->f_path.dentry->d_inode); -struct cpuinfo_x86 *c = &(cpu_data)[cpu]; +struct cpuinfo_x86 *c = &cpu_data (cpu);if (cpu >=NR_CPUS || !cpu_online (cpu))return -ENXIO ;/* No such CPU */
arch/i386/kernel/microcode.c +3 -3
@@ -132,7 +132,7 @@ static struct ucode_cpu_info {static void collect_cpu_info (int cpu_num) { -struct cpuinfo_x86 *c = cpu_data + cpu_num; +struct cpuinfo_x86 *c = &cpu_data (cpu_num);struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;unsigned int val[2 ];
@@ -522,7 +522,7 @@ static struct platform_device *microcodestatic int cpu_request_microcode (int cpu) {char name[30 ]; -struct cpuinfo_x86 *c = cpu_data + cpu; +struct cpuinfo_x86 *c = &cpu_data (cpu);const struct firmware *firmware;void *buf;unsigned long size;
@@ -570,7 +570,7 @@ static int cpu_request_microcode(int cpustatic int apply_microcode_check_cpu (int cpu) { -struct cpuinfo_x86 *c = cpu_data + cpu; +struct cpuinfo_x86 *c = &cpu_data (cpu);struct ucode_cpu_info *uci = ucode_cpu_info + cpu;cpumask_t old;unsigned int val[2 ];
arch/i386/kernel/msr.c +1 -1
@@ -114,7 +114,7 @@ static ssize_t msr_write(struct file *fistatic int msr_open (struct inode *inode,struct file *file) {unsigned int cpu =iminor (file->f_path.dentry->d_inode); -struct cpuinfo_x86 *c = &(cpu_data)[cpu]; +struct cpuinfo_x86 *c = &cpu_data (cpu);if (cpu >=NR_CPUS || !cpu_online (cpu))return -ENXIO ;/* No such CPU */
arch/i386/kernel/smp.c +1 -1
@@ -609,7 +609,7 @@ static void stop_this_cpu (void * dummy)*/ cpu_clear (smp_processor_id (), cpu_online_map);disable_local_APIC (); -if (cpu_data[smp_processor_id ()].hlt_works_ok) +if (cpu_data (smp_processor_id ()).hlt_works_ok)for (;;)halt ();for (;;); }
arch/i386/kernel/smpboot.c +23 -22
131 lines not on this page · raw message
arch/i386/kernel/tsc.c +4 -4
@@ -187,8 +187,8 @@ int recalibrate_cpu_khz(void)if (cpu_has_tsc) { cpu_khz =calculate_cpu_khz (); tsc_khz = cpu_khz; - cpu_data[0 ].loops_per_jiffy = -cpufreq_scale (cpu_data[0 ].loops_per_jiffy, +cpu_data (0 ).loops_per_jiffy = +cpufreq_scale (cpu_data (0 ).loops_per_jiffy, cpu_khz_old, cpu_khz);return 0 ; }else
@@ -221,7 +221,7 @@ time_cpufreq_notifier(struct notifier_blreturn 0 ; } ref_freq = freq->old; - loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; + loops_per_jiffy_ref =cpu_data (freq->cpu).loops_per_jiffy; cpu_khz_ref = cpu_khz; }
@@ -229,7 +229,7 @@ time_cpufreq_notifier(struct notifier_bl (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || (val == CPUFREQ_RESUMECHANGE)) {if (!(freq->flags &CPUFREQ_CONST_LOOPS )) - cpu_data[freq->cpu].loops_per_jiffy = +cpu_data (freq->cpu).loops_per_jiffy =cpufreq_scale (loops_per_jiffy_ref, ref_freq, freq->new);
arch/i386/lib/delay.c +1 -1
@@ -82,7 +82,7 @@ inline void __const_udelay(unsigned long __asm__("mull %0" :"=d" (xloops),"=&a" (d0) :"1" (xloops),"0" - (cpu_data[raw_smp_processor_id ()].loops_per_jiffy * (HZ /4 ))); + (cpu_data (raw_smp_processor_id ()).loops_per_jiffy * (HZ /4 )));__delay (++xloops); }
arch/i386/mach-voyager/voyager_smp.c +6 -6
@@ -36,8 +36,8 @@ static unsigned long cpu_irq_affinity[NR/* per CPU data structure (for /proc/cpuinfo et al), visible externally * indexed physically */ -struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; -EXPORT_SYMBOL (cpu_data); +DEFINE_PER_CPU(cpuinfo_x86, cpu_info) __cacheline_aligned; +EXPORT_PER_CPU_SYMBOL (cpu_info);/* physical ID of the CPU used to boot the system */ unsigned char boot_cpu_id;
@@ -430,7 +430,7 @@ find_smp_config(void)void __init smp_store_cpu_info (int id) { -struct cpuinfo_x86 *c=&cpu_data[id]; +struct cpuinfo_x86 *c=&cpu_data (id); *c = boot_cpu_data;
@@ -634,7 +634,7 @@ do_boot_cpu(__u8 cpu) cpu, smp_processor_id()));printk ("CPU%d: " , cpu); -print_cpu_info (&cpu_data[cpu]); +print_cpu_info (&cpu_data (cpu));wmb ();cpu_set (cpu, cpu_callout_map);cpu_set (cpu, cpu_present_map);
@@ -683,7 +683,7 @@ smp_boot_cpus(void)*/ smp_store_cpu_info (boot_cpu_id);printk ("CPU%d: " , boot_cpu_id); -print_cpu_info (&cpu_data[boot_cpu_id]); +print_cpu_info (&cpu_data (boot_cpu_id));if (is_cpu_quad ()) {/* booting on a Quad CPU */
@@ -714,7 +714,7 @@ smp_boot_cpus(void)unsigned long bogosum =0 ;for (i =0 ; i <NR_CPUS ; i++)if (cpu_isset (i, cpu_online_map)) - bogosum += cpu_data[i].loops_per_jiffy; + bogosum +=cpu_data (i).loops_per_jiffy; printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", cpucount+1, bogosum/(500000/HZ),
arch/x86_64/kernel/mce.c +1 -1
@@ -804,7 +804,7 @@ static __cpuinit int mce_create_device(u {int err;int i; -if (!mce_available (&cpu_data[cpu])) +if (!mce_available (&cpu_data (cpu)))return -EIO ;per_cpu (device_mce,cpu).id = cpu;
arch/x86_64/kernel/mce_amd.c +2 -2
@@ -471,11 +471,11 @@ static __cpuinit int threshold_create_basprintf (name,"threshold_bank%i" , bank);#ifdef CONFIG_SMP -if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) {/* symlink */ +if (cpu_data (cpu).cpu_core_id && shared_bank[bank]) {/* symlink */ i =first_cpu (per_cpu (cpu_core_map, cpu));/* first core not up yet */ -if (cpu_data[i].cpu_core_id) +if (cpu_data (i).cpu_core_id) goto out;/* already linked */
arch/x86_64/kernel/setup.c +11 -7
@@ -536,7 +536,7 @@ static void __init amd_detect_cmp(structbut in the same order as the HT nodeids. If that doesn't result in a usable node fall back to the path for the previous case. */ -int ht_nodeid = apicid - (cpu_data[0 ].phys_proc_id << bits); +int ht_nodeid = apicid - (cpu_data (0 ).phys_proc_id << bits);if (ht_nodeid >=0 && apicid_to_node[ht_nodeid] !=NUMA_NO_NODE ) node = apicid_to_node[ht_nodeid];
@@ -826,6 +826,7 @@ void __cpuinit early_identify_cpu(struct#ifdef CONFIG_SMP c->phys_proc_id = (cpuid_ebx (1 ) >>24 ) &0xff ; + c->cpu_index =0 ;#endif }
@@ -932,6 +933,7 @@ void __cpuinit print_cpu_info(struct cpustatic int show_cpuinfo (struct seq_file *m,void *v) {struct cpuinfo_x86 *c = v; +int cpu =0 ;/* * These flag bits must match the definitions in <asm/cpufeature.h>.
@@ -1010,8 +1012,9 @@ static int show_cpuinfo(struct seq_file#ifdef CONFIG_SMP -if (!cpu_online (c-cpu_data)) +if (!cpu_online (c->cpu_index))return 0 ; + cpu = c->cpu_index;#endif seq_printf(m,"processor\t: %u\n"
@@ -1019,7 +1022,7 @@ static int show_cpuinfo(struct seq_file"cpu family\t: %d\n" "model\t\t: %d\n" "model name\t: %s\n" , - (unsigned )(c-cpu_data), + (unsigned )cpu, c->x86_vendor_id[0 ] ? c->x86_vendor_id :"unknown" , c->x86, (int)c->x86_model,
@@ -1031,7 +1034,7 @@ static int show_cpuinfo(struct seq_fileseq_printf (m,"stepping\t: unknown\n" );if (cpu_has (c,X86_FEATURE_TSC )) { -unsigned int freq =cpufreq_quick_get ((unsigned )(c-cpu_data)); +unsigned int freq =cpufreq_quick_get ((unsigned )cpu);if (!freq) freq = cpu_khz; seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
@@ -1044,7 +1047,6 @@ static int show_cpuinfo(struct seq_file#ifdef CONFIG_SMP if (smp_num_siblings * c->x86_max_cores >1 ) { -int cpu = c - cpu_data;seq_printf (m,"physical id\t: %d\n" , c->phys_proc_id);seq_printf (m,"siblings\t: %d\n" ,cpus_weight (per_cpu (cpu_core_map, cpu)));
@@ -1102,12 +1104,14 @@ static int show_cpuinfo(struct seq_filestatic 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); +return cpu_possible (*pos) ? &cpu_data (*pos) :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); }
arch/x86_64/kernel/tsc.c +2 -2
@@ -71,13 +71,13 @@ static int time_cpufreq_notifier(structstruct cpufreq_freqs *freq = data;unsigned long *lpj, dummy; -if (cpu_has (&cpu_data[freq->cpu],X86_FEATURE_CONSTANT_TSC )) +if (cpu_has (&cpu_data (freq->cpu),X86_FEATURE_CONSTANT_TSC ))return 0 ; lpj = &dummy; if (!(freq->flags & CPUFREQ_CONST_LOOPS))#ifdef CONFIG_SMP - lpj = &cpu_data[freq->cpu].loops_per_jiffy; + lpj = &cpu_data (freq->cpu).loops_per_jiffy;#else lpj = &boot_cpu_data.loops_per_jiffy;#endif
arch/x86_64/kernel/vsyscall.c +1 -1
@@ -293,7 +293,7 @@ static void __cpuinit vsyscall_set_cpu(i#ifdef CONFIG_NUMA node =cpu_to_node (cpu);#endif -if (cpu_has (&cpu_data[cpu],X86_FEATURE_RDTSCP )) +if (cpu_has (&cpu_data (cpu),X86_FEATURE_RDTSCP ))write_rdtscp_aux ((node <<12 ) | cpu);/* Store cpu number in limit so that it can be loaded quickly
drivers/hwmon/coretemp.c +3 -3
@@ -152,7 +152,7 @@ static struct coretemp_data *coretemp_upstatic int __devinit coretemp_probe (struct platform_device *pdev) {struct coretemp_data *data; -struct cpuinfo_x86 *c = &(cpu_data)[pdev->id]; +struct cpuinfo_x86 *c = &cpu_data (pdev->id);int err;u32 eax, edx;
@@ -361,7 +361,7 @@ static int __init coretemp_init(void)struct pdev_entry *p, *n;/* quick check if we run Intel */ -if (cpu_data[0 ].x86_vendor !=X86_VENDOR_INTEL ) +if (cpu_data (0 ).x86_vendor !=X86_VENDOR_INTEL ) goto exit; err =platform_driver_register (&coretemp_driver);
@@ -369,7 +369,7 @@ static int __init coretemp_init(void) goto exit;for_each_online_cpu (i) { -struct cpuinfo_x86 *c = &(cpu_data)[i]; +struct cpuinfo_x86 *c = &cpu_data (i);/* check if family 6, models e, f */ if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
drivers/hwmon/hwmon-vid.c +1 -1
@@ -200,7 +200,7 @@ static u8 find_vrm(u8 eff_family, u8 effu8 vid_which_vrm (void ) { -struct cpuinfo_x86 *c = cpu_data; +struct cpuinfo_x86 *c = &cpu_data (0 );u32 eax;u8 eff_family, eff_model, eff_stepping, vrm_ret;
drivers/input/gameport/gameport.c +1 -1
@@ -136,7 +136,7 @@ static int gameport_measure_speed(struct }gameport_close (gameport); -return (cpu_data[raw_smp_processor_id ()].loops_per_jiffy * (unsigned long )HZ / (1000 /50 )) / (tx <1 ?1 : tx); +return (cpu_data (raw_smp_processor_id ()).loops_per_jiffy * (unsigned long )HZ / (1000 /50 )) / (tx <1 ?1 : tx);#else
drivers/video/geode/video_gx.c +1 -1
@@ -127,7 +127,7 @@ static void gx_set_dclk_frequency(structint timeout =1000 ;/* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */ -if (cpu_data->x86_mask ==1 ) { +if (cpu_data (0 ).x86_mask ==1 ) { pll_table = gx_pll_table_14MHz; pll_table_len =ARRAY_SIZE (gx_pll_table_14MHz); }else {
include/asm-i386/processor.h +6 -4
@@ -79,6 +79,7 @@ struct cpuinfo_x86 {unsigned char booted_cores;/* number of cores as seen by OS */ __u8 phys_proc_id;/* Physical processor id. */ __u8 cpu_core_id;/* Core id */ +__u8 cpu_index;/* index into per_cpu list */ #endif } __attribute__((__aligned__(SMP_CACHE_BYTES)));
@@ -103,11 +104,12 @@ extern struct tss_struct doublefault_tss DECLARE_PER_CPU(struct tss_struct, init_tss);#ifdef CONFIG_SMP -extern struct cpuinfo_x86 cpu_data[]; -#define current_cpu_data cpu_data[smp_processor_id()] +DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); +#define cpu_data (cpu) per_cpu(cpu_info, cpu) +#define current_cpu_data cpu_data(smp_processor_id())#else -#define cpu_data (&boot_cpu_data) -#define current_cpu_data boot_cpu_data +#define cpu_data (cpu) boot_cpu_data +#define current_cpu_data boot_cpu_data#endif /*
include/asm-i386/topology.h +2 -2
@@ -28,8 +28,8 @@#define _ASM_I386_TOPOLOGY_H#ifdef CONFIG_X86_HT -#define topology_physical_package_id (cpu) (cpu_data[cpu].phys_proc_id) -#define topology_core_id (cpu) (cpu_data[cpu].cpu_core_id) +#define topology_physical_package_id (cpu) (cpu_data(cpu).phys_proc_id) +#define topology_core_id (cpu) (cpu_data(cpu).cpu_core_id)#define topology_core_siblings (cpu) (per_cpu(cpu_core_map, cpu))#define topology_thread_siblings (cpu) (per_cpu(cpu_sibling_map, cpu))#endif
include/asm-x86_64/topology.h +2 -2
@@ -56,8 +56,8 @@ extern int __node_distance(int, int);#endif #ifdef CONFIG_SMP -#define topology_physical_package_id (cpu) (cpu_data[cpu].phys_proc_id) -#define topology_core_id (cpu) (cpu_data[cpu].cpu_core_id) +#define topology_physical_package_id (cpu) (cpu_data(cpu).phys_proc_id) +#define topology_core_id (cpu) (cpu_data(cpu).cpu_core_id)#define topology_core_siblings (cpu) (per_cpu(cpu_core_map, cpu))#define topology_thread_siblings (cpu) (per_cpu(cpu_sibling_map, cpu))#define mc_capable () (boot_cpu_data.x86_max_cores > 1)
arch/x86_64/lib/delay.c +1 -1
@@ -40,7 +40,7 @@ EXPORT_SYMBOL(__delay);inline void __const_udelay (unsigned long xloops) { -__delay (((xloops *HZ * cpu_data[raw_smp_processor_id ()].loops_per_jiffy) >>32 ) +1 ); +__delay (((xloops *HZ *cpu_data (raw_smp_processor_id ()).loops_per_jiffy) >>32 ) +1 ); }EXPORT_SYMBOL (__const_udelay);
arch/i386/kernel/cpu/proc.c +6 -3
@@ -85,12 +85,13 @@ static int show_cpuinfo(struct seq_file/* 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,13 @@ static int show_cpuinfo(struct seq_filestatic 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); +return cpu_possible (*pos) ? &cpu_data (*pos) :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)
Signature · 5 lines
-- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/1] x86: Convert cpuinfo_x86 array to a per_cpu array
Quoted 5 lines · [email protected] wrote:
This patch is based on 2.6.23-rc6 with the prior
per_cpupatches applied. I can also provide a version based on 2.6.23-rc4-mm1 which has some different changes.
I just noticed that 2.6.23-rc6-mm1 is now available. I will rebase this patch on that version as there are some significant differences.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>