Skip to content

Commit

Permalink
x86/cpu/topology: Add support for the AMD 0x80000026 leaf
Browse files Browse the repository at this point in the history
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]
  • Loading branch information
KAGA-KOKO authored and Ingo Molnar committed Mar 22, 2024
1 parent 95bfb35 commit 63edbaa
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
19 changes: 11 additions & 8 deletions arch/x86/kernel/cpu/topology_amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static void store_node(struct topo_scan *tscan, unsigned int nr_nodes, u16 node_
tscan->amd_node_id = node_id;
}

static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
static bool parse_8000_001e(struct topo_scan *tscan, bool has_topoext)
{
struct {
// eax
Expand Down Expand Up @@ -78,7 +78,7 @@ static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
* topology_set_dom() would propagate and overwrite the already
* propagated CORE level.
*/
if (!has_0xb) {
if (!has_topoext) {
unsigned int nthreads = leaf.core_nthreads + 1;

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

static void parse_topology_amd(struct topo_scan *tscan)
{
bool has_0xb = false;
bool has_topoext = false;

/*
* If the extended topology leaf 0x8000_001e is available
* try to get SMT and CORE shift from leaf 0xb first, then
* try to get the CORE shift from leaf 0x8000_0008.
* try to get SMT, CORE, TILE, and DIE shifts from extended
* CPUID leaf 0x8000_0026 on supported processors first. If
* extended CPUID leaf 0x8000_0026 is not supported, try to
* get SMT and CORE shift from leaf 0xb first, then try to
* get the CORE shift from leaf 0x8000_0008.
*/
if (cpu_feature_enabled(X86_FEATURE_TOPOEXT))
has_0xb = cpu_parse_topology_ext(tscan);
has_topoext = cpu_parse_topology_ext(tscan);

if (!has_0xb && !parse_8000_0008(tscan))
if (!has_topoext && !parse_8000_0008(tscan))
return;

/* Prefer leaf 0x8000001e if available */
if (parse_8000_001e(tscan, has_0xb))
if (parse_8000_001e(tscan, has_topoext))
return;

/* Try the NODEID MSR */
Expand Down
15 changes: 15 additions & 0 deletions arch/x86/kernel/cpu/topology_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ enum topo_types {
CORE_TYPE = 2,
MAX_TYPE_0B = 3,
MODULE_TYPE = 3,
AMD_CCD_TYPE = 3,
TILE_TYPE = 4,
AMD_SOCKET_TYPE = 4,
MAX_TYPE_80000026 = 5,
DIE_TYPE = 5,
DIEGRP_TYPE = 6,
MAX_TYPE_1F = 7,
Expand All @@ -32,6 +35,13 @@ static const unsigned int topo_domain_map_0b_1f[MAX_TYPE_1F] = {
[DIEGRP_TYPE] = TOPO_DIEGRP_DOMAIN,
};

static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
[SMT_TYPE] = TOPO_SMT_DOMAIN,
[CORE_TYPE] = TOPO_CORE_DOMAIN,
[AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
[AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
};

static inline bool topo_subleaf(struct topo_scan *tscan, u32 leaf, u32 subleaf,
unsigned int *last_dom)
{
Expand All @@ -56,6 +66,7 @@ static inline bool topo_subleaf(struct topo_scan *tscan, u32 leaf, u32 subleaf,
switch (leaf) {
case 0x0b: maxtype = MAX_TYPE_0B; map = topo_domain_map_0b_1f; break;
case 0x1f: maxtype = MAX_TYPE_1F; map = topo_domain_map_0b_1f; break;
case 0x80000026: maxtype = MAX_TYPE_80000026; map = topo_domain_map_80000026; break;
default: return false;
}

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

/* AMD: Try leaf 0x80000026 first. */
if (tscan->c->extended_cpuid_level >= 0x80000026 && parse_topology_leaf(tscan, 0x80000026))
return true;

/* Intel/AMD: Fall back to leaf 0xB if available */
return tscan->c->cpuid_level >= 0x0b && parse_topology_leaf(tscan, 0x0b);
}

0 comments on commit 63edbaa

Please sign in to comment.