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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.