Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2
xen
23611-amd-fam15-topology.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 23611-amd-fam15-topology.patch of Package xen
References: fate#309894 # HG changeset patch # User Wei Huang <wei.huang2@amd.com> # Date 1309248833 -3600 # Node ID c2c12b2dafb5b1d3bfcc4c05a60ca4f9051c90e7 # Parent 87c2013c2aa2d4874f892507e6cc7b52219a3acf 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. Signed-off-by: Wei Huang <wei.huang2@amd.com> Index: xen-4.1.2-testing/xen/arch/x86/cpu/amd.c =================================================================== --- xen-4.1.2-testing.orig/xen/arch/x86/cpu/amd.c +++ xen-4.1.2-testing/xen/arch/x86/cpu/amd.c @@ -344,6 +344,49 @@ static void check_syscfg_dram_mod_en(voi wrmsrl(MSR_K8_SYSCFG, syscfg); } +static void __devinit amd_get_topology(struct cpuinfo_x86 *c) +{ +#ifdef CONFIG_X86_HT + int cpu; + unsigned bits; + + if (c->x86_max_cores <= 1) + return; + /* + * On a AMD multi core setup the lower bits of the APIC id + * distingush the cores. + */ + cpu = smp_processor_id(); + bits = (cpuid_ecx(0x80000008) >> 12) & 0xf; + + if (bits == 0) { + while ((1 << bits) < c->x86_max_cores) + bits++; + } + + /* Low order bits define the core id */ + c->cpu_core_id = c->phys_proc_id & ((1<<bits)-1); + /* Convert local APIC ID into the socket ID */ + c->phys_proc_id >>= bits; + /* Collect compute unit ID if available */ + if (cpu_has(c, X86_FEATURE_TOPOEXT)) { + u32 eax, ebx, ecx, edx; + + cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); + c->compute_unit_id = ebx & 0xFF; + c->x86_num_siblings = ((ebx >> 8) & 0x3) + 1; + } + + if (opt_cpu_info) + printk("CPU %d(%d) -> Processor %d, %s %d\n", + cpu, c->x86_max_cores, c->phys_proc_id, + cpu_has(c, X86_FEATURE_TOPOEXT) ? "Compute Unit" : + "Core", + cpu_has(c, X86_FEATURE_TOPOEXT) ? c->compute_unit_id : + c->cpu_core_id); +#endif +} + static void __devinit init_amd(struct cpuinfo_x86 *c) { u32 l, h; @@ -566,26 +609,7 @@ static void __devinit init_amd(struct cp } } -#ifdef CONFIG_X86_HT - /* - * On a AMD multi core setup the lower bits of the APIC id - * distingush the cores. - */ - if (c->x86_max_cores > 1) { - int cpu = smp_processor_id(); - unsigned bits = (cpuid_ecx(0x80000008) >> 12) & 0xf; - - if (bits == 0) { - while ((1 << bits) < c->x86_max_cores) - 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, c->cpu_core_id); - } -#endif + amd_get_topology(c); /* Pointless to use MWAIT on Family10 as it does not deep sleep. */ if (c->x86 >= 0x10 && !force_mwait) Index: xen-4.1.2-testing/xen/arch/x86/cpu/common.c =================================================================== --- xen-4.1.2-testing.orig/xen/arch/x86/cpu/common.c +++ xen-4.1.2-testing/xen/arch/x86/cpu/common.c @@ -364,6 +364,7 @@ void __cpuinit identify_cpu(struct cpuin 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); if (!have_cpuid_p()) { Index: xen-4.1.2-testing/xen/arch/x86/smpboot.c =================================================================== --- xen-4.1.2-testing.orig/xen/arch/x86/smpboot.c +++ xen-4.1.2-testing/xen/arch/x86/smpboot.c @@ -240,6 +240,14 @@ static int booting_cpu; /* 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; @@ -251,13 +259,13 @@ static void set_cpu_sibling_map(int cpu) { 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); } } } @@ -838,6 +846,7 @@ remove_siblinginfo(int cpu) 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); } Index: xen-4.1.2-testing/xen/include/asm-x86/processor.h =================================================================== --- xen-4.1.2-testing.orig/xen/include/asm-x86/processor.h +++ xen-4.1.2-testing/xen/include/asm-x86/processor.h @@ -175,9 +175,10 @@ struct cpuinfo_x86 { __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;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor