From nobody Sat Feb 7 05:49:08 2026 Received: from sg-1-33.ptr.blmpb.com (sg-1-33.ptr.blmpb.com [118.26.132.33]) (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 90449353EC7 for ; Wed, 28 Jan 2026 13:28:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=118.26.132.33 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769606942; cv=none; b=mmHDU2B30CYjyDsFUGVBSuuDtf3elPcLr7HHwrz2tzRWgtTQtzbbFI5qyLrC+4+2PgDF5ibZIipahlmvdEpz3BobF9BIJST1zxZjxef2w/07d9S0OUWDp0oWcTNmjwMe5bjQL4pgD3ajnCdrFSgc/RYEXCgrJ9qWXXpyoHJEoPk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769606942; c=relaxed/simple; bh=2QK1ViLbJ87FLD0VE6w+dGmaUX+pzVccBNJjH2+u7CY=; h=Subject:To:Mime-Version:Message-Id:Content-Type:Cc:Date:From; b=qaw+6Iuj1GCdtaIZCl4niYBVzHbzrEBj5sS56Z/Jpavv074CPdWsha0S5x5dgIbz8swvBo6FHoR6xZUPZaoP1hvHkym6hV/tBAOnFvjan4y7bPMNvkodzf68RteaP3I7FFf1CM6ADzRM9+Sp5GF5zGEc6/gN6V69+kr1BpCfveQ= 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=dJ5Egclq; arc=none smtp.client-ip=118.26.132.33 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="dJ5Egclq" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=s1; d=picoheart-com.20200927.dkim.feishu.cn; t=1769606933; h=from:subject:mime-version:from:date:message-id:subject:to:cc: reply-to:content-type:mime-version:in-reply-to:message-id; bh=vcYXwx5F8javVvZgh4a7pvf8s/p2JUmWBU4iY67rl4o=; b=dJ5Egclq4+OLZhTBlMWeH/6/xatwYPvi9J2nvaFQG/r2BfXtkB5CxJHe6vuNLaNAbqlc2Q b/FSXMYIBerFScFxW+QkI69xifIY05cXq9sue6YCDUyHPKXGC4znbsum/qMB5gBhltCFNi rR7KAvB98PiGCPyGQ8RUcj9WGOgOc82s/1KcZwWvA8a4JAS8BBO/jMxS4afjOx6SghIPdp 0xZHibfqvSOEwNVDILEm7isagquvSME2nCHsJK1petQfjQBgjQVeDkm+GI2xg7RSHHzEjy +XzMIrapUWir67/DhspuwTfgqO26tbKiWaAzI4Rg7koj0X2+cJzp6ljuxthj5A== Subject: [PATCH v3] ACPI: scan: Use async schedule function for acpi_scan_clear_dep_fn To: , , , , X-Original-From: Yicong Yang X-Lms-Return-Path: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Message-Id: <20260128132848.93638-1-yang.yicong@picoheart.com> Content-Transfer-Encoding: quoted-printable Cc: , , , , , , , , , , , Date: Wed, 28 Jan 2026 21:28:47 +0800 X-Mailer: git-send-email 2.50.1 Received: from G9WYR9K0VW ([58.250.122.114]) by smtp.feishu.cn with ESMTPS; Wed, 28 Jan 2026 21:28:50 +0800 From: "Yicong Yang" Content-Type: text/plain; charset="utf-8" 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 missing when userspace init task tries to find them. Two issues observed on our RISCV platforms: - kernel panic due to userspace init cannot have an opened console. the console device scanning is queued by acpi_scan_clear_dep_queue and not finished by the time userspace init process running, thus by the time userspace init running, no console is created - 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 is because both devices (console, PCIe host bridge) depend on riscv-aplic irqchip to serve their interrupts (console's wired interrupt and PCI's INTx interrupts). 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 queue the device scan work with acpi_scan_clear_dep_queue, it's close to the time running userspace init process. Since system_dfl_wq is used in acpi_scan_clear_dep_queue and no synchronization, the issues will happen if userspace init runs before these devices are ready. The solution is to wait for the queued work finished before entering userspace init. One possible way is to use a dedicated workqueue instead of the system_dfl_wq, and explicitly flush it somewhere in the initcall stage before entering userspace. One other way is to use async_schedule_dev_nocall() for these device scanning. It's designed for asynchronous initialization and will work same as before since it's using a dedicated unbound workqueue as well, but the kernel init code will wait for the work finished (async_synchronize_full) right before entering userspace init. This patch use the second approach. Compared to a dedicated workqueue, it's simpler since the async schedule framework have handled most works like synchronization, memory allocation of works and workqueue. The ACPI code only needs to focus on its work. A dedicated workqueue for this could also be redundant since some platforms don't need acpi_scan_clear_dep_queue() for their device scanning. Signed-off-by: Yicong Yang --- Change since v2: - minor code cleanup for return path per Rafael Link: https://lore.kernel.org/all/20260126070427.64574-1-yang.yicong@picohe= art.com/ Change since v1: Refine the commit message to: - include the issues and the analysis - include the reason for using the async schedule rather than a dedicated workqueue Link: https://lore.kernel.org/linux-riscv/20260122073446.45628-2-yang.yicon= g@picoheart.com/ drivers/acpi/scan.c | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 416d87f9bd10..b78f6be2f946 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -5,6 +5,7 @@ =20 #define pr_fmt(fmt) "ACPI: " fmt =20 +#include #include #include #include @@ -2360,46 +2361,34 @@ static int acpi_dev_get_next_consumer_dev_cb(struct= acpi_dep_data *dep, void *da return 0; } =20 -struct acpi_scan_clear_dep_work { - struct work_struct 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); =20 acpi_scan_lock_acquire(); - acpi_bus_attach(cdw->adev, (void *)true); + acpi_bus_attach(adev, (void *)true); acpi_scan_lock_release(); =20 - acpi_dev_put(cdw->adev); - kfree(cdw); + acpi_dev_put(adev); } =20 static bool acpi_scan_clear_dep_queue(struct acpi_device *adev) { - struct acpi_scan_clear_dep_work *cdw; - if (adev->dep_unmet) return false; =20 - 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 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 userspace 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); - - return true; + return async_schedule_dev_nocall(acpi_scan_clear_dep_fn, &adev->dev); } =20 static void acpi_scan_delete_dep_data(struct acpi_dep_data *dep) --=20 2.34.1