Re: [PATCH] ACPI: processor: Add acpi_processor_start() back to parse _CPC tables before CPU online

From: Rafael J. Wysocki (Intel)

Date: Wed Aug 26 2026 - 06:40:17 EST


On Wed, Aug 26, 2026 at 10:00 AM Pengjie Zhang <zhangpengjie2@xxxxxxxxxx> 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 <zhenglifeng1@xxxxxxxxxx>
> > ---
> > 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 <zhangpengjie2@xxxxxxxxxx>
> Reviewed-by: Pengjie Zhang <zhangpengjie2@xxxxxxxxxx>

Thanks for this information!

I'll consider queuing up the patch as a fix for 7.3-rc next week.