x86 SMP: enables core-pair topology detection for AMD CPUs
cover x86 SMP: enables core-pair topology detection for AMD CPUs
Hi,
The following two patches enable core-pair topology detection for AMD CPUs. The main idea is to record compute unit information into cpuinfo_x86 and use it when building sibling map. The sibling map will be used by Xen credit scheduler to coordinate VCPU scheduling in a fashion similar to SMT. This code is very similar to upstream Linux kernel.
Regarding the performance improvement, I saw ~8% improvement running kernel compilation on Dom0 with this patch. Anrea Przywara ran a POVRay benchmark using this patch and he saw ~5% improvement. No perf degradation was seen so far.
Please review.
Thanks,
-Wei
Quoted 9 lines
Quoted 1 line
Quoted 1 line · Wei Huang
Hi,
The following two patches enable core-pair topology detection for AMD CPUs. The main idea is to record compute unit information into
cpuinfo_x86and use it when building sibling map. The sibling map will be used by Xen credit scheduler to coordinate VCPU scheduling in a fashion similar to SMT. This code is very similar to upstream Linux kernel.
Quoted 6 lines
Regarding the performance improvement, I saw ~8% improvement running kernel compilation on Dom0 with this patch. Anrea Przywara ran a POVRay benchmark using this patch and he saw ~5% improvement. No perf degradation was seen so far.
Please review.
Apart from some indentation issues these look fine to me.
Jan
Quoted 2 lines
Thanks,
-Wei
Thanks, Jan and George. I attach the latest version which fixes the indentation issues.
-Wei
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 1 line
Quoted 1 line · Wei Huang
Hi,
The following two patches enable core-pair topology detection for AMD CPUs. The main idea is to record compute unit information into
cpuinfo_x86and use it when building sibling map. The sibling map will be used by Xen credit scheduler to coordinate VCPU scheduling in a fashion similar to SMT. This code is very similar to upstream Linux kernel.Regarding the performance improvement, I saw ~8% improvement running kernel compilation on Dom0 with this patch. Anrea Przywara ran a POVRay benchmark using this patch and he saw ~5% improvement. No perf degradation was seen so far.
Quoted 10 lines
Quoted 1 line
Please review.
Apart from some indentation issues these look fine to me.
Jan
Quoted 2 lines
Thanks,
-Wei
# HG changeset patch
# User Wei Huang <[email protected]>
# Date 1309193579 18000
# Node ID e6c4ff6fcb9fcbf1899463e5ec6c425bcbd683e3
# Parent d3027374a8c0d548c6ff468c4d747300e858904b
SMP: consolidate cpu_core_id and phys_proc_id into cpuinfo_x86 struct
This patch moves cpu_core_id and phys_proc_id into cpuinfo_x86 structure. This is similar to upstream Linux kernel's approach.
xen/arch/x86/cpu/amd.c +3 -3
@@ -446,11 +446,11 @@while ((1 << bits) < c->x86_max_cores) bits++; } - cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 <<bits)-1 ); - phys_proc_id[cpu] >>= bits; + c->cpu_core_id = c->phys_proc_id & ((1 <<bits)-1 ); + c->phys_proc_id >>= bits;if (opt_cpu_info)printk ("CPU %d(%d) -> Core %d\n" , - cpu, c->x86_max_cores, cpu_core_id[cpu]); + cpu, c->x86_max_cores, c->cpu_core_id); }#endif
xen/arch/x86/cpu/common.c +11 -11
@@ -271,7 +271,7 @@early_intel_workaround (c);#ifdef CONFIG_X86_HT - phys_proc_id[smp_processor_id ()] = (cpuid_ebx (1 ) >>24 ) &0xff ; + c->phys_proc_id = (cpuid_ebx (1 ) >>24 ) &0xff ;#endif }
@@ -316,6 +316,8 @@ c->x86_max_cores =1 ; c->x86_num_siblings =1 ; c->x86_clflush_size =0 ; + c->phys_proc_id =BAD_APICID ; + c->cpu_core_id =BAD_APICID ;memset (&c->x86_capability,0 ,sizeof c->x86_capability);generic_identify (c);
@@ -453,7 +455,6 @@unsigned int ht_mask_width, core_plus_mask_width;unsigned int core_select_mask, core_level_siblings;unsigned int initial_apicid; -int cpu =smp_processor_id ();if ( c->cpuid_level <0xb )return ;
@@ -488,9 +489,9 @@ core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width; - cpu_core_id[cpu] =phys_pkg_id (initial_apicid, ht_mask_width) + c->cpu_core_id =phys_pkg_id (initial_apicid, ht_mask_width) & core_select_mask; - phys_proc_id[cpu] =phys_pkg_id (initial_apicid, core_plus_mask_width); + c->phys_proc_id =phys_pkg_id (initial_apicid, core_plus_mask_width); c->apicid =phys_pkg_id (initial_apicid,0 ); c->x86_max_cores = (core_level_siblings / c->x86_num_siblings);
@@ -498,10 +499,10 @@if ( opt_cpu_info ) {printk ("CPU: Physical Processor ID: %d\n" , - phys_proc_id[cpu]); + c->phys_proc_id);if ( c->x86_max_cores >1 )printk ("CPU: Processor Core ID: %d\n" , - cpu_core_id[cpu]); + c->cpu_core_id); } }
@@ -510,7 +511,6 @@ {u32 eax, ebx, ecx, edx;int index_msb, core_bits; -int cpu =smp_processor_id ();cpuid (1 , &eax, &ebx, &ecx, &edx);
@@ -533,11 +533,11 @@ } index_msb =get_count_order (c->x86_num_siblings); - phys_proc_id[cpu] =phys_pkg_id ((ebx >>24 ) &0xFF , index_msb); + c->phys_proc_id =phys_pkg_id ((ebx >>24 ) &0xFF , index_msb);if (opt_cpu_info)printk ("CPU: Physical Processor ID: %d\n" , - phys_proc_id[cpu]); + c->phys_proc_id); c->x86_num_siblings = c->x86_num_siblings / c->x86_max_cores;
@@ -545,12 +545,12 @@ core_bits =get_count_order (c->x86_max_cores); - cpu_core_id[cpu] =phys_pkg_id ((ebx >>24 ) &0xFF , index_msb) & + c->cpu_core_id =phys_pkg_id ((ebx >>24 ) &0xFF , index_msb) & ((1 << core_bits) -1 );if (opt_cpu_info && c->x86_max_cores >1 )printk ("CPU: Processor Core ID: %d\n" , - cpu_core_id[cpu]); + c->cpu_core_id); } }#endif
xen/arch/x86/cpu/mcheck/mce.c +2 -2
@@ -1046,9 +1046,9 @@if (nthreads !=NULL ) *nthreads =1 ; }else { - *chipid = phys_proc_id[cpu]; + *chipid = c->phys_proc_id;if (c->x86_max_cores >1 ) - *coreid = cpu_core_id[cpu]; + *coreid = c->cpu_core_id;else *coreid =0 ; *threadid = c->apicid & ((1 << (c->x86_num_siblings -1 )) -1 );
xen/arch/x86/smpboot.c +5 -11
@@ -49,12 +49,6 @@#define setup_trampoline () (bootsym_phys(trampoline_realmode_entry)) -/* Package ID of each logical CPU */ -int phys_proc_id[NR_CPUS ]__read_mostly = {[0 ...NR_CPUS -1 ] =BAD_APICID }; - -/* Core ID of each logical CPU */ -int cpu_core_id[NR_CPUS ]__read_mostly = {[0 ...NR_CPUS -1 ] =BAD_APICID }; -/* representing HT siblings of each logical CPU */ DEFINE_PER_CPU_READ_MOSTLY (cpumask_t, cpu_sibling_map);/* representing HT and core siblings of each logical CPU */
@@ -247,8 +241,8 @@ { for_each_cpu_mask ( i, cpu_sibling_setup_map ) { -if ( (phys_proc_id[cpu] == phys_proc_id[i]) && - (cpu_core_id[cpu] == cpu_core_id[i]) ) +if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) && + (c[cpu].cpu_core_id == c[i].cpu_core_id) ) {cpu_set (i,per_cpu (cpu_sibling_map, cpu));cpu_set (cpu,per_cpu (cpu_sibling_map, i));
@@ -271,7 +265,7 @@ for_each_cpu_mask ( i, cpu_sibling_setup_map ) { -if ( phys_proc_id[cpu] == phys_proc_id[i] ) +if ( c[cpu].phys_proc_id == c[i].phys_proc_id ) {cpu_set (i,per_cpu (cpu_core_map, cpu));cpu_set (cpu,per_cpu (cpu_core_map, i));
@@ -832,8 +826,8 @@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)); - phys_proc_id[cpu] =BAD_APICID ; - cpu_core_id[cpu] =BAD_APICID ; + c[cpu].phys_proc_id =BAD_APICID ; + c[cpu].cpu_core_id =BAD_APICID ;cpu_clear (cpu, cpu_sibling_setup_map); }
xen/include/asm-x86/processor.h +4 -4
@@ -175,6 +175,8 @@__u32 x86_max_cores;/* cpuid returned max cores value */ __u32 booted_cores;/* number of cores as seen by OS */ __u32 x86_num_siblings;/* cpuid logical cpus per chip value */ +int phys_proc_id;/* package ID of each logical CPU */ +int cpu_core_id;/* core ID of each logical CPU*/ __u32 apicid;unsigned short x86_clflush_size; } __cacheline_aligned;
@@ -194,8 +196,6 @@#endif extern u64 host_pat; -extern int phys_proc_id[NR_CPUS ]; -extern int cpu_core_id[NR_CPUS ];extern bool_t opt_cpu_info;/* Maximum width of physical addresses supported by the hardware */
@@ -215,8 +215,8 @@ static always_inline void detect_ht(struct cpuinfo_x86 *c) {}#endif -#define cpu_to_core (_cpu) (cpu_core_id[_cpu]) -#define cpu_to_socket (_cpu) (phys_proc_id[_cpu]) +#define cpu_to_core (_cpu) (cpu_data[_cpu].cpu_core_id) +#define cpu_to_socket (_cpu) (cpu_data[_cpu].phys_proc_id)/* * Generic CPUID function
# HG changeset patch
# User Wei Huang <[email protected]>
# Date 1309193845 18000
# Node ID 4d928bdd56769eb8b09eefd5db80400e1c6c818a # Parent e6c4ff6fcb9fcbf1899463e5ec6c425bcbd683e3
x86: AMD core-pair topology detection code
This patch is to support core-pair topology introduced by AMD CPUs, which introduces a new concept of [core, compute unit]. There is a new feature bit for topology extension in CPUID:0x80000001. Also a new CPUID 0x8000001E is introduced for CPU topology enumeration. This patch collects the sibling information from the new CPUID and will be stored in the sibling map in Xen hypervisor.
xen/arch/x86/cpu/amd.c +44 -20
76 lines not on this page · raw message
xen/arch/x86/cpu/common.c +1 -0
@@ -318,6 +318,7 @@ c->x86_clflush_size =0 ; c->phys_proc_id =BAD_APICID ; c->cpu_core_id =BAD_APICID ; + c->compute_unit_id =BAD_APICID ;memset (&c->x86_capability,0 ,sizeof c->x86_capability);generic_identify (c);
xen/arch/x86/smpboot.c +16 -7
@@ -230,6 +230,14 @@/* CPUs for which sibling maps can be computed. */ static cpumask_t cpu_sibling_setup_map; +static void link_thread_siblings (int cpu1,int cpu2) +{ +cpu_set (cpu1,per_cpu (cpu_sibling_map, cpu2)); +cpu_set (cpu2,per_cpu (cpu_sibling_map, cpu1)); +cpu_set (cpu1,per_cpu (cpu_core_map, cpu2)); +cpu_set (cpu2,per_cpu (cpu_core_map, cpu1)); +} +static void set_cpu_sibling_map (int cpu) {int i;
@@ -241,13 +249,13 @@ { 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) ) - { -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)); +if (cpu_has (c,X86_FEATURE_TOPOEXT ) ) { +if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) && + (c[cpu].compute_unit_id == c[i].compute_unit_id) ) +link_thread_siblings (cpu, i); + }else if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) && + (c[cpu].cpu_core_id == c[i].cpu_core_id) ) { +link_thread_siblings (cpu, i); } } }
@@ -828,6 +836,7 @@cpus_clear (per_cpu (cpu_core_map, cpu)); c[cpu].phys_proc_id =BAD_APICID ; c[cpu].cpu_core_id =BAD_APICID ; + c[cpu].compute_unit_id =BAD_APICID ;cpu_clear (cpu, cpu_sibling_setup_map); }
xen/include/asm-x86/processor.h +2 -1
@@ -175,9 +175,10 @@__u32 x86_max_cores;/* cpuid returned max cores value */ __u32 booted_cores;/* number of cores as seen by OS */ __u32 x86_num_siblings;/* cpuid logical cpus per chip value */ +__u32 apicid;int phys_proc_id;/* package ID of each logical CPU */ int cpu_core_id;/* core ID of each logical CPU*/ -__u32 apicid; +int compute_unit_id;/* AMD compute unit ID of each logical CPU */ unsigned short x86_clflush_size; } __cacheline_aligned;
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
Jan Beulich
Acked-byQuoted 3 lines
Quoted 1 line
Quoted 1 line · Wei Huang
Thanks, Jan and George. I attach the latest version which fixes the indentation issues.
Quoted 29 lines
-Wei
Quoted 24 lines · Jan Beulich
Quoted 9 lines
Quoted 1 line
Quoted 1 line · Wei Huang
Hi,
The following two patches enable core-pair topology detection for AMD CPUs. The main idea is to record compute unit information into
cpuinfo_x86and use it when building sibling map. The sibling map will be used by Xen credit scheduler to coordinate VCPU scheduling in a fashion similar to SMT. This code is very similar to upstream Linux kernel.Quoted 6 lines
Regarding the performance improvement, I saw ~8% improvement running kernel compilation on Dom0 with this patch. Anrea Przywara ran a POVRay benchmark using this patch and he saw ~5% improvement. No perf degradation was seen so far.
Please review.
Apart from some indentation issues these look fine to me.
Jan
Quoted 2 lines
Thanks,
-Wei
George Dunlap
Acked-byQuoted 2 lines · Wei Huang
Thanks, Jan and George. I attach the latest version which fixes the indentation issues.
Assuming the patch has the same effect on the scheduling, my previous ack-effects-on-the-schedulers stands:
Quoted 30 lines
-Wei
Quoted 24 lines · Jan Beulich
Quoted 9 lines
Quoted 1 line
Quoted 1 line · Wei Huang
Hi,
The following two patches enable core-pair topology detection for AMD CPUs. The main idea is to record compute unit information into
cpuinfo_x86and use it when building sibling map. The sibling map will be used by Xen credit scheduler to coordinate VCPU scheduling in a fashion similar to SMT. This code is very similar to upstream Linux kernel.Quoted 6 lines
Regarding the performance improvement, I saw ~8% improvement running kernel compilation on Dom0 with this patch. Anrea Przywara ran a POVRay benchmark using this patch and he saw ~5% improvement. No perf degradation was seen so far.
Please review.
Apart from some indentation issues these look fine to me.
Jan
Quoted 2 lines
Thanks,
-Wei
Sorry for the late request -- should these patches be back-ported to 4.1.2? Otherwise anyone using AMD Magny-cours may have a significant performance hit when using 4.1.
-George
Quoted 43 lines · Wei Huang
Thanks, Jan and George. I attach the latest version which fixes the indentation issues.
-Wei
Quoted 17 lines · Jan Beulich
Quoted 17 lines
Quoted 2 lines
Quoted 2 lines · Wei Huang
Hi,
The following two patches enable core-pair topology detection for AMD CPUs. The main idea is to record compute unit information into
cpuinfo_x86and use it when building sibling map. The sibling map will be used by Xen credit scheduler to coordinate VCPU scheduling in a fashion similar to SMT. This code is very similar to upstream Linux kernel.Regarding the performance improvement, I saw ~8% improvement running kernel compilation on Dom0 with this patch. Anrea Przywara ran a POVRay benchmark using this patch and he saw ~5% improvement. No perf degradation was seen so far.
Quoted 11 lines
Quoted 1 line
Please review.
Apart from some indentation issues these look fine to me.
Jan
Quoted 2 lines
Thanks,
-Wei_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel