Skip to content

Commit

Permalink
x86/CPU/AMD: Save AMD NodeId as cpu_die_id
Browse files Browse the repository at this point in the history
[ Upstream commit 028c221 ]

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
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
yghannam authored and gregkh committed Dec 30, 2020
1 parent bb25fd4 commit 700d098
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 17 deletions.
9 changes: 9 additions & 0 deletions Documentation/x86/topology.rst
Expand Up @@ -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:
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/include/asm/cacheinfo.h
Expand Up @@ -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 */
11 changes: 5 additions & 6 deletions arch/x86/kernel/cpu/amd.c
Expand Up @@ -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 */
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions arch/x86/kernel/cpu/cacheinfo.c
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand Down
11 changes: 5 additions & 6 deletions arch/x86/kernel/cpu/hygon.c
Expand Up @@ -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 */
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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)
Expand Down

0 comments on commit 700d098

Please sign in to comment.