From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from sg-1-36.ptr.blmpb.com (sg-1-36.ptr.blmpb.com [118.26.132.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B938E33C515 for ; Thu, 22 Jan 2026 13:48:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=118.26.132.36 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769089722; cv=none; b=nVzO0oFn96NMCpbO+4R28RwREVRQq1kSg42e0U7HynLAowj9d+fIIe2lLxWRVdyX9OeoxNGaYuD1P2mZ58Twr+2o1g20BCuvTKN8ck5zQtQSQd+60EzXtdzTrXtFQl+acmiLy0NAJwTFQlb7OQsm3fHvw7dIbMXReYicBeZLZhI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769089722; c=relaxed/simple; bh=MxpgorCASj+kbR070LnJqHrDqVFszt3cTg6nRBtxNuM=; h=From:Subject:Content-Type:In-Reply-To:Date:Message-Id: Mime-Version:References:To:Cc; b=E66Yl7xLeSJBcu10c5bM9Co++Fi/yBQ+AfTSwmYvkPmyQHZtVO1538JQM+iSHeTgs2ItY2YpMoPseQ4pU600gnLF4ylQlvxK73nO5T7AJ9ZKXKToecOPq3Raih/9kBC71E/YSE9Mqr0jThHOxY/c7YzXmsxY7CeFUoNaWWiBaik= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=picoheart.com; spf=pass smtp.mailfrom=picoheart.com; dkim=pass (2048-bit key) header.d=picoheart-com.20200927.dkim.feishu.cn header.i=@picoheart-com.20200927.dkim.feishu.cn header.b=BBucjTdG; arc=none smtp.client-ip=118.26.132.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=picoheart.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=picoheart.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=picoheart-com.20200927.dkim.feishu.cn header.i=@picoheart-com.20200927.dkim.feishu.cn header.b="BBucjTdG" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=s1; d=picoheart-com.20200927.dkim.feishu.cn; t=1769089712; h=from:subject:mime-version:from:date:message-id:subject:to:cc: reply-to:content-type:mime-version:in-reply-to:message-id; bh=TODsxxuFeJVkCe8LIZIipx2CnPyf3RHsGb/quE/s81E=; b=BBucjTdGRUcEiHdHjiy0dSVC07wDwcplPkkGyq/RQkaodyF1LGvvKwOT0z39A6mS2qlXss 18fQtdZ4qcg3daM54DdqymbdZOkaxcYmaO+2wscdo2HxtlfwUKPXvTRJ0nn8X4izneIPst eYD7MTaR+oAGBNewAkJhlInsNCm/kUGa0OtXMs+Ztvi8HLt5qczipENLnt09V7fJeYaGjj hQhP6ocJbP9rS+ayFf0iFDNQ/CLvbfCEQE/mUEvS7mjMQO+UkOdcmEyX+57RCf+MwkWwil 2U2Hwo/uQDq4JgYVTJUH5mg52wPuZrD7KpAEVa8VS031R0qStbKG0JSPzeNgsg== Received: from [172.16.153.176] ([58.250.122.114]) by smtp.feishu.cn with ESMTPS; Thu, 22 Jan 2026 21:48:30 +0800 X-Original-From: Yicong Yang From: "Yicong Yang" Subject: Re: [PATCH 1/2] ACPI: scan: Use async schedule function for acpi_scan_clear_dep_fn User-Agent: Mozilla Thunderbird X-Lms-Return-Path: Content-Type: text/plain; charset=UTF-8 In-Reply-To: Date: Thu, 22 Jan 2026 21:48:27 +0800 Message-Id: <6ac7b51b-376e-4fa9-a7a9-dc0f5da90f64@picoheart.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260122073446.45628-1-yang.yicong@picoheart.com> <20260122073446.45628-2-yang.yicong@picoheart.com> <2026012214-dinginess-improper-9bc1@gregkh> Content-Language: en-US To: "Rafael J. Wysocki" Cc: , "Greg KH" , , , , , , , , , , , , , , Content-Transfer-Encoding: quoted-printable On 1/22/26 9:21 PM, Rafael J. Wysocki wrote: > On Thu, Jan 22, 2026 at 1:43=E2=80=AFPM Yicong Yang wrote: >> >> On 1/22/26 6:29 PM, Greg KH wrote: >>> On Thu, Jan 22, 2026 at 03:34:45PM +0800, Yicong Yang 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 >>>> --- >>>> 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 >>>> #include >>>> #include >>>> #include >>>> @@ -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 =3D container_of(work, struct acpi_scan_clear_dep_work, work)= ; >>>> + struct acpi_device *adev =3D 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 =3D kmalloc(sizeof(*cdw), GFP_KERNEL); >>>> - if (!cdw) >>>> - return false; >>>> - >>>> - cdw->adev =3D 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 un= bound >>>> - * 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= )) >>>> + return false; >>> >>> This really feels wrong to me, you are taking a code path that has been >>> working for quite a while and changing it. Perhaps your system ACPI >>> tables are the thing that is incorrect here? >>> >>> What exactly is the problem that you are seeing? Why not start with >>> that and then we can work out how to solve that issue? >>> >> >> two issues here we met (as briefly mentioned in the commit and cover let= ter): >> 1. kernel panic due to userspace init cannot have an opened console. the >> console device scanning is queued in the system_dfl_wq in above code >> and not finished by the time userspace init process running, thus by >> the time userspace init running, no console is created >> 2. entering rescue shell due to no root devices (PCIe nvme in our case) >> found. same reason as above, the PCIe host bridge scanning is queued >> in above and finished after init process running. >> >> The reason why these devices are created here is because they both depen= d >> on riscv-aplic irqchip to serve their interrupts (console's wired >> interrupt and PCI's INTx interrupts) and in order to keep the dependency >> these devices are scanned and created after riscv-aplic initialized. The >> riscv-aplic is initialized in device_initcall and invoke above codes for >> the scan/creation of these devices, it's close to the time running >> userspace init process. Since system_dfl_wq is used here and no synchron= ized >> mechanism, the issues will happen if userspace init runs before these de= vices >> are ready. >=20 > Well, there is flush_workqueue(), isn't it there? >=20 sure, of course. I implement it using async schedule but open to any better ones. but.. >> Previous solution [1] is to advance the initialization of riscv-aplic >> earlier but the order still cannot be guaranteed conceptually. >> With async_schedule_dev_nocal() the work queued is finished >> before entering userspace init since we'll wait for completion at >> async_synchronize_full() before executing userspace init process. >> >> To solve the issue I think we should make these devices ready before >> entering userspace and async schedule is one way to make it. It's also >> using an unbound workqueue but have additional synchronization. Any >> corrections or suggestions? >=20 > You can flush the dedicated workqueue at the same spot where you do > async_synchronize_full(), can't you? >=20 the async_synchronize_full() is already there in the init code right before entering usersapce [1] so if we use async schedule we don't need to add synchronize spot ourselves. For a dedicated workqueue we need to call flush_workqueue() explicitly somewhere (I suppose to be the last level initcall like late_initcall_sync). Furthermore we need to allocate it and I think not all the platforms need this piece of code. It seems no need to have a dedicated workqueue for this since async schedule can satisfy the needs already (from my view). Except less modifications can be made for this piece of code if we use a dedicated workqueue, is this the consideration and mandatory? [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree= /init/main.c?h=3Dv6.19-rc6#n1580 thanks.