]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
x86/CPU/AMD: Bring back Compute Unit ID
authorBorislav Petkov <bp@suse.de>
Sun, 5 Feb 2017 10:50:21 +0000 (11:50 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Feb 2017 23:25:41 +0000 (15:25 -0800)
commit 79a8b9aa388b0620cc1d525d7c0f0d9a8a85e08e upstream.

Commit:

  a33d331761bc ("x86/CPU/AMD: Fix Bulldozer topology")

restored the initial approach we had with the Fam15h topology of
enumerating CU (Compute Unit) threads as cores. And this is still
correct - they're beefier than HT threads but still have some
shared functionality.

Our current approach has a problem with the Mad Max Steam game, for
example. Yves Dionne reported a certain "choppiness" while playing on
v4.9.5.

That problem stems most likely from the fact that the CU threads share
resources within one CU and when we schedule to a thread of a different
compute unit, this incurs latency due to migrating the working set to a
different CU through the caches.

When the thread siblings mask mirrors that aspect of the CUs and
threads, the scheduler pays attention to it and tries to schedule within
one CU first. Which takes care of the latency, of course.

Reported-by: Yves Dionne <yves.dionne@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Brice Goglin <Brice.Goglin@inria.fr>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Yazen Ghannam <yazen.ghannam@amd.com>
Link: http://lkml.kernel.org/r/20170205105022.8705-1-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/smpboot.c

index 984a7bf17f6a7295c3a7c8531e68cb807a722c35..83db0eae99797da9fca22c59eee3fb1ed12ca373 100644 (file)
@@ -104,6 +104,7 @@ struct cpuinfo_x86 {
        __u8                    x86_phys_bits;
        /* CPUID returned core id bits: */
        __u8                    x86_coreid_bits;
+       __u8                    cu_id;
        /* Max extended CPUID function supported: */
        __u32                   extended_cpuid_level;
        /* Maximum supported CPUID level, -1=no CPUID: */
index 1d3167269a6717902149171fe755123a5c654eb6..20dc44d1e6be4e484407a8a4fb46a22fc320b297 100644 (file)
@@ -309,8 +309,15 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
 
        /* get information required for multi-node processors */
        if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+               u32 eax, ebx, ecx, edx;
 
-               node_id = cpuid_ecx(0x8000001e) & 7;
+               cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
+
+               node_id  = ecx & 0xff;
+               smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
+
+               if (c->x86 == 0x15)
+                       c->cu_id = ebx & 0xff;
 
                /*
                 * We may have multiple LLCs if L3 caches exist, so check if we
index 023c7bfa24dfeda6a61f5c6ca879fe4d6b9d25c7..4eece91ada374d1dc25c39b763861c755354d060 100644 (file)
@@ -1015,6 +1015,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
        c->x86_model_id[0] = '\0';  /* Unset */
        c->x86_max_cores = 1;
        c->x86_coreid_bits = 0;
+       c->cu_id = 0xff;
 #ifdef CONFIG_X86_64
        c->x86_clflush_size = 64;
        c->x86_phys_bits = 36;
index e9bbe02950adb779d24b0382bcde04a1f93fe6c8..36171bcd91f81c30982a0c0b826588ed19d0cde9 100644 (file)
@@ -423,9 +423,15 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
                int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
 
                if (c->phys_proc_id == o->phys_proc_id &&
-                   per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2) &&
-                   c->cpu_core_id == o->cpu_core_id)
-                       return topology_sane(c, o, "smt");
+                   per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2)) {
+                       if (c->cpu_core_id == o->cpu_core_id)
+                               return topology_sane(c, o, "smt");
+
+                       if ((c->cu_id != 0xff) &&
+                           (o->cu_id != 0xff) &&
+                           (c->cu_id == o->cu_id))
+                               return topology_sane(c, o, "smt");
+               }
 
        } else if (c->phys_proc_id == o->phys_proc_id &&
                   c->cpu_core_id == o->cpu_core_id) {