From: Guixin Liu <kanie@linux.alibaba.com>
To: Davidlohr Bueso <dave@stgolabs.net>,
Jonathan Cameron <jic23@kernel.org>,
Dave Jiang <dave.jiang@intel.com>,
Alison Schofield <alison.schofield@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Dan Williams <djbw@kernel.org>, Ira Weiny <iweiny@kernel.org>,
Li Ming <ming.li@zohomail.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Danilo Krummrich <dakr@kernel.org>,
Shaikh Kamaluddin <shaikhkamal2012@gmail.com>
Cc: linux-cxl@vger.kernel.org, driver-core@lists.linux.dev
Subject: [PATCH v2 2/2] cxl/memdev: Fix deadlock between poison debugfs and cxl_mem unbind
Date: Mon, 31 Aug 2026 20:48:09 +0800 [thread overview]
Message-ID: <20260831124809.889829-3-kanie@linux.alibaba.com> (raw)
In-Reply-To: <20260831124809.889829-1-kanie@linux.alibaba.com>
The poison debugfs handlers take the memdev device lock so that the
region lookup sees a stable cxlmd->dev.driver. debugfs holds a reference
on the file across the handler, and cxl_mem unbind removes that file
while holding the very same device lock, so a handler that waits for the
lock deadlocks against a concurrent unbind.
Both tasks then hang. The unbind side is uninterruptible, and it also
blocks the memdev detach work, which runs on an ordered workqueue and so
stalls every other CXL bus work item.
Take the lock with the trylock guard and return -EBUSY instead of
waiting. An unbind that wins the race removes the file first and the
write fails with -ENOENT.
Found by code inspection. Reproduced by writing inject_poison in a loop
while unbinding and rebinding cxl_mem, and confirmed fixed by the same
test.
Fixes: 574eda81d0a7 ("cxl/memdev: Hold memdev lock during memdev poison injection/clear")
Suggested-by: Shaikh Kamaluddin <shaikhkamal2012@gmail.com>
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
checkpatch reports "do not use assignment in if condition" twice, on the
two ACQUIRE_ERR() lines. Those are pre-existing: the unpatched file and
the Fixes: commit report the same two, this patch only swaps the lock
class on them, and the combined form is what all 40 ACQUIRE_ERR() call
sites in drivers/cxl use.
drivers/cxl/mem.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 798e5c369cfc..3959ec963026 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -50,8 +50,13 @@ static int cxl_debugfs_poison_inject(void *data, u64 dpa)
struct cxl_memdev *cxlmd = data;
int rc;
- ACQUIRE(device_intr, devlock)(&cxlmd->dev);
- if ((rc = ACQUIRE_ERR(device_intr, &devlock)))
+ /*
+ * Never wait for this lock: the debugfs proxy holds a file reference
+ * across the callback and unbind removes the file under the same
+ * device lock, so waiting here deadlocks against unbind.
+ */
+ ACQUIRE(device_try, devlock)(&cxlmd->dev);
+ if ((rc = ACQUIRE_ERR(device_try, &devlock)))
return rc;
return cxl_inject_poison(cxlmd, dpa);
@@ -65,8 +70,9 @@ static int cxl_debugfs_poison_clear(void *data, u64 dpa)
struct cxl_memdev *cxlmd = data;
int rc;
- ACQUIRE(device_intr, devlock)(&cxlmd->dev);
- if ((rc = ACQUIRE_ERR(device_intr, &devlock)))
+ /* Never wait, per the inject path above. */
+ ACQUIRE(device_try, devlock)(&cxlmd->dev);
+ if ((rc = ACQUIRE_ERR(device_try, &devlock)))
return rc;
return cxl_clear_poison(cxlmd, dpa);
--
2.43.7
prev parent reply other threads:[~2026-08-31 12:48 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 12:48 [PATCH v2 0/2] cxl/memdev: Fix poison debugfs vs unbind deadlock Guixin Liu
2026-08-31 12:48 ` [PATCH v2 1/2] driver core: Add conditional guard support for device_trylock() Guixin Liu
2026-08-31 12:48 ` Guixin Liu [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=20260831124809.889829-3-kanie@linux.alibaba.com \
--to=kanie@linux.alibaba.com \
--cc=alison.schofield@intel.com \
--cc=dakr@kernel.org \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=djbw@kernel.org \
--cc=driver-core@lists.linux.dev \
--cc=gregkh@linuxfoundation.org \
--cc=iweiny@kernel.org \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=ming.li@zohomail.com \
--cc=rafael@kernel.org \
--cc=shaikhkamal2012@gmail.com \
--cc=vishal.l.verma@intel.com \
/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