x86/topology: Fix AMD core count
authorPeter Zijlstra <peterz@infradead.org>
Fri, 25 Mar 2016 14:52:34 +0000 (15:52 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 29 Mar 2016 08:45:04 +0000 (10:45 +0200)
It turns out AMD gets x86_max_cores wrong when there are compute
units.

The issue is that Linux assumes:

nr_logical_cpus = nr_cores * nr_siblings

But AMD reports its CU unit as 2 cores, but then sets num_smp_siblings
to 2 as well.

Boris: fixup ras/mce_amd_inj.c too, to compute the Node Base Core
properly, according to the new nomenclature.

Fixes: 1f12e32f4cd5 ("x86/topology: Create logical package id")
Reported-by: Xiong Zhou <jencce.kernel@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andreas Herrmann <aherrmann@suse.com>
Cc: Andy Lutomirski <luto@kernel.org>
Link: http://lkml.kernel.org/r/20160317095220.GO6344@twins.programming.kicks-ass.net
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/include/asm/smp.h
arch/x86/kernel/cpu/amd.c
arch/x86/ras/mce_amd_inj.c

index 20a3de5cb3b0dd5e3362833baebd752c1142ae4e..66b057306f404718c233c18c5603ec30e9e535ba 100644 (file)
@@ -155,6 +155,7 @@ static inline int wbinvd_on_all_cpus(void)
        wbinvd();
        return 0;
 }
+#define smp_num_siblings       1
 #endif /* CONFIG_SMP */
 
 extern unsigned disabled_cpus;
index 6e47e3a916f12a03069a7c38ef21e9b2df5edcdf..4d0087f94ee543b52c291add95b15c00b1e68dc6 100644 (file)
@@ -312,9 +312,9 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
                node_id = ecx & 7;
 
                /* get compute unit information */
-               smp_num_siblings = ((ebx >> 8) & 3) + 1;
+               cores_per_cu = smp_num_siblings = ((ebx >> 8) & 3) + 1;
+               c->x86_max_cores /= smp_num_siblings;
                c->compute_unit_id = ebx & 0xff;
-               cores_per_cu += ((ebx >> 8) & 3);
        } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
                u64 value;
 
@@ -329,8 +329,8 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
                u32 cus_per_node;
 
                set_cpu_cap(c, X86_FEATURE_AMD_DCM);
-               cores_per_node = c->x86_max_cores / nodes_per_socket;
-               cus_per_node = cores_per_node / cores_per_cu;
+               cus_per_node = c->x86_max_cores / nodes_per_socket;
+               cores_per_node = cus_per_node * cores_per_cu;
 
                /* store NodeID, use llc_shared_map to store sibling info */
                per_cpu(cpu_llc_id, cpu) = node_id;
index 55d38cfa46c2626c6d2f85587da27c05ca3e6bf7..9e02dcaef68311ed376f8fcd0579d6c207e80103 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/pci.h>
 
 #include <asm/mce.h>
+#include <asm/smp.h>
 #include <asm/amd_nb.h>
 #include <asm/irq_vectors.h>
 
@@ -206,7 +207,7 @@ static u32 get_nbc_for_node(int node_id)
        struct cpuinfo_x86 *c = &boot_cpu_data;
        u32 cores_per_node;
 
-       cores_per_node = c->x86_max_cores / amd_get_nodes_per_socket();
+       cores_per_node = (c->x86_max_cores * smp_num_siblings) / amd_get_nodes_per_socket();
 
        return cores_per_node * node_id;
 }
This page took 0.027519 seconds and 5 git commands to generate.