Skip to content

Commit 63edbaa

Browse files
KAGA-KOKOIngo Molnar
authored and
Ingo Molnar
committed
x86/cpu/topology: Add support for the AMD 0x80000026 leaf
On AMD processors that support extended CPUID leaf 0x80000026, use the extended leaf to parse the topology information. In case of a failure, fall back to parsing the information from CPUID leaf 0xb. CPUID leaf 0x80000026 exposes the "CCX" and "CCD (Die)" information on AMD processors which have been mapped to TOPO_TILE_DOMAIN and TOPO_DIE_DOMAIN respectively. Since this information was previously not available via CPUID leaf 0xb or 0x8000001e, the "die_id", "logical_die_id", "max_die_per_pkg", "die_cpus", and "die_cpus_list" will differ with this addition on AMD processors that support extended CPUID leaf 0x80000026 and contain more than one "CCD (Die)" on the package. For example, following are the changes in the values reported by "/sys/kernel/debug/x86/topo/cpus/16" after applying this patch on a 4th Generation AMD EPYC System (1 x 128C/256T): (CPU16 is the first CPU of the second CCD on the package) tip:x86/apic tip:x86/apic + this patch online: 1 1 initial_apicid: 80 80 apicid: 80 80 pkg_id: 0 0 die_id: 0 4 * cu_id: 255 255 core_id: 64 64 logical_pkg_id: 0 0 logical_die_id: 0 4 * llc_id: 8 8 l2c_id: 65535 65535 amd_node_id: 0 0 amd_nodes_per_pkg: 1 1 num_threads: 256 256 num_cores: 128 128 max_dies_per_pkg: 1 8 * max_threads_per_core:2 2 [ prateek: commit log, updated comment in topoext_amd.c, changed has_0xb to has_topoext, rebased the changes on tip:x86/apic, tested the changes on 4th Gen AMD EPYC system ] [ mingo: tidy up the changelog a bit more ] Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: K Prateek Nayak <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 95bfb35 commit 63edbaa

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

arch/x86/kernel/cpu/topology_amd.c

+11-8
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static void store_node(struct topo_scan *tscan, unsigned int nr_nodes, u16 node_
4848
tscan->amd_node_id = node_id;
4949
}
5050

51-
static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
51+
static bool parse_8000_001e(struct topo_scan *tscan, bool has_topoext)
5252
{
5353
struct {
5454
// eax
@@ -78,7 +78,7 @@ static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
7878
* topology_set_dom() would propagate and overwrite the already
7979
* propagated CORE level.
8080
*/
81-
if (!has_0xb) {
81+
if (!has_topoext) {
8282
unsigned int nthreads = leaf.core_nthreads + 1;
8383

8484
topology_update_dom(tscan, TOPO_SMT_DOMAIN, get_count_order(nthreads), nthreads);
@@ -137,21 +137,24 @@ static void legacy_set_llc(struct topo_scan *tscan)
137137

138138
static void parse_topology_amd(struct topo_scan *tscan)
139139
{
140-
bool has_0xb = false;
140+
bool has_topoext = false;
141141

142142
/*
143143
* If the extended topology leaf 0x8000_001e is available
144-
* try to get SMT and CORE shift from leaf 0xb first, then
145-
* try to get the CORE shift from leaf 0x8000_0008.
144+
* try to get SMT, CORE, TILE, and DIE shifts from extended
145+
* CPUID leaf 0x8000_0026 on supported processors first. If
146+
* extended CPUID leaf 0x8000_0026 is not supported, try to
147+
* get SMT and CORE shift from leaf 0xb first, then try to
148+
* get the CORE shift from leaf 0x8000_0008.
146149
*/
147150
if (cpu_feature_enabled(X86_FEATURE_TOPOEXT))
148-
has_0xb = cpu_parse_topology_ext(tscan);
151+
has_topoext = cpu_parse_topology_ext(tscan);
149152

150-
if (!has_0xb && !parse_8000_0008(tscan))
153+
if (!has_topoext && !parse_8000_0008(tscan))
151154
return;
152155

153156
/* Prefer leaf 0x8000001e if available */
154-
if (parse_8000_001e(tscan, has_0xb))
157+
if (parse_8000_001e(tscan, has_topoext))
155158
return;
156159

157160
/* Try the NODEID MSR */

arch/x86/kernel/cpu/topology_ext.c

+15
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ enum topo_types {
1313
CORE_TYPE = 2,
1414
MAX_TYPE_0B = 3,
1515
MODULE_TYPE = 3,
16+
AMD_CCD_TYPE = 3,
1617
TILE_TYPE = 4,
18+
AMD_SOCKET_TYPE = 4,
19+
MAX_TYPE_80000026 = 5,
1720
DIE_TYPE = 5,
1821
DIEGRP_TYPE = 6,
1922
MAX_TYPE_1F = 7,
@@ -32,6 +35,13 @@ static const unsigned int topo_domain_map_0b_1f[MAX_TYPE_1F] = {
3235
[DIEGRP_TYPE] = TOPO_DIEGRP_DOMAIN,
3336
};
3437

38+
static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
39+
[SMT_TYPE] = TOPO_SMT_DOMAIN,
40+
[CORE_TYPE] = TOPO_CORE_DOMAIN,
41+
[AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
42+
[AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
43+
};
44+
3545
static inline bool topo_subleaf(struct topo_scan *tscan, u32 leaf, u32 subleaf,
3646
unsigned int *last_dom)
3747
{
@@ -56,6 +66,7 @@ static inline bool topo_subleaf(struct topo_scan *tscan, u32 leaf, u32 subleaf,
5666
switch (leaf) {
5767
case 0x0b: maxtype = MAX_TYPE_0B; map = topo_domain_map_0b_1f; break;
5868
case 0x1f: maxtype = MAX_TYPE_1F; map = topo_domain_map_0b_1f; break;
69+
case 0x80000026: maxtype = MAX_TYPE_80000026; map = topo_domain_map_80000026; break;
5970
default: return false;
6071
}
6172

@@ -125,6 +136,10 @@ bool cpu_parse_topology_ext(struct topo_scan *tscan)
125136
if (tscan->c->cpuid_level >= 0x1f && parse_topology_leaf(tscan, 0x1f))
126137
return true;
127138

139+
/* AMD: Try leaf 0x80000026 first. */
140+
if (tscan->c->extended_cpuid_level >= 0x80000026 && parse_topology_leaf(tscan, 0x80000026))
141+
return true;
142+
128143
/* Intel/AMD: Fall back to leaf 0xB if available */
129144
return tscan->c->cpuid_level >= 0x0b && parse_topology_leaf(tscan, 0x0b);
130145
}

0 commit comments

Comments
 (0)