lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAJZ5v0iUfHQBaXZ65H2nfcwMAyvdw_x5_42z0b8VMvL356kZsA@mail.gmail.com>
Date: Thu, 22 Jan 2026 14:22:39 +0100
From: "Rafael J. Wysocki" <rafael@...nel.org>
To: Yicong Yang <yang.yicong@...oheart.com>
Cc: "Rafael J. Wysocki" <rafael@...nel.org>, lenb@...nel.org, tglx@...nel.org, 
	gregkh@...uxfoundation.org, dakr@...nel.org, akpm@...ux-foundation.org, 
	apatel@...tanamicro.com, pjw@...nel.org, palmer@...belt.com, 
	aou@...s.berkeley.edu, alex@...ti.fr, geshijian@...oheart.com, 
	weidong.wd@...oheart.com, linux-acpi@...r.kernel.org, 
	linux-kernel@...r.kernel.org, linux-riscv@...ts.infradead.org
Subject: Re: [PATCH 1/2] ACPI: scan: Use async schedule function for acpi_scan_clear_dep_fn

On Thu, Jan 22, 2026 at 1:50 PM Yicong Yang <yang.yicong@...oheart.com> wrote:
>
> On 1/22/26 7:19 PM, Rafael J. Wysocki wrote:
> > On Thu, Jan 22, 2026 at 8:35 AM Yicong Yang <yang.yicong@...oheart.com> wrote:
> >>
> >> The device object rescan in acpi_scan_clear_dep_fn is scheduled
> >> in the system workqueue which is not guaranteed to be finished
> >> before entering userspace. This will cause the problem that
> >> some key devices are missed when the init task try to find them,
> >> e.g. console devices and root devices (PCIe nvme, etc).
> >> This issues is more possbile to happen on RISCV since these
> >> devices using GSI interrupt may depend on APLIC and will be
> >> scanned in acpi_scan_clear_dep_queue() after APLIC initialized.
> >>
> >> Fix this by scheduling the acpi_scan_clear_dep_queue() using async
> >> schedule function rather than the system workqueue. The deferred
> >> works will be synchronized by async_synchronize_full() before
> >> entering init task.
> >>
> >> Update the comment as well.
> >>
> >> Signed-off-by: Yicong Yang <yang.yicong@...oheart.com>
> >> ---
> >>  drivers/acpi/scan.c | 35 ++++++++++++++++-------------------
> >>  1 file changed, 16 insertions(+), 19 deletions(-)
> >>
> >> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> >> index 416d87f9bd10..bf0d8ba9ba19 100644
> >> --- a/drivers/acpi/scan.c
> >> +++ b/drivers/acpi/scan.c
> >> @@ -5,6 +5,7 @@
> >>
> >>  #define pr_fmt(fmt) "ACPI: " fmt
> >>
> >> +#include <linux/async.h>
> >>  #include <linux/module.h>
> >>  #include <linux/init.h>
> >>  #include <linux/slab.h>
> >> @@ -2365,39 +2366,35 @@ struct acpi_scan_clear_dep_work {
> >>         struct acpi_device *adev;
> >>  };
> >>
> >> -static void acpi_scan_clear_dep_fn(struct work_struct *work)
> >> +static void acpi_scan_clear_dep_fn(void *dev, async_cookie_t cookie)
> >>  {
> >> -       struct acpi_scan_clear_dep_work *cdw;
> >> -
> >> -       cdw = container_of(work, struct acpi_scan_clear_dep_work, work);
> >> +       struct acpi_device *adev = to_acpi_device(dev);
> >>
> >>         acpi_scan_lock_acquire();
> >> -       acpi_bus_attach(cdw->adev, (void *)true);
> >> +       acpi_bus_attach(adev, (void *)true);
> >>         acpi_scan_lock_release();
> >>
> >> -       acpi_dev_put(cdw->adev);
> >> -       kfree(cdw);
> >> +       acpi_dev_put(adev);
> >>  }
> >>
> >>  static bool acpi_scan_clear_dep_queue(struct acpi_device *adev)
> >>  {
> >> -       struct acpi_scan_clear_dep_work *cdw;
> >> -
> >>         if (adev->dep_unmet)
> >>                 return false;
> >>
> >> -       cdw = kmalloc(sizeof(*cdw), GFP_KERNEL);
> >> -       if (!cdw)
> >> -               return false;
> >> -
> >> -       cdw->adev = adev;
> >> -       INIT_WORK(&cdw->work, acpi_scan_clear_dep_fn);
> >>         /*
> >> -        * Since the work function may block on the lock until the entire
> >> -        * initial enumeration of devices is complete, put it into the unbound
> >> -        * workqueue.
> >> +        * Async schedule the deferred acpi_scan_clear_dep_fn() since:
> >> +        * - acpi_bus_attach() needs to hold acpi_scan_lock which cannot
> >> +        *   be acquired under acpi_dep_list_lock (held here)
> >> +        * - the deferred work at boot stage is ensured to be finished
> >> +        *   before entering init task by the async_synchronize_full()
> >> +        *   barrier
> >> +        *
> >> +        * Use _nocall variant since it'll return on failure instead of
> >> +        * run the function synchronously.
> >>          */
> >> -       queue_work(system_dfl_wq, &cdw->work);
> >> +       if (!async_schedule_dev_nocall(acpi_scan_clear_dep_fn, &adev->dev))
> >
> > If the problem is that system_dfl_wq is too slow, why don't you just
> > try a dedicated workqueue for this?
> >
> > There's no need to modify all of this code.
> >
>
> The problem is that these works are not finished before entering userspace,
> so some key devices like console or PCIe nvme (for root device) is not ready
> in time userspace init running.
>
> If we use a dedicated workqueue we still need to do the synchronization
> somewhere before entering the userspace to solve the problem. But that's just
> what async_schedule* does: queue the function in async_wq (also an unbound one)
> and wait finish before execute init process by async_synchronize_full(). Does
> it make sense?

Well, please see my reply to the other message.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ