From nobody Sun May 24 19:35:53 2026 Received: from cstnet.cn (smtp21.cstnet.cn [159.226.251.21]) (using TLSv1.2 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A1CD31A9FAF; Sat, 23 May 2026 02:23:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.226.251.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779503017; cv=none; b=HNuq89eN+MTR+4eSD8/KGnmBiqN335oeLToNVNB2hHhcV5q8oi59wJv6TRro8q5xnrGQHgD81xD+tJ+04habNxQT+8UkUeJJIZTX7FYjgkBNbjohQbLbOB3ayaS6k1MBJsHwmsb/2UQ0EtBK8XbhsH8hxmXIk6BZ3qs5tbaEv6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779503017; c=relaxed/simple; bh=p8aFvTyAZakS59hVADNs6H5FFthlR+RJokbXfGT5pDw=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=PnX/Ljke0uHkT+JEvUeLTpfShV2uNkgKCPhrteb/flEvHfNwr0yhE26/B1FPXlVW85yOwMb4vHE8PnzWDGAfLMzig2XVOHaOInYvufkR8JKzCf/6aAjydogrgBeaGhtmOxRiiW2xDhV8pDuqSXVDJpFvZ1i2/D7zYWDpTz0naxA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=mails.ucas.ac.cn; spf=pass smtp.mailfrom=mails.ucas.ac.cn; arc=none smtp.client-ip=159.226.251.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=mails.ucas.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mails.ucas.ac.cn Received: from fric.. (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACHMGyTDxFqub48EQ--.12603S2; Sat, 23 May 2026 10:23:15 +0800 (CST) From: Jiakai Xu To: driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-rt-devel@lists.linux.dev Cc: "Rafael J . Wysocki" , Clark Williams , Colin Cross , Danilo Krummrich , Greg Kroah-Hartman , Len Brown , Pavel Machek , Sebastian Andrzej Siewior , Steven Rostedt , Jiakai Xu Subject: [PATCH v3] PM: sleep: Use complete() in device_pm_sleep_init() and skip no_pm devices in dpm_wait() Date: Sat, 23 May 2026 02:23:14 +0000 Message-Id: <20260523022314.2657232-1-xujiakai24@mails.ucas.ac.cn> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACHMGyTDxFqub48EQ--.12603S2 X-Coremail-Antispam: 1UD129KBjvJXoWxZr4kZr48Wr13ZFy3Wr48Zwb_yoW5Ar4fp3 4q9ayFkw4UWr4vk3Wjq3W8GF15W397CryfCrZYkw1j9wn0gr98tFW5tFW5JFs8Z397ta42 qFWUJw45CFnF9FJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBa14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j 6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gr 1j6F4UJwAac4AC62xK8xCEY4vEwIxC4wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40E FcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr 0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8v x2IErcIFxwACI402YVCY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20x vY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I 3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIx AIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAI cVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2js IEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0JUQvtAUUUUU= X-CM-SenderInfo: 50xmxthndljko6pdxz3voxutnvoduhdfq/ Content-Type: text/plain; charset="utf-8" Replace complete_all() with complete() in device_pm_sleep_init() to allow it to be called in atomic contexts without triggering a false-positive WARNING from lockdep_assert_RT_in_threaded_ctx() when CONFIG_PROVE_RAW_LOCK_NESTING is enabled. device_pm_sleep_init() may be called during device initialization while holding a raw_spinlock (e.g., from within device_initialize()), and complete_all() is unsafe in atomic contexts on PREEMPT_RT kernels. complete(), which is safe to call from any context, is sufficient here. complete_all() sets the completion count to UINT_MAX/2 (permanently signaled), while complete() increments it by 1. Since no threads can be waiting during device initialization, both are functionally equivalent. The completion is always reinitialized via reinit_completion() in dpm_clear_async_state() before each suspend/resume cycle. However, changing to complete() introduces a potential deadlock for devices with no PM support (dev->power.no_pm =3D true). Such devices are never added to the dpm_list and never go through dpm_clear_async_state(), so their completion is never reinitialized. A parent device waiting on a no_pm child across multiple suspend phases would consume the single-use token in the first phase and block forever in the second. Fix this by adding an early return in dpm_wait() when dev->power.no_pm is set, since no_pm devices do not participate in system suspend/resume. Fixes: 152e1d592071 ("PM: Prevent waiting forever on asynchronous resume af= ter failing suspend") Signed-off-by: Jiakai Xu --- V1 -> V2: - Updated dpm_wait() to skip devices with no PM support, as suggested by Rafael J. Wysocki. V2 -> V3: - Revised commit message to clarify that the lockdep warning originates from device_pm_sleep_init() called in atomic context, not from device_pm_remove(). No code changes relative to v2. --- drivers/base/power/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e1b550664bab..ed48c292f575 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -115,7 +115,7 @@ void device_pm_sleep_init(struct device *dev) dev->power.is_noirq_suspended =3D false; dev->power.is_late_suspended =3D false; init_completion(&dev->power.completion); - complete_all(&dev->power.completion); + complete(&dev->power.completion); dev->power.wakeup =3D NULL; INIT_LIST_HEAD(&dev->power.entry); } @@ -252,6 +252,10 @@ static void dpm_wait(struct device *dev, bool async) if (!dev) return; =20 + /* Devices with no PM support don't use the completion. */ + if (dev->power.no_pm) + return; + if (async || (pm_async_enabled && dev->power.async_suspend)) wait_for_completion(&dev->power.completion); } --=20 2.34.1