All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rafael@kernel.org>
To: Hans de Goede <hdegoede@redhat.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Linux ACPI <linux-acpi@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 5/5] ACPI: scan: Fix race related to dropping dependencies
Date: Wed, 16 Jun 2021 17:19:16 +0200	[thread overview]
Message-ID: <CAJZ5v0hC2Q4M455X4FQ-Z6tzdFkcUgMH_qPHDVV=4O0OcTpBkg@mail.gmail.com> (raw)
In-Reply-To: <a691eab8-51bb-0965-9d17-63d438c43490@redhat.com>

On Wed, Jun 16, 2021 at 4:55 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 6/16/21 4:25 PM, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > If acpi_add_single_object() runs concurrently with respect to
> > acpi_scan_clear_dep() which deletes a dependencies list entry where
> > the device being added is the consumer, the device's dep_unmet
> > counter may not be updated to reflect that change.
> >
> > Namely, if the dependencies list entry is deleted right after
> > calling acpi_scan_dep_init() and before calling acpi_device_add(),
> > acpi_scan_clear_dep() will not find the device object corresponding
> > to the consumer device ACPI handle and it will not update its
> > dep_unmet counter to reflect the deletion of the list entry.
> > Consequently, the dep_unmet counter of the device will never
> > become zero going forward which may prevent it from being
> > completely enumerated.
> >
> > To address this problem, modify acpi_add_single_object() to run
> > acpi_tie_acpi_dev(), to attach the ACPI device object created by it
> > to the corresponding ACPI namespace node, under acpi_dep_list_lock
> > along with acpi_scan_dep_init() whenever the latter is called.
> >
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/acpi/scan.c |   46 +++++++++++++++++++++++++++++++++-------------
> >  1 file changed, 33 insertions(+), 13 deletions(-)
> >
> > Index: linux-pm/drivers/acpi/scan.c
> > ===================================================================
> > --- linux-pm.orig/drivers/acpi/scan.c
> > +++ linux-pm/drivers/acpi/scan.c
> > @@ -657,16 +657,12 @@ static int acpi_tie_acpi_dev(struct acpi
> >       return 0;
> >  }
> >
> > -int acpi_device_add(struct acpi_device *device,
> > -                 void (*release)(struct device *))
> > +int __acpi_device_add(struct acpi_device *device,
> > +                   void (*release)(struct device *))
> >  {
> >       struct acpi_device_bus_id *acpi_device_bus_id;
> >       int result;
> >
> > -     result = acpi_tie_acpi_dev(device);
> > -     if (result)
> > -             return result;
> > -
> >       /*
> >        * Linkage
> >        * -------
> > @@ -755,6 +751,17 @@ err_unlock:
> >       return result;
> >  }
> >
> > +int acpi_device_add(struct acpi_device *adev, void (*release)(struct device *))
> > +{
> > +     int ret;
> > +
> > +     ret = acpi_tie_acpi_dev(adev);
> > +     if (ret)
> > +             return ret;
> > +
> > +     return __acpi_device_add(adev, release);
> > +}
> > +
> >  /* --------------------------------------------------------------------------
> >                                   Device Enumeration
> >     -------------------------------------------------------------------------- */
> > @@ -1681,14 +1688,10 @@ static void acpi_scan_dep_init(struct ac
> >  {
> >       struct acpi_dep_data *dep;
> >
> > -     mutex_lock(&acpi_dep_list_lock);
> > -
> >       list_for_each_entry(dep, &acpi_dep_list, node) {
> >               if (dep->consumer == adev->handle)
> >                       adev->dep_unmet++;
> >       }
> > -
> > -     mutex_unlock(&acpi_dep_list_lock);
> >  }
> >
> >  void acpi_device_add_finalize(struct acpi_device *device)
> > @@ -1707,6 +1710,7 @@ static int acpi_add_single_object(struct
> >                                 acpi_handle handle, int type, bool dep_init)
> >  {
> >       struct acpi_device *device;
> > +     bool release_dep_lock = false;
> >       int result;
> >
> >       device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
> > @@ -1720,16 +1724,32 @@ static int acpi_add_single_object(struct
> >        * this must be done before the get power-/wakeup_dev-flags calls.
> >        */
> >       if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR) {
> > -             if (dep_init)
> > +             if (dep_init) {
> > +                     mutex_lock(&acpi_dep_list_lock);
> > +                     /*
> > +                      * Hold the lock until the acpi_tie_acpi_dev() call
> > +                      * below to prevent concurrent acpi_scan_clear_dep()
> > +                      * from deleting a dependency list entry without
> > +                      * updating dep_unmet for the device.
> > +                      */
> > +                     release_dep_lock = true;
> >                       acpi_scan_dep_init(device);
> > -
> > +             }
> >               acpi_scan_init_status(device);
> >       }
> >
> >       acpi_bus_get_power_flags(device);
> >       acpi_bus_get_wakeup_device_flags(device);
> >
> > -     result = acpi_device_add(device, acpi_device_release);
> > +     result = acpi_tie_acpi_dev(device);
> > +
> > +     if (release_dep_lock)
> > +             mutex_unlock(&acpi_dep_list_lock);
> > +
> > +     if (result)
>
> AFAICT you are missing a "acpi_device_release(&device->dev);"
> call in the error-exit path here, causing a mem-leak.

Indeed.

I'll send a v2 of this patch alone to fix this issue.

> Otherwise this looks good, with the above fixed this is:
>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Thanks!

  reply	other threads:[~2021-06-16 15:19 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-16 14:21 [PATCH 0/5] ACPI: scan: Fixes and cleanups related to dependencies list handling Rafael J. Wysocki
2021-06-16 14:21 ` [PATCH 1/5] ACPI: scan: Rearrange acpi_dev_get_first_consumer_dev_cb() Rafael J. Wysocki
2021-06-16 14:36   ` Hans de Goede
2021-06-16 14:22 ` [PATCH 2/5] ACPI: scan: Make acpi_walk_dep_device_list() Rafael J. Wysocki
2021-06-16 14:41   ` Hans de Goede
2021-06-16 15:11     ` Rafael J. Wysocki
2021-06-16 15:25       ` Rafael J. Wysocki
2021-06-16 15:28       ` Hans de Goede
2021-06-16 14:23 ` [PATCH 3/5] ACPI: scan: Fix device object rescan in acpi_scan_clear_dep() Rafael J. Wysocki
2021-06-16 14:48   ` Hans de Goede
2021-06-16 15:12     ` Rafael J. Wysocki
2021-06-16 14:24 ` [PATCH 4/5] ACPI: scan: Reorganize acpi_device_add() Rafael J. Wysocki
2021-06-16 14:49   ` Hans de Goede
2021-06-16 14:25 ` [PATCH 5/5] ACPI: scan: Fix race related to dropping dependencies Rafael J. Wysocki
2021-06-16 14:55   ` Hans de Goede
2021-06-16 15:19     ` Rafael J. Wysocki [this message]
2021-06-16 18:00   ` [PATCH v2 " Rafael J. Wysocki
2021-06-16 18:04     ` Hans de Goede
2021-06-17  0:25   ` [PATCH " kernel test robot
2021-06-17  0:25     ` kernel test robot
2021-06-17  0:41   ` kernel test robot
2021-06-17  0:41     ` kernel test robot
2021-06-17  0:42   ` [RFC PATCH] ACPI: scan: __acpi_device_add() can be static kernel test robot
2021-06-17  0:42     ` kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJZ5v0hC2Q4M455X4FQ-Z6tzdFkcUgMH_qPHDVV=4O0OcTpBkg@mail.gmail.com' \
    --to=rafael@kernel.org \
    --cc=hdegoede@redhat.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.