Message ID | 20250311075143.61078-3-yangyicong@huawei.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Support SMT control on arm64 | expand |
On Tue, Mar 11, 2025 at 03:51:41PM +0800, Yicong Yang wrote: > From: Yicong Yang <yangyicong@hisilicon.com> > > On building the topology from the devicetree, we've already gotten the > SMT thread number of each core. Update the largest SMT thread number > and enable the SMT control by the end of topology parsing. > > The framework's SMT control provides two interface to the users [1] > through /sys/devices/system/cpu/smt/control: > 1) enable SMT by writing "on" and disable by "off" > 2) enable SMT by writing max_thread_number or disable by writing 1 > > Both method support to completely disable/enable the SMT cores so both > work correctly for symmetric SMT platform and asymmetric platform with > non-SMT and one type SMT cores like: > core A: 1 thread > core B: X (X!=1) threads > > Note that for a theoretically possible multiple SMT-X (X>1) core > platform the SMT control is also supported as expected but only > by writing the "on/off" method. > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/ABI/testing/sysfs-devices-system-cpu#n542 Just the path must suffice here, no need for URL. LGTM otherwise, much simple now: Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 3ebe77566788..d409d323ee64 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -11,6 +11,7 @@ #include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpufreq.h> +#include <linux/cpu_smt.h> #include <linux/device.h> #include <linux/of.h> #include <linux/slab.h> @@ -506,6 +507,10 @@ core_initcall(free_raw_capacity); #endif #if defined(CONFIG_ARM64) || defined(CONFIG_RISCV) + +/* Used to enable the SMT control */ +static unsigned int max_smt_thread_num = 1; + /* * This function returns the logic cpu number of the node. * There are basically three kinds of return values: @@ -565,6 +570,8 @@ static int __init parse_core(struct device_node *core, int package_id, i++; } while (1); + max_smt_thread_num = max_t(unsigned int, max_smt_thread_num, i); + cpu = get_cpu_for_node(core); if (cpu >= 0) { if (!leaf) { @@ -677,6 +684,17 @@ static int __init parse_socket(struct device_node *socket) if (!has_socket) ret = parse_cluster(socket, 0, -1, 0); + /* + * Reset the max_smt_thread_num to 1 on failure. Since on failure + * we need to notify the framework the SMT is not supported, but + * max_smt_thread_num can be initialized to the SMT thread number + * of the cores which are successfully parsed. + */ + if (ret) + max_smt_thread_num = 1; + + cpu_smt_set_num_threads(max_smt_thread_num, max_smt_thread_num); + return ret; }