From: James Morse james.morse@arm.com
mainline inclusion from mainline-v6.8-rc1 commit c72bbf200162a3b4b9e1baedec9008d8d710b427 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8XMTL CVE: NA
----------------------------------
register_cpu_capacity_sysctl() adds a property to sysfs that describes the CPUs capacity. This is done from a subsys_initcall() that assumes all possible CPUs are registered.
With CPU hotplug, possible CPUs aren't registered until they become present, (or for arm64 enabled). This leads to messages during boot: | register_cpu_capacity_sysctl: too early to get CPU1 device! and once these CPUs are added to the system, the file is missing.
Move this to a cpuhp callback, so that the file is created once CPUs are brought online. This covers CPUs that are added late by mechanisms like hotplug. One observable difference is the file is now missing for offline CPUs.
Signed-off-by: James Morse james.morse@arm.com Reviewed-by: Gavin Shan gshan@redhat.com Signed-off-by: "Russell King (Oracle)" rmk+kernel@armlinux.org.uk Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/E1r5R2g-00CsyV-Ss@rmk-PC.armlinux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: liwei liwei728@huawei.com --- drivers/base/arch_topology.c | 38 ++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index b741b5ba82bd..9ccb7daee78e 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -220,20 +220,34 @@ static DECLARE_WORK(update_topology_flags_work, update_topology_flags_workfn);
static DEVICE_ATTR_RO(cpu_capacity);
-static int register_cpu_capacity_sysctl(void) +static int cpu_capacity_sysctl_add(unsigned int cpu) { - int i; - struct device *cpu; + struct device *cpu_dev = get_cpu_device(cpu);
- for_each_possible_cpu(i) { - cpu = get_cpu_device(i); - if (!cpu) { - pr_err("%s: too early to get CPU%d device!\n", - __func__, i); - continue; - } - device_create_file(cpu, &dev_attr_cpu_capacity); - } + if (!cpu_dev) + return -ENOENT; + + device_create_file(cpu_dev, &dev_attr_cpu_capacity); + + return 0; +} + +static int cpu_capacity_sysctl_remove(unsigned int cpu) +{ + struct device *cpu_dev = get_cpu_device(cpu); + + if (!cpu_dev) + return -ENOENT; + + device_remove_file(cpu_dev, &dev_attr_cpu_capacity); + + return 0; +} + +static int register_cpu_capacity_sysctl(void) +{ + cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "topology/cpu-capacity", + cpu_capacity_sysctl_add, cpu_capacity_sysctl_remove);
return 0; }