NFSv4: Protect the state recovery thread against direct reclaim
[ Upstream commit 3e17898aca293a24dae757a440a50aa63ca29671 ] If memory allocation triggers a direct reclaim from the state recovery thread, then we can deadlock. Use memalloc_nofs_save/restore to ensure that doesn't happen. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
b37f482ba9
commit
a34752aa23
@ -49,6 +49,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
|
||||
@ -2559,9 +2560,17 @@ static void nfs4_layoutreturn_any_run(struct nfs_client *clp)
|
||||
|
||||
static void nfs4_state_manager(struct nfs_client *clp)
|
||||
{
|
||||
unsigned int memflags;
|
||||
int status = 0;
|
||||
const char *section = "", *section_sep = "";
|
||||
|
||||
/*
|
||||
* State recovery can deadlock if the direct reclaim code tries
|
||||
* start NFS writeback. So ensure memory allocations are all
|
||||
* GFP_NOFS.
|
||||
*/
|
||||
memflags = memalloc_nofs_save();
|
||||
|
||||
/* Ensure exclusive access to NFSv4 state */
|
||||
do {
|
||||
trace_nfs4_state_mgr(clp);
|
||||
@ -2656,6 +2665,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
|
||||
clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
|
||||
}
|
||||
|
||||
memalloc_nofs_restore(memflags);
|
||||
nfs4_end_drain_session(clp);
|
||||
nfs4_clear_state_manager_bit(clp);
|
||||
|
||||
@ -2673,6 +2683,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
|
||||
return;
|
||||
if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
|
||||
return;
|
||||
memflags = memalloc_nofs_save();
|
||||
} while (refcount_read(&clp->cl_count) > 1 && !signalled());
|
||||
goto out_drain;
|
||||
|
||||
@ -2685,6 +2696,7 @@ out_error:
|
||||
clp->cl_hostname, -status);
|
||||
ssleep(1);
|
||||
out_drain:
|
||||
memalloc_nofs_restore(memflags);
|
||||
nfs4_end_drain_session(clp);
|
||||
nfs4_clear_state_manager_bit(clp);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user