[PATCH] dlm: make lockspace join wait killable
From: Nguyen Ngoc Thang
Date: Sat Sep 19 2026 - 13:37:59 EST
do_uevent() sleeps uninterruptibly until dlm_controld answers the
ONLINE uevent via sysfs. If the daemon is absent or stuck, a task
creating a lockspace through /dev/dlm-control blocks forever in D
state, cannot be killed and trips the hung task detector.
Use wait_event_killable() for the join event and return the error to
new_lockspace(), which already unwinds through out_recoverd. The
leave path is left alone as it must not skip teardown.
Reported-by: syzbot+b114bbe890d76037877c@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=b114bbe890d76037877c
Fixes: e7fd41792fc0 ("[DLM] The core of the DLM for GFS2/CLVM")
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@xxxxxxxxx>
---
Problem: syzbot reports "INFO: task hung in do_uevent"
(https://syzkaller.appspot.com/bug?extid=b114bbe890d76037877c).
Cause: creating a lockspace through /dev/dlm-control ends in do_uevent(),
which sends the ONLINE uevent and then sleeps in wait_event() until
dlm_controld writes the result to the sysfs "event_done" file. With no
daemon (or a stuck one) the writer sleeps in TASK_UNINTERRUPTIBLE forever:
SIGKILL has no effect and khungtaskd fires after the timeout.
Fix: use wait_event_killable() for the join event only and return the
error to new_lockspace(), which already unwinds through out_recoverd. The
leave path is unchanged, since it must complete teardown.
Testing (x86_64 QEMU/KVM, lockdep+KASAN, hung_task_timeout=20s): a static
repro configures a local comm in configfs and writes DLM_USER_CREATE_LOCKSPACE
to /dev/dlm-control with no dlm_controld.
before: task stuck in D, hung task splat, still D after SIGKILL.
after: no splat, task exits on SIGKILL, no KASAN/lockdep reports.
Open question: a late "event_done" write racing with the error unwind is
safe because kobject_put() removes the sysfs entry (waiting for active
users) before the lockspace is freed; happy to add an explicit kobject_del()
if you prefer.
fs/dlm/lockspace.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index a9c98b4f378f..5d6a752e6650 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -190,6 +190,7 @@ static int do_uevent(struct dlm_ls *ls, int in, unsigned int release_recover)
{
char message[512] = {};
char *envp[] = { message, NULL };
+ int error;
if (in) {
kobject_uevent(&ls->ls_kobj, KOBJ_ONLINE);
@@ -203,8 +204,16 @@ static int do_uevent(struct dlm_ls *ls, int in, unsigned int release_recover)
/* dlm_controld will see the uevent, do the necessary group management
and then write to sysfs to wake us */
- wait_event(ls->ls_uevent_wait,
- test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
+ if (in) {
+ /* don't hang forever if dlm_controld never answers */
+ error = wait_event_killable(ls->ls_uevent_wait,
+ test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
+ if (error)
+ return error;
+ } else {
+ wait_event(ls->ls_uevent_wait,
+ test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
+ }
log_rinfo(ls, "group event done %d", ls->ls_uevent_result);
--
2.43.0