Re: [PATCH] ACPI: processor: Add acpi_processor_start() back to parse _CPC tables before CPU online
Pengjie Zhang <[email protected]>
| Newsgroups | org.kernel.vger.linux-acpi,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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]>