]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
NFSv4: Avoid unnecessary scans of filesystems for returning delegations
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Tue, 18 Feb 2025 23:14:26 +0000 (18:14 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Apr 2025 12:39:24 +0000 (14:39 +0200)
[ Upstream commit 35a566a24e58f1b5f89737edf60b77de58719ed0 ]

The amount of looping through the list of delegations is occasionally
leading to soft lockups. If the state manager was asked to return
delegations asynchronously, it should only scan those filesystems that
hold delegations that need to be returned.

Fixes: af3b61bf6131 ("NFSv4: Clean up nfs_client_return_marked_delegations()")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/delegation.c
include/linux/nfs_fs_sb.h

index df77d68d9ff99192524e43566c7cc759801ba1d2..d1f5e497729c3b5fbdb6b4dbfa601017c9d7bf35 100644 (file)
@@ -79,6 +79,7 @@ static void nfs_mark_return_delegation(struct nfs_server *server,
                                       struct nfs_delegation *delegation)
 {
        set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
+       set_bit(NFS4SERV_DELEGRETURN, &server->delegation_flags);
        set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
 }
 
@@ -608,6 +609,9 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server,
        struct nfs_delegation *place_holder_deleg = NULL;
        int err = 0;
 
+       if (!test_and_clear_bit(NFS4SERV_DELEGRETURN,
+                               &server->delegation_flags))
+               return 0;
 restart:
        /*
         * To avoid quadratic looping we hold a reference
@@ -659,6 +663,7 @@ restart:
                cond_resched();
                if (!err)
                        goto restart;
+               set_bit(NFS4SERV_DELEGRETURN, &server->delegation_flags);
                set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
                goto out;
        }
index b804346a974195927de579e67369cfd5e6054c78..98fc10ee0b86943c535c63fc9178de9f0849e1e4 100644 (file)
@@ -251,6 +251,8 @@ struct nfs_server {
        struct list_head        ss_copies;
        struct list_head        ss_src_copies;
 
+       unsigned long           delegation_flags;
+#define NFS4SERV_DELEGRETURN           (1)
        unsigned long           delegation_gen;
        unsigned long           mig_gen;
        unsigned long           mig_status;