]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dlm: use hlist_for_each_entry_srcu for SRCU protected lists
authorLi RongQing <lirongqing@baidu.com>
Mon, 27 Apr 2026 15:59:32 +0000 (11:59 -0400)
committerDavid Teigland <teigland@redhat.com>
Fri, 8 May 2026 13:38:03 +0000 (08:38 -0500)
The connection and node hash tables in DLM are protected by SRCU, but
the code currently uses hlist_for_each_entry_rcu() for traversal.
While this works functionally, it is semantically incorrect and triggers
warnings when RCU lockdep debugging is enabled, as it expects regular
RCU read-side critical sections.

This patch replaces the incorrect macros with hlist_for_each_entry_srcu()
and adds the appropriate lockdep expressions using srcu_read_lock_held()
to ensure consistency with the underlying locking mechanism.

Signed-off-by: Li RongQing <lirongqing@baidu.com>
Acked-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
fs/dlm/lowcomms.c
fs/dlm/midcomms.c

index 5b6142787919534398c8340fdb36e1024d5a9ad0..2aff1c7c17de49c41f9fd02a1fae00bcc9e6af5b 100644 (file)
@@ -271,7 +271,8 @@ static struct connection *__find_con(int nodeid, int r)
 {
        struct connection *con;
 
-       hlist_for_each_entry_rcu(con, &connection_hash[r], list) {
+       hlist_for_each_entry_srcu(con, &connection_hash[r], list,
+                       srcu_read_lock_held(&connections_srcu)) {
                if (con->nodeid == nodeid)
                        return con;
        }
@@ -426,7 +427,8 @@ static int addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid,
 
        idx = srcu_read_lock(&connections_srcu);
        for (i = 0; i < CONN_HASH_SIZE; i++) {
-               hlist_for_each_entry_rcu(con, &connection_hash[i], list) {
+               hlist_for_each_entry_srcu(con, &connection_hash[i], list,
+                               srcu_read_lock_held(&connections_srcu)) {
                        WARN_ON_ONCE(!con->addr_count);
 
                        spin_lock(&con->addrs_lock);
@@ -1729,7 +1731,8 @@ void dlm_lowcomms_shutdown(void)
 
        idx = srcu_read_lock(&connections_srcu);
        for (i = 0; i < CONN_HASH_SIZE; i++) {
-               hlist_for_each_entry_rcu(con, &connection_hash[i], list) {
+               hlist_for_each_entry_srcu(con, &connection_hash[i], list,
+                               srcu_read_lock_held(&connections_srcu)) {
                        shutdown_connection(con, true);
                        stop_connection_io(con);
                        flush_workqueue(process_workqueue);
@@ -1968,7 +1971,8 @@ void dlm_lowcomms_exit(void)
 
        idx = srcu_read_lock(&connections_srcu);
        for (i = 0; i < CONN_HASH_SIZE; i++) {
-               hlist_for_each_entry_rcu(con, &connection_hash[i], list) {
+               hlist_for_each_entry_srcu(con, &connection_hash[i], list,
+                               srcu_read_lock_held(&connections_srcu)) {
                        spin_lock(&connections_lock);
                        hlist_del_rcu(&con->list);
                        spin_unlock(&connections_lock);
index d54bdd8fc4f2ed9d9051534f8d3603e14e330fed..a5b363b4785f334bb35cb2f63d2267322271e76f 100644 (file)
@@ -275,7 +275,8 @@ static struct midcomms_node *__find_node(int nodeid, int r)
 {
        struct midcomms_node *node;
 
-       hlist_for_each_entry_rcu(node, &node_hash[r], hlist) {
+       hlist_for_each_entry_srcu(node, &node_hash[r], hlist,
+                       srcu_read_lock_held(&nodes_srcu)) {
                if (node->nodeid == nodeid)
                        return node;
        }
@@ -1165,7 +1166,8 @@ void dlm_midcomms_exit(void)
 
        idx = srcu_read_lock(&nodes_srcu);
        for (i = 0; i < CONN_HASH_SIZE; i++) {
-               hlist_for_each_entry_rcu(node, &node_hash[i], hlist) {
+               hlist_for_each_entry_srcu(node, &node_hash[i], hlist,
+                               srcu_read_lock_held(&nodes_srcu)) {
                        dlm_delete_debug_comms_file(node->debugfs);
 
                        spin_lock(&nodes_lock);
@@ -1325,7 +1327,8 @@ void dlm_midcomms_version_wait(void)
 
        idx = srcu_read_lock(&nodes_srcu);
        for (i = 0; i < CONN_HASH_SIZE; i++) {
-               hlist_for_each_entry_rcu(node, &node_hash[i], hlist) {
+               hlist_for_each_entry_srcu(node, &node_hash[i], hlist,
+                               srcu_read_lock_held(&nodes_srcu)) {
                        ret = wait_event_timeout(node->shutdown_wait,
                                                 node->version != DLM_VERSION_NOT_SET ||
                                                 node->state == DLM_CLOSED ||
@@ -1396,7 +1399,8 @@ void dlm_midcomms_shutdown(void)
        mutex_lock(&close_lock);
        idx = srcu_read_lock(&nodes_srcu);
        for (i = 0; i < CONN_HASH_SIZE; i++) {
-               hlist_for_each_entry_rcu(node, &node_hash[i], hlist) {
+               hlist_for_each_entry_srcu(node, &node_hash[i], hlist,
+                               srcu_read_lock_held(&nodes_srcu)) {
                        midcomms_shutdown(node);
                }
        }
@@ -1404,7 +1408,8 @@ void dlm_midcomms_shutdown(void)
        dlm_lowcomms_shutdown();
 
        for (i = 0; i < CONN_HASH_SIZE; i++) {
-               hlist_for_each_entry_rcu(node, &node_hash[i], hlist) {
+               hlist_for_each_entry_srcu(node, &node_hash[i], hlist,
+                               srcu_read_lock_held(&nodes_srcu)) {
                        midcomms_node_reset(node);
                }
        }