Commit 090610ba authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

x86/cpu/topology: Use topology bitmaps for sizing



Now that all possible APIC IDs are tracked in the topology bitmaps, its
trivial to retrieve the real information from there.

This gets rid of the guesstimates for the maximal packages and dies per
package as the actual numbers can be determined before a single AP has been
brought up.

The number of SMT threads can now be determined correctly from the bitmaps
in all situations. Up to now a system which has SMT disabled in the BIOS
will still claim that it is SMT capable, because the lowest APIC ID bit is
reserved for that and CPUID leaf 0xb/0x1f still enumerates the SMT domain
accordingly. By calculating the bitmap weights of the SMT and the CORE
domain and setting them into relation the SMT disabled in BIOS situation
reports correctly that the system is not SMT capable.

It also handles the situation correctly when a hybrid systems boot CPU does
not have SMT as it takes the SMT capability of the APs fully into account.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarMichael Kelley <mhklinux@outlook.com>
Tested-by: default avatarSohil Mehta <sohil.mehta@intel.com>
Link: https://lore.kernel.org/r/20240213210252.681709880@linutronix.de
parent 354da4cf
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
#include <asm/current.h>
#include <asm/thread_info.h>

extern int smp_num_siblings;
extern unsigned int smp_num_siblings;

DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
@@ -109,7 +109,6 @@ void cpu_disable_common(void);
void native_smp_prepare_boot_cpu(void);
void smp_prepare_cpus_common(void);
void native_smp_prepare_cpus(unsigned int max_cpus);
void calculate_max_logical_packages(void);
void native_smp_cpus_done(unsigned int max_cpus);
int common_cpu_up(unsigned int cpunum, struct task_struct *tidle);
int native_kick_ap(unsigned int cpu, struct task_struct *tidle);
+12 −11
Original line number Diff line number Diff line
@@ -143,7 +143,18 @@ extern const struct cpumask *cpu_clustergroup_mask(int cpu);

#define topology_amd_node_id(cpu)		(cpu_data(cpu).topo.amd_node_id)

extern unsigned int __max_die_per_package;
extern unsigned int __max_dies_per_package;
extern unsigned int __max_logical_packages;

static inline unsigned int topology_max_packages(void)
{
	return __max_logical_packages;
}

static inline unsigned int topology_max_die_per_package(void)
{
	return __max_dies_per_package;
}

#ifdef CONFIG_SMP
#define topology_cluster_id(cpu)		(cpu_data(cpu).topo.l2c_id)
@@ -152,14 +163,6 @@ extern unsigned int __max_die_per_package;
#define topology_core_cpumask(cpu)		(per_cpu(cpu_core_map, cpu))
#define topology_sibling_cpumask(cpu)		(per_cpu(cpu_sibling_map, cpu))

extern unsigned int __max_logical_packages;
#define topology_max_packages()			(__max_logical_packages)

static inline int topology_max_die_per_package(void)
{
	return __max_die_per_package;
}

extern int __max_smt_threads;

static inline int topology_max_smt_threads(void)
@@ -193,13 +196,11 @@ static inline bool topology_is_primary_thread(unsigned int cpu)
}

#else /* CONFIG_SMP */
#define topology_max_packages()			(1)
static inline int
topology_update_package_map(unsigned int apicid, unsigned int cpu) { return 0; }
static inline int
topology_update_die_map(unsigned int dieid, unsigned int cpu) { return 0; }
static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
static inline int topology_max_die_per_package(void) { return 1; }
static inline int topology_max_smt_threads(void) { return 1; }
static inline bool topology_is_primary_thread(unsigned int cpu) { return true; }
static inline unsigned int topology_amd_nodes_per_pkg(void) { return 0; };
+6 −3
Original line number Diff line number Diff line
@@ -73,11 +73,14 @@
u32 elf_hwcap2 __read_mostly;

/* Number of siblings per CPU package */
int smp_num_siblings = 1;
unsigned int smp_num_siblings __ro_after_init = 1;
EXPORT_SYMBOL(smp_num_siblings);

unsigned int __max_die_per_package __read_mostly = 1;
EXPORT_SYMBOL(__max_die_per_package);
unsigned int __max_dies_per_package __ro_after_init = 1;
EXPORT_SYMBOL(__max_dies_per_package);

unsigned int __max_logical_packages __ro_after_init = 1;
EXPORT_SYMBOL(__max_logical_packages);

static struct ppin_info {
	int	feature;
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ static int cpu_debug_show(struct seq_file *m, void *p)
	seq_printf(m, "amd_node_id:         %u\n", c->topo.amd_node_id);
	seq_printf(m, "amd_nodes_per_pkg:   %u\n", topology_amd_nodes_per_pkg());
	seq_printf(m, "max_cores:           %u\n", c->x86_max_cores);
	seq_printf(m, "max_die_per_pkg:     %u\n", __max_die_per_package);
	seq_printf(m, "max_dies_per_pkg:    %u\n", __max_dies_per_package);
	seq_printf(m, "smp_num_siblings:    %u\n", smp_num_siblings);
	return 0;
}
+19 −1
Original line number Diff line number Diff line
@@ -348,8 +348,8 @@ void __init topology_init_possible_cpus(void)
{
	unsigned int assigned = topo_info.nr_assigned_cpus;
	unsigned int disabled = topo_info.nr_disabled_cpus;
	unsigned int cnta, cntb, cpu, allowed = 1;
	unsigned int total = assigned + disabled;
	unsigned int cpu, allowed = 1;
	u32 apicid;

	if (!restrict_to_up()) {
@@ -372,6 +372,24 @@ void __init topology_init_possible_cpus(void)
	total_cpus = allowed;
	set_nr_cpu_ids(allowed);

	cnta = domain_weight(TOPO_PKG_DOMAIN);
	cntb = domain_weight(TOPO_DIE_DOMAIN);
	__max_logical_packages = cnta;
	__max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta));

	pr_info("Max. logical packages: %3u\n", cnta);
	pr_info("Max. logical dies:     %3u\n", cntb);
	pr_info("Max. dies per package: %3u\n", __max_dies_per_package);

	cnta = domain_weight(TOPO_CORE_DOMAIN);
	cntb = domain_weight(TOPO_SMT_DOMAIN);
	/*
	 * Can't use order delta here as order(cnta) can be equal
	 * order(cntb) even if cnta != cntb.
	 */
	smp_num_siblings = DIV_ROUND_UP(cntb, cnta);
	pr_info("Max. threads per core: %3u\n", smp_num_siblings);

	pr_info("Allowing %u present CPUs plus %u hotplug CPUs\n", assigned, disabled);
	if (topo_info.nr_rejected_cpus)
		pr_info("Rejected CPUs %u\n", topo_info.nr_rejected_cpus);
Loading