FAILED: patch "[PATCH] NFSv4: Fix a state manager thread deadlock regression" failed to apply to 6.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 956fd46f97d238032cb5fa4771cdaccc6e760f9a
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023100427-labored-staff-0ab4@gregkh' --subject-prefix 'PATCH 6.1.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 956fd46f97d238032cb5fa4771cdaccc6e760f9a Mon Sep 17 00:00:00 2001
From: Trond Myklebust <[email protected]>
Date: Sun, 24 Sep 2023 13:14:15 -0400
Subject: [PATCH] NFSv4: Fix a state manager thread deadlock regression
Commit 4dc73c679114 reintroduces the deadlock that was fixed by commit aeabb3c96186 ("NFSv4: Fix a NFSv4 state manager deadlock") because it prevents the setup of new threads to handle reboot recovery, while the older recovery thread is stuck returning delegations.
fs/nfs/nfs4proc.c +3 -1
@@ -10622,7 +10622,9 @@ static void nfs4_disable_swap(struct inode *inode)*/ struct nfs_client *clp =NFS_SERVER (inode)->nfs_client; -nfs4_schedule_state_manager (clp); +set_bit (NFS4CLNT_RUN_MANAGER , &clp->cl_state); +clear_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state); +wake_up_var (&clp->cl_state); }static const struct inode_operations nfs4_dir_inode_operations = {
fs/nfs/nfs4state.c +26 -12
@@ -1209,16 +1209,26 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) {struct task_struct *task;char buf[INET6_ADDRSTRLEN +sizeof ("-manager" ) +1 ]; +struct rpc_clnt *clnt = clp->cl_rpcclient; +bool swapon = false; -if (clp->cl_rpcclient->cl_shutdown) +if (clnt->cl_shutdown)return ;set_bit (NFS4CLNT_RUN_MANAGER , &clp->cl_state); -if (test_and_set_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state) !=0 ) { -wake_up_var (&clp->cl_state); -return ; + +if (atomic_read (&clnt->cl_swapper)) { + swapon = !test_and_set_bit (NFS4CLNT_MANAGER_AVAILABLE , + &clp->cl_state); +if (!swapon) { +wake_up_var (&clp->cl_state); +return ; + } } -set_bit (NFS4CLNT_MANAGER_RUNNING , &clp->cl_state); + +if (test_and_set_bit (NFS4CLNT_MANAGER_RUNNING , &clp->cl_state) !=0 ) +return ; +__module_get (THIS_MODULE );refcount_inc (&clp->cl_count);
@@ -1235,8 +1245,9 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) __func__, PTR_ERR(task));if (!nfs_client_init_is_complete (clp))nfs_mark_client_ready (clp,PTR_ERR (task)); +if (swapon) +clear_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state);nfs4_clear_state_manager_bit (clp); -clear_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state);nfs_put_client (clp);module_put (THIS_MODULE ); }
@@ -2748,22 +2759,25 @@ static int nfs4_run_state_manager(void *ptr)allow_signal (SIGKILL ); again: -set_bit (NFS4CLNT_MANAGER_RUNNING , &clp->cl_state);nfs4_state_manager (clp); -if (atomic_read (&cl->cl_swapper)) { + +if (test_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state) && + !test_bit (NFS4CLNT_MANAGER_RUNNING , &clp->cl_state)) {wait_var_event_interruptible (&clp->cl_state,test_bit (NFS4CLNT_RUN_MANAGER , &clp->cl_state)); -if (atomic_read (&cl->cl_swapper) && -test_bit (NFS4CLNT_RUN_MANAGER , &clp->cl_state)) +if (!atomic_read (&cl->cl_swapper)) +clear_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state); +if (refcount_read (&clp->cl_count) >1 && !signalled () && + !test_and_set_bit (NFS4CLNT_MANAGER_RUNNING , &clp->cl_state)) goto again;/* Either no longer a swapper, or were signalled */ +clear_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state); } -clear_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state);if (refcount_read (&clp->cl_count) >1 && !signalled () &&test_bit (NFS4CLNT_RUN_MANAGER , &clp->cl_state) && - !test_and_set_bit (NFS4CLNT_MANAGER_AVAILABLE , &clp->cl_state)) + !test_and_set_bit (NFS4CLNT_MANAGER_RUNNING , &clp->cl_state)) goto again;nfs_put_client (clp);