Commit f7fb3b2d authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

x86/cpu: Provide an AMD/HYGON specific topology parser



AMD/HYGON uses various methods for topology evaluation:

  - Leaf 0x80000008 and 0x8000001e based with an optional leaf 0xb,
    which is the preferred variant for modern CPUs.

    Leaf 0xb will be superseded by leaf 0x80000026 soon, which is just
    another variant of the Intel 0x1f leaf for whatever reasons.
    
  - Subleaf 0x80000008 and NODEID_MSR base

  - Legacy fallback

That code is following the principle of random bits and pieces all over the
place which results in multiple evaluations and impenetrable code flows in
the same way as the Intel parsing did.

Provide a sane implementation by clearly separating the three variants and
bringing them in the proper preference order in one place.

This provides the parsing for both AMD and HYGON because there is no point
in having a separate HYGON parser which only differs by 3 lines of
code. Any further divergence between AMD and HYGON can be handled in
different functions, while still sharing the existing parsers.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarJuergen Gross <jgross@suse.com>
Tested-by: default avatarSohil Mehta <sohil.mehta@intel.com>
Tested-by: default avatarMichael Kelley <mhklinux@outlook.com>
Tested-by: default avatarZhang Rui <rui.zhang@intel.com>
Tested-by: default avatarWang Wendy <wendy.wang@intel.com>
Tested-by: default avatarK Prateek Nayak <kprateek.nayak@amd.com>
Link: https://lore.kernel.org/r/20240212153625.020038641@linutronix.de
parent 7e3ec628
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -163,6 +163,8 @@ int topology_update_package_map(unsigned int apicid, unsigned int cpu);
int topology_update_die_map(unsigned int dieid, unsigned int cpu);
int topology_phys_to_logical_pkg(unsigned int pkg);

extern unsigned int __amd_nodes_per_pkg;

static inline unsigned int topology_amd_nodes_per_pkg(void)
{
	return __max_die_per_package;
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ KMSAN_SANITIZE_common.o := n
KCSAN_SANITIZE_common.o := n

obj-y			:= cacheinfo.o scattered.o
obj-y			+= topology_common.o topology_ext.o topology.o
obj-y			+= topology_common.o topology_ext.o topology_amd.o topology.o
obj-y			+= common.o
obj-y			+= rdrand.o
obj-y			+= match.o
+1 −1
Original line number Diff line number Diff line
@@ -351,7 +351,7 @@ 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);
		cacheinfo_amd_init_llc_id(c, c->topo.die_id);

	} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
		u64 value;
+2 −2
Original line number Diff line number Diff line
@@ -661,7 +661,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
	return i;
}

void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c)
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)
{
	/*
	 * We may have multiple LLCs if L3 caches exist, so check if we
@@ -672,7 +672,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c)

	if (c->x86 < 0x17) {
		/* LLC is at the node level. */
		c->topo.llc_id = c->topo.die_id;
		c->topo.llc_id = die_id;
	} else if (c->x86 == 0x17 && c->x86_model <= 0x1F) {
		/*
		 * LLC is at the core complex level.
+1 −1
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c);
extern int detect_extended_topology(struct cpuinfo_x86 *c);
extern void check_null_seg_clears_base(struct cpuinfo_x86 *c);

void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c);
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id);
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c);

unsigned int aperfmperf_get_khz(int cpu);
Loading