Re: [PATCH] ACPI: processor: Add acpi_processor_start() back to parse _CPC tables before CPU online
"Rafael J. Wysocki (Intel)" <[email protected]>
| Newsgroups | org.kernel.vger.linux-acpi,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAJZ5v0gyQvmyS4gXS-b6HT7arkO0sqt8EgjWBTrWDJ8L-Tp=rA@mail.gmail.com> |
On Wed, Aug 26, 2026 at 10:00 AM Pengjie Zhang <[email protected]> wrote: > > Hi Lifeng, > > On 1/20/2026 7:32 PM, Lifeng Zheng wrote: > > Currently, if boot with maxcpus less than NR_CPUS, the cppc_cpufreq driver > > will fail to register. Because it requires the domain information of all > > possible CPUs to construct shared_cpu_map, which shows the CPUs that share > > the same domain. > > > > Commit c1385c1f0ba3 ("ACPI: processor: Simplify initial onlining to use > > same path for cold and hotplug") removes probe() of acpi_processor_driver > > and makes acpi_cppc_processor_probe() only being called the first time CPU > > goes online. This means that CPUs that haven't yet gone online will not > > have pre-parsed _CPC objects and causes cppc_cpufreq driver register fail. > > > > Add acpi_processor_start() back as the probe() callback of > > acpi_processor_driver and call acpi_cppc_processor_probe() in it to make > > sure all _CPC tables will be parsed when acpi_processor_driver registered. > > > > Fixes: c1385c1f0ba3 ("ACPI: processor: Simplify initial onlining to use same path for cold and hotplug") > > Signed-off-by: Lifeng Zheng <[email protected]> > > --- > > drivers/acpi/processor_driver.c | 30 ++++++++++++++++++++++++++---- > > 1 file changed, 26 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c > > index 65e779be64ff..c8b4daf580b0 100644 > > --- a/drivers/acpi/processor_driver.c > > +++ b/drivers/acpi/processor_driver.c > > @@ -33,6 +33,7 @@ MODULE_AUTHOR("Paul Diefenbaugh"); > > MODULE_DESCRIPTION("ACPI Processor Driver"); > > MODULE_LICENSE("GPL"); > > > > +static int acpi_processor_start(struct device *dev); > > static int acpi_processor_stop(struct device *dev); > > > > static const struct acpi_device_id processor_device_ids[] = { > > @@ -46,6 +47,7 @@ static struct device_driver acpi_processor_driver = { > > .name = "processor", > > .bus = &cpu_subsys, > > .acpi_match_table = processor_device_ids, > > + .probe = acpi_processor_start, > > .remove = acpi_processor_stop, > > }; > > > > @@ -162,10 +164,6 @@ static int __acpi_processor_start(struct acpi_device *device) > > if (!pr) > > return -ENODEV; > > > > - result = acpi_cppc_processor_probe(pr); > > - if (result && !IS_ENABLED(CONFIG_ACPI_CPU_FREQ_PSS)) > > - dev_dbg(&device->dev, "CPPC data invalid or not present\n"); > > - > > if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) > > acpi_processor_power_init(pr); > > > > @@ -192,6 +190,30 @@ static int __acpi_processor_start(struct acpi_device *device) > > return result; > > } > > > > +static int acpi_processor_start(struct device *dev) > > +{ > > + struct acpi_device *device = ACPI_COMPANION(dev); > > + struct acpi_processor *pr; > > + int result; > > + > > + if (!device) > > + return -ENODEV; > > + > > + pr = acpi_driver_data(device); > > + if (!pr) > > + return -ENODEV; > > + > > + /* Protect against concurrent CPU hotplug operations */ > > + cpu_hotplug_disable(); > > + result = acpi_cppc_processor_probe(pr); > > + cpu_hotplug_enable(); > > + > > + if (result && !IS_ENABLED(CONFIG_ACPI_CPU_FREQ_PSS)) > > + dev_dbg(&device->dev, "CPPC data invalid or not present\n"); > > + > > + return 0; > > +} > > + > > static int acpi_processor_stop(struct device *dev) > > { > > struct acpi_device *device = ACPI_COMPANION(dev); > I reproduced the issue described by this patch on the latest kernel at > commit 45c13f3f9e3bb15f. > > On my system, CPU0 and CPU1 belong to the same software-coordinated > frequency domain. After booting with maxcpus=1, CPU1 is present but > offline, and its CPC descriptor is not parsed. > > Consequently, acpi_get_psd_map() skips CPU1 and constructs an > incomplete shared_cpu_map containing only CPU0. > > When CPU1 is subsequently brought online: > > echo 1 > /sys/devices/system/cpu/cpu1/online > > the cpufreq core creates an overlapping policy and attempts to create > the existing cpu0/cpufreq symbolic link again, resulting in the > following warnings: > ... > sysfs_warn_dup > sysfs_do_create_link_sd > sysfs_create_link > add_cpu_dev_symlink > cpufreq_policy_online > cpufreq_online > cpuhp_cpufreq_online > ... > processor cpu0: cpufreq symlink creation failed > > freq_qos_add_request() called for active request > WARNING: kernel/power/qos.c:658 at freq_qos_add_request > > The affected CPU masks are also inconsistent: > > $ cat /sys/devices/system/cpu/cpu0/cpufreq/affected_cpus > 0 > > $ cat /sys/devices/system/cpu/cpu1/cpufreq/affected_cpus > 0 1 > > After applying this patch on top of commit 45c13f3f9e3bb15f, the CPC > descriptors are parsed before the CPUs are brought online. The > shared_cpu_map is constructed correctly, and CPU1 can be brought > online without triggering the duplicate sysfs link or active QoS > request warnings. > > This patch fixes the issue in my testing. so, > > Tested-by: Pengjie Zhang <[email protected]> > Reviewed-by: Pengjie Zhang <[email protected]> Thanks for this information! I'll consider queuing up the patch as a fix for 7.3-rc next week.