[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-4.1-testing] x86: AMD core-pair topology detection code



# HG changeset patch
# User Wei Huang <wei.huang2@xxxxxxx>
# Date 1331112260 0
# Node ID f141db2fe4c1600cd40e1737560f5841150a30b2
# Parent  a168569a765915e0bb592b348359def4f6784ca6
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@xxxxxxx>
xen-unstable changeset:   23611:c2c12b2dafb5
xen-unstable date:        Tue Jun 28 09:13:53 2011 +0100
---


diff -r a168569a7659 -r f141db2fe4c1 xen/arch/x86/cpu/amd.c
--- a/xen/arch/x86/cpu/amd.c    Wed Mar 07 09:23:41 2012 +0000
+++ b/xen/arch/x86/cpu/amd.c    Wed Mar 07 09:24:20 2012 +0000
@@ -344,6 +344,49 @@
        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 @@
                }
        }
 
-#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)
diff -r a168569a7659 -r f141db2fe4c1 xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c Wed Mar 07 09:23:41 2012 +0000
+++ b/xen/arch/x86/cpu/common.c Wed Mar 07 09:24:20 2012 +0000
@@ -364,6 +364,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);
 
        if (!have_cpuid_p()) {
diff -r a168569a7659 -r f141db2fe4c1 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Wed Mar 07 09:23:41 2012 +0000
+++ b/xen/arch/x86/smpboot.c    Wed Mar 07 09:24:20 2012 +0000
@@ -241,6 +241,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;
@@ -252,13 +260,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);
             }
         }
     }
@@ -854,6 +862,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);
 }
 
diff -r a168569a7659 -r f141db2fe4c1 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Wed Mar 07 09:23:41 2012 +0000
+++ b/xen/include/asm-x86/processor.h   Wed Mar 07 09:24:20 2012 +0000
@@ -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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.