mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:09:29 +02:00
NFS/localio: issue commit inline when not in a memory-reclaim context
Extend the memory-reclaim-context test used for LOCALIO reads and writes to the commit (fsync) path. As with data IO, bouncing every commit through the dedicated !WQ_MEM_RECLAIM nfslocaliod_workqueue is only required when the submitting context is a memory-reclaim context: nfs_local_run_commit() calls vfs_fsync_range(), which may flush the underlying filesystem's own !WQ_MEM_RECLAIM workqueue, and doing so from a WQ_MEM_RECLAIM worker or a PF_MEMALLOC task trips check_flush_dependency(). The writeback path does exercise this: nfs_write_inode() (the ->write_inode super_op) runs under wb_workfn on the WQ_MEM_RECLAIM bdi_wq and reaches nfs_local_commit() via __nfs_commit_inode(), so that case must keep deferring. Application-context commits -- fsync (nfs_file_fsync), O_DIRECT (nfs_direct), and copy/clone (nfs42) -- are not in a reclaim context and now run the fsync inline via nfs_local_defer_io(), avoiding the per-commit workqueue hop. Completion (nfs_commit_release_pages -> nfs_commit_end) then runs synchronously in the submitting context; higher layers already cope with this, as __nfs_commit_inode() dispatches the commit async and waits for it separately via wait_on_commit(). Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
committed by
Trond Myklebust
parent
b10c63dcf2
commit
3e05a62a97
+13
-1
@@ -1132,7 +1132,19 @@ int nfs_local_commit(struct nfsd_file *localio,
|
||||
}
|
||||
|
||||
nfs_local_init_commit(data, call_ops);
|
||||
queue_work(nfslocaliod_workqueue, &ctx->work);
|
||||
|
||||
/*
|
||||
* Run the commit (fsync) inline when not in a memory-reclaim context,
|
||||
* rather than bouncing through nfslocaliod_workqueue; see
|
||||
* nfs_local_defer_io(). Completion (nfs_commit_release_pages ->
|
||||
* nfs_commit_end) then runs synchronously, which higher layers cope
|
||||
* with: __nfs_commit_inode() dispatches async and waits via
|
||||
* wait_on_commit().
|
||||
*/
|
||||
if (nfs_local_defer_io())
|
||||
queue_work(nfslocaliod_workqueue, &ctx->work);
|
||||
else
|
||||
nfs_local_fsync_work(&ctx->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user