Re: [PATCH] ACPI: scan: fix bus ID cleanup on device_add() failure

"Rafael J. Wysocki (Intel)" <[email protected]> Fri, 7 Aug 2026 19:38:10 +0200
Newsgroups gmane.linux.acpi.devel
Message-ID <CAJZ5v0gOZK8pgAJyyOLYeX0Ky4hdi6m2o88PP3nQkq8DZbWDsw@mail.gmail.com>
On Tue, Aug 4, 2026 at 5:49 PM Hongyan Xu <[email protected]> wrote:
>
> When device_add() fails after acpi_device_set_name() has allocated an
> instance ID and linked a new acpi_device_bus_id into
> acpi_bus_id_list, the rollback path only removes wakeup_list and
> detaches the ACPI handle data.
>
> That leaves the bus-ID bookkeeping behind and keeps the allocated
> instance number consumed.
>
> Factor the bus-ID removal into a helper, use it from both the normal
> device teardown path and the device_add() rollback path, and only drop
> wakeup_list when it was actually linked.
>
> Found by manual review of reports from the
> kernel70rc2-fail11-retry-20260801 run.
>
> Signed-off-by: Hongyan Xu <[email protected]>
> ---
>  drivers/acpi/scan.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index ff7000b71..852682436 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -520,12 +520,10 @@ static void acpi_device_release(struct device *dev)
>         kfree(acpi_dev);
>  }
>
> -static void acpi_device_del(struct acpi_device *device)
> +static void acpi_device_remove_bus_id(struct acpi_device *device)
>  {
>         struct acpi_device_bus_id *acpi_device_bus_id;
>
> -       mutex_lock(&acpi_device_lock);
> -
>         list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
>                 if (!strcmp(acpi_device_bus_id->bus_id,
>                             acpi_device_hid(device))) {
> @@ -538,8 +536,16 @@ static void acpi_device_del(struct acpi_device *device)
>                         }
>                         break;
>                 }
> +}
>
> -       list_del(&device->wakeup_list);
> +static void acpi_device_del(struct acpi_device *device)
> +{
> +       mutex_lock(&acpi_device_lock);
> +
> +       acpi_device_remove_bus_id(device);
> +
> +       if (device->wakeup.flags.valid)
> +               list_del(&device->wakeup_list);
>
>         mutex_unlock(&acpi_device_lock);
>
> @@ -800,7 +806,9 @@ int acpi_device_add(struct acpi_device *device)
>  err:
>         mutex_lock(&acpi_device_lock);
>
> -       list_del(&device->wakeup_list);
> +       acpi_device_remove_bus_id(device);
> +       if (device->wakeup.flags.valid)
> +               list_del(&device->wakeup_list);

You have exactly the same code sequence in two places, so any chance
to avoid that duplication?

Also, it is not necessary to check device->wakeup.flags.valid before
doing list_del(&device->wakeup_list) if I'm not mistaken.

>
>  err_unlock:
>         mutex_unlock(&acpi_device_lock);
> --