x86, amd: Normalize compute unit IDs on multi-node processors
authorAndreas Herrmann <andreas.herrmann3@amd.com>
Mon, 24 Jan 2011 15:05:40 +0000 (16:05 +0100)
committerIngo Molnar <mingo@elte.hu>
Wed, 26 Jan 2011 07:28:22 +0000 (08:28 +0100)
On multi-node CPUs we don't need the socket wide compute unit ID
but the node-wide compute unit ID. Thus we need to normalize the
value. This is similar to what we do with cpu_core_id.

A compute unit is then identified by physical_package_id,
node_id, and compute_unit_id.

Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
LKML-Reference: <1295881543-572552-2-git-send-email-hans.rosenfeld@amd.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/smpboot.c

index 7c7bedb83c5a463bad2a2cd59765d3d6b1066f8b..990cc486158696e4ecd79f79ddede91615b70d1a 100644 (file)
@@ -261,7 +261,7 @@ static int __cpuinit nearby_node(int apicid)
 #ifdef CONFIG_X86_HT
 static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c)
 {
-       u32 nodes;
+       u32 nodes, cores_per_cu;
        u8 node_id;
        int cpu = smp_processor_id();
 
@@ -276,6 +276,7 @@ static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c)
                /* get compute unit information */
                smp_num_siblings = ((ebx >> 8) & 3) + 1;
                c->compute_unit_id = ebx & 0xff;
+               cores_per_cu = ((ebx >> 8) & 3) + 1;
        } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
                u64 value;
 
@@ -288,15 +289,18 @@ static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c)
        /* fixup multi-node processor information */
        if (nodes > 1) {
                u32 cores_per_node;
+               u32 cus_per_node;
 
                set_cpu_cap(c, X86_FEATURE_AMD_DCM);
                cores_per_node = c->x86_max_cores / nodes;
+               cus_per_node = cores_per_node / cores_per_cu;
 
                /* store NodeID, use llc_shared_map to store sibling info */
                per_cpu(cpu_llc_id, cpu) = node_id;
 
                /* core id to be in range from 0 to (cores_per_node - 1) */
-               c->cpu_core_id = c->cpu_core_id % cores_per_node;
+               c->cpu_core_id %= cores_per_node;
+               c->compute_unit_id %= cus_per_node;
        }
 }
 #endif
index 0cbe8c0b35edd290e98c989cfc48c5b4b0af350a..fbaa2229af5b6c634ec4c32b6f097b91a18251d8 100644 (file)
@@ -414,6 +414,7 @@ void __cpuinit set_cpu_sibling_map(int cpu)
 
                        if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
                                if (c->phys_proc_id == o->phys_proc_id &&
+                                   per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i) &&
                                    c->compute_unit_id == o->compute_unit_id)
                                        link_thread_siblings(cpu, i);
                        } else if (c->phys_proc_id == o->phys_proc_id &&