From: "Jan Sebastian Götte" <linux@jaseg.de>
To: Ulf Hansson <ulfh@kernel.org>, Abel Vesa <abelvesa@kernel.org>
Cc: "Konrad Dybcio" <konrad.dybcio@oss.qualcomm.com>,
linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org,
"Jan Sebastian Götte" <linux@jaseg.de>,
stable@vger.kernel.org
Subject: [PATCH v2] pmdomain: core: Wait for device link removals before dropping genpd->dev
Date: Fri, 31 Jul 2026 15:10:02 +0200 [thread overview]
Message-ID: <20260731131002.142671-1-linux@jaseg.de> (raw)
In-Reply-To: <ivkwuomer5vsajf2lq6otpgxwqljkwooh3p7e5ne23j37pv22t@iluamo6gxmq3>
genpd->dev is embedded in struct generic_pm_domain and its release
function is empty, so providers free the containing genpd with a plain
kfree() once of_genpd_remove_last() returns, ignoring its refcount.
Since genpd->dev is registered on the genpd provider bus, fw_devlink
creates device links to it, and those are torn down asynchronously.
Nothing made genpd_remove() wait for those teardowns, so the provider
could free the memory backing genpd->dev while the queued workers still
used it.
This is reachable at boot on qrb2210, where the firmware rejects PC mode
and psci_cpuidle_domain_probe() removes all the CPU PM domains before
returning -EPROBE_DEFER. The bug is asymptomatic on defconfig, but shows
up when enabling KASAN or INIT_ON_FREE_DEFAULT_ON. In some builds, it
causes the kernel to crash a few hundred ms into the boot.
Call device_link_wait_removal() before dropping the final reference. All
link removal work is queued from device_del(), via
device_links_driver_cleanup() and device_links_purge(), which precedes
genpd_free_data(), and flush_workqueue() waits for it to complete.
Assisted-by: Claude:claude-5-opus
Fixes: 18a3a510ecfd ("pmdomain: core: Add the genpd->dev to the genpd provider bus")
Cc: stable@vger.kernel.org
Signed-off-by: Jan Sebastian Götte <linux@jaseg.de>
---
v2: remove this note from the commit text.
Note: This patch was LLM-assisted. I reproduced the issue and tested
this patch on hardware, and I did my best to verify it by hand. However,
I'm far from an expert in pmdomain, so YMMV.
drivers/pmdomain/core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 842c4169e290..4eeb980e5a40 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2348,6 +2348,9 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
static void genpd_free_data(struct generic_pm_domain *genpd)
{
+ /* Pending device link removals still reference genpd->dev. */
+ device_link_wait_removal();
+
put_device(&genpd->dev);
if (genpd->device_id != -ENXIO)
ida_free(&genpd_ida, genpd->device_id);
--
2.53.0
prev parent reply other threads:[~2026-07-31 13:10 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 10:21 [PATCH] pmdomain: core: Wait for device link removals before dropping genpd->dev jaseg
2026-07-31 11:35 ` Konrad Dybcio
2026-07-31 12:10 ` Abel Vesa
2026-07-31 13:10 ` Jan Sebastian Götte [this message]
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=20260731131002.142671-1-linux@jaseg.de \
--to=linux@jaseg.de \
--cc=abelvesa@kernel.org \
--cc=konrad.dybcio@oss.qualcomm.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=ulfh@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox