Skip to content

Commit 1340ccf

Browse files
AlisonSchofieldKAGA-KOKO
authored andcommitted
x86,sched: Allow topologies where NUMA nodes share an LLC
Intel's Skylake Server CPUs have a different LLC topology than previous generations. When in Sub-NUMA-Clustering (SNC) mode, the package is divided into two "slices", each containing half the cores, half the LLC, and one memory controller and each slice is enumerated to Linux as a NUMA node. This is similar to how the cores and LLC were arranged for the Cluster-On-Die (CoD) feature. CoD allowed the same cache line to be present in each half of the LLC. But, with SNC, each line is only ever present in *one* slice. This means that the portion of the LLC *available* to a CPU depends on the data being accessed: Remote socket: entire package LLC is shared Local socket->local slice: data goes into local slice LLC Local socket->remote slice: data goes into remote-slice LLC. Slightly higher latency than local slice LLC. The biggest implication from this is that a process accessing all NUMA-local memory only sees half the LLC capacity. The CPU describes its cache hierarchy with the CPUID instruction. One of the CPUID leaves enumerates the "logical processors sharing this cache". This information is used for scheduling decisions so that tasks move more freely between CPUs sharing the cache. But, the CPUID for the SNC configuration discussed above enumerates the LLC as being shared by the entire package. This is not 100% precise because the entire cache is not usable by all accesses. But, it *is* the way the hardware enumerates itself, and this is not likely to change. The userspace visible impact of all the above is that the sysfs info reports the entire LLC as being available to the entire package. As noted above, this is not true for local socket accesses. This patch does not correct the sysfs info. It is the same, pre and post patch. The current code emits the following warning: sched: CPU #3's llc-sibling CPU #0 is not on the same node! [node: 1 != 0]. Ignoring dependency. The warning is coming from the topology_sane() check in smpboot.c because the topology is not matching the expectations of the model for obvious reasons. To fix this, add a vendor and model specific check to never call topology_sane() for these systems. Also, just like "Cluster-on-Die" disable the "coregroup" sched_domain_topology_level and use NUMA information from the SRAT alone. This is OK at least on the hardware we are immediately concerned about because the LLC sharing happens at both the slice and at the package level, which are also NUMA boundaries. Signed-off-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Borislav Petkov <bp@suse.de> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: brice.goglin@gmail.com Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: David Rientjes <rientjes@google.com> Cc: Igor Mammedov <imammedo@redhat.com> Cc: "H. Peter Anvin" <hpa@linux.intel.com> Cc: Tim Chen <tim.c.chen@linux.intel.com> Link: https://lkml.kernel.org/r/20180407002130.GA18984@alison-desk.jf.intel.com
1 parent 451cf3c commit 1340ccf

1 file changed

Lines changed: 40 additions & 5 deletions

File tree

‎arch/x86/kernel/smpboot.c‎

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
#include <asm/i8259.h>
7878
#include <asm/misc.h>
7979
#include <asm/qspinlock.h>
80+
#include <asm/intel-family.h>
81+
#include <asm/cpu_device_id.h>
8082

8183
/* Number of siblings per CPU package */
8284
int smp_num_siblings = 1;
@@ -390,15 +392,47 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
390392
return false;
391393
}
392394

395+
/*
396+
* Define snc_cpu[] for SNC (Sub-NUMA Cluster) CPUs.
397+
*
398+
* These are Intel CPUs that enumerate an LLC that is shared by
399+
* multiple NUMA nodes. The LLC on these systems is shared for
400+
* off-package data access but private to the NUMA node (half
401+
* of the package) for on-package access.
402+
*
403+
* CPUID (the source of the information about the LLC) can only
404+
* enumerate the cache as being shared *or* unshared, but not
405+
* this particular configuration. The CPU in this case enumerates
406+
* the cache to be shared across the entire package (spanning both
407+
* NUMA nodes).
408+
*/
409+
410+
static const struct x86_cpu_id snc_cpu[] = {
411+
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X },
412+
{}
413+
};
414+
393415
static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
394416
{
395417
int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
396418

397-
if (per_cpu(cpu_llc_id, cpu1) != BAD_APICID &&
398-
per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2))
399-
return topology_sane(c, o, "llc");
419+
/* Do not match if we do not have a valid APICID for cpu: */
420+
if (per_cpu(cpu_llc_id, cpu1) == BAD_APICID)
421+
return false;
400422

401-
return false;
423+
/* Do not match if LLC id does not match: */
424+
if (per_cpu(cpu_llc_id, cpu1) != per_cpu(cpu_llc_id, cpu2))
425+
return false;
426+
427+
/*
428+
* Allow the SNC topology without warning. Return of false
429+
* means 'c' does not share the LLC of 'o'. This will be
430+
* reflected to userspace.
431+
*/
432+
if (!topology_same_node(c, o) && x86_match_cpu(snc_cpu))
433+
return false;
434+
435+
return topology_sane(c, o, "llc");
402436
}
403437

404438
/*
@@ -456,7 +490,8 @@ static struct sched_domain_topology_level x86_topology[] = {
456490

457491
/*
458492
* Set if a package/die has multiple NUMA nodes inside.
459-
* AMD Magny-Cours and Intel Cluster-on-Die have this.
493+
* AMD Magny-Cours, Intel Cluster-on-Die, and Intel
494+
* Sub-NUMA Clustering have this.
460495
*/
461496
static bool x86_has_numa_in_package;
462497

0 commit comments

Comments
 (0)