summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZqiang <qiang.zhang@linux.dev>2026-09-01 13:47:14 -0400
committerDavid Teigland <teigland@redhat.com>2026-09-02 11:52:20 -0500
commited9b6a1296f10e4881d93dfe6d76013fbbaeee87 (patch)
treeed534a328dc32fd575204dbdb13575ab1a6d6123
parentb4e6ae7ba711758c38d5eb7d5a7a0712273bdf6f (diff)
dlm: wait for outstanding SRCU callbacks to complete in exit paths
The dlm_lowcomms_exit() and dlm_midcomms_exit() iterate over the srcu protected connection and node hash tables and hand each element to call_srcu() for deferred freeing (connection_release() and midcomms_node_release()). call_srcu() is asynchronous: the callbacks are invoked only after an SRCU grace period, which may happen after the exit function has already returned. These exit functions are reached from exit_dlm() on module unload. Once they return, module teardown continues and the module text may be unloaded while call_srcu() callbacks are still pending. When such a callback finally runs, it executes freed module code and touches the static SRCU domains that are being torn down, resulting in a use-after-free. Add an srcu_barrier() after the call_srcu() loop in each exit function to wait for all outstanding callbacks of the respective SRCU domain to complete before returning. In dlm_midcomms_exit() the barrier is issued before dlm_lowcomms_exit() so that node callbacks are drained prior to tearing down the lower layer. Signed-off-by: Zqiang <qiang.zhang@linux.dev> Acked-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
-rw-r--r--fs/dlm/lowcomms.c1
-rw-r--r--fs/dlm/midcomms.c1
2 files changed, 2 insertions, 0 deletions
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 2aff1c7c17de..ea8353c4638d 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -1984,4 +1984,5 @@ void dlm_lowcomms_exit(void)
}
}
srcu_read_unlock(&connections_srcu, idx);
+ srcu_barrier(&connections_srcu);
}
diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c
index 8964164600d2..045431524494 100644
--- a/fs/dlm/midcomms.c
+++ b/fs/dlm/midcomms.c
@@ -1178,6 +1178,7 @@ void dlm_midcomms_exit(void)
}
}
srcu_read_unlock(&nodes_srcu, idx);
+ srcu_barrier(&nodes_srcu);
dlm_lowcomms_exit();
}