x86/CPU/AMD: Save AMD NodeId as cpu_die_id
authorYazen Ghannam <yazen.ghannam@amd.com>
Mon, 9 Nov 2020 21:06:56 +0000 (21:06 +0000)
committerBorislav Petkov <bp@suse.de>
Thu, 19 Nov 2020 10:43:13 +0000 (11:43 +0100)
AMD systems provide a "NodeId" value that represents a global ID
indicating to which "Node" a logical CPU belongs. The "Node" is a
physical structure equivalent to a Die, and it should not be confused
with logical structures like NUMA nodes. Logical nodes can be adjusted
based on firmware or other settings whereas the physical nodes/dies are
fixed based on hardware topology.

The NodeId value can be used when a physical ID is needed by software.

Save the AMD NodeId to struct cpuinfo_x86.cpu_die_id. Use the value
from CPUID or MSR as appropriate. Default to phys_proc_id otherwise.
Do so for both AMD and Hygon systems.

Drop the node_id parameter from cacheinfo_*_init_llc_id() as it is no
longer needed.

Update the x86 topology documentation.

Suggested-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20201109210659.754018-2-Yazen.Ghannam@amd.com
Documentation/x86/topology.rst
arch/x86/include/asm/cacheinfo.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/cacheinfo.c
arch/x86/kernel/cpu/hygon.c

index e297399..7f58010 100644 (file)
@@ -41,6 +41,8 @@ Package
 Packages contain a number of cores plus shared resources, e.g. DRAM
 controller, shared caches etc.
 
+Modern systems may also use the term 'Die' for package.
+
 AMD nomenclature for package is 'Node'.
 
 Package-related topology information in the kernel:
@@ -53,11 +55,18 @@ Package-related topology information in the kernel:
 
     The number of dies in a package. This information is retrieved via CPUID.
 
+  - cpuinfo_x86.cpu_die_id:
+
+    The physical ID of the die. This information is retrieved via CPUID.
+
   - cpuinfo_x86.phys_proc_id:
 
     The physical ID of the package. This information is retrieved via CPUID
     and deduced from the APIC IDs of the cores in the package.
 
+    Modern systems use this value for the socket. There may be multiple
+    packages within a socket. This value may differ from cpu_die_id.
+
   - cpuinfo_x86.logical_proc_id:
 
     The logical ID of the package. As we do not trust BIOSes to enumerate the
index 86b63c7..86b2e0d 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _ASM_X86_CACHEINFO_H
 #define _ASM_X86_CACHEINFO_H
 
-void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id);
-void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id);
+void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu);
+void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu);
 
 #endif /* _ASM_X86_CACHEINFO_H */
index 6062ce5..2f1fbd8 100644 (file)
@@ -330,7 +330,6 @@ static void legacy_fixup_core_id(struct cpuinfo_x86 *c)
  */
 static void amd_get_topology(struct cpuinfo_x86 *c)
 {
-       u8 node_id;
        int cpu = smp_processor_id();
 
        /* get information required for multi-node processors */
@@ -340,7 +339,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
 
                cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
 
-               node_id  = ecx & 0xff;
+               c->cpu_die_id  = ecx & 0xff;
 
                if (c->x86 == 0x15)
                        c->cu_id = ebx & 0xff;
@@ -360,15 +359,15 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
                if (!err)
                        c->x86_coreid_bits = get_count_order(c->x86_max_cores);
 
-               cacheinfo_amd_init_llc_id(c, cpu, node_id);
+               cacheinfo_amd_init_llc_id(c, cpu);
 
        } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
                u64 value;
 
                rdmsrl(MSR_FAM10H_NODE_ID, value);
-               node_id = value & 7;
+               c->cpu_die_id = value & 7;
 
-               per_cpu(cpu_llc_id, cpu) = node_id;
+               per_cpu(cpu_llc_id, cpu) = c->cpu_die_id;
        } else
                return;
 
@@ -393,7 +392,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
        /* Convert the initial APIC ID into the socket ID */
        c->phys_proc_id = c->initial_apicid >> bits;
        /* use socket ID also for last level cache */
-       per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
+       per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
 }
 
 static void amd_detect_ppin(struct cpuinfo_x86 *c)
index 57074cf..f9ac682 100644 (file)
@@ -646,7 +646,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
        return i;
 }
 
-void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
+void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu)
 {
        /*
         * We may have multiple LLCs if L3 caches exist, so check if we
@@ -657,7 +657,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
 
        if (c->x86 < 0x17) {
                /* LLC is at the node level. */
-               per_cpu(cpu_llc_id, cpu) = node_id;
+               per_cpu(cpu_llc_id, cpu) = c->cpu_die_id;
        } else if (c->x86 == 0x17 && c->x86_model <= 0x1F) {
                /*
                 * LLC is at the core complex level.
@@ -684,7 +684,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
        }
 }
 
-void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
+void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu)
 {
        /*
         * We may have multiple LLCs if L3 caches exist, so check if we
index ac6c30e..dc0840a 100644 (file)
@@ -65,7 +65,6 @@ static void hygon_get_topology_early(struct cpuinfo_x86 *c)
  */
 static void hygon_get_topology(struct cpuinfo_x86 *c)
 {
-       u8 node_id;
        int cpu = smp_processor_id();
 
        /* get information required for multi-node processors */
@@ -75,7 +74,7 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
 
                cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
 
-               node_id  = ecx & 0xff;
+               c->cpu_die_id  = ecx & 0xff;
 
                c->cpu_core_id = ebx & 0xff;
 
@@ -93,14 +92,14 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
                /* Socket ID is ApicId[6] for these processors. */
                c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT;
 
-               cacheinfo_hygon_init_llc_id(c, cpu, node_id);
+               cacheinfo_hygon_init_llc_id(c, cpu);
        } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
                u64 value;
 
                rdmsrl(MSR_FAM10H_NODE_ID, value);
-               node_id = value & 7;
+               c->cpu_die_id = value & 7;
 
-               per_cpu(cpu_llc_id, cpu) = node_id;
+               per_cpu(cpu_llc_id, cpu) = c->cpu_die_id;
        } else
                return;
 
@@ -123,7 +122,7 @@ static void hygon_detect_cmp(struct cpuinfo_x86 *c)
        /* Convert the initial APIC ID into the socket ID */
        c->phys_proc_id = c->initial_apicid >> bits;
        /* use socket ID also for last level cache */
-       per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
+       per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
 }
 
 static void srat_detect_node(struct cpuinfo_x86 *c)