[PATCH 0/3] NFS/localio: issue IO inline when not reclaiming memory

Mike Snitzer <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.nfs
Message-ID <[email protected]>
Hi,

Every NFS LOCALIO read, write and commit is currently issued indirectly: it
is queued onto the dedicated !WQ_MEM_RECLAIM nfslocaliod_workqueue rather
than being submitted to the underlying filesystem in the calling context.
That intermediate hop was introduced by commit b9f5dd57f4a5 ("nfs/localio:
use dedicated workqueues for filesystem read and write") because:
LOCALIO submits IO directly into a stacked local filesystem (e.g. XFS)
which may in turn flush its own !WQ_MEM_RECLAIM workqueue. Doing so from a
WQ_MEM_RECLAIM worker -- most importantly writeback's wb_workfn running on
bdi_wq -- or from an explicit PF_MEMALLOC reclaim task trips
check_flush_dependency() and risks a forward-progress deadlock.

However, that hazard only exists when the submitting context is itself a
memory-reclaim context.  For ordinary application/task submission -- e.g.
O_DIRECT, or an fsync-driven commit -- the workqueue hop buys nothing: it
just adds a context switch and scheduling latency per IO and throws away the
NFS client's inherent application-context parallelism.

This series makes the hop conditional.  It adds a small workqueue-core
helper, current_is_workqueue_mem_reclaim(), that reports whether %current is
a WQ_MEM_RECLAIM worker using exactly the predicate check_flush_dependency()
warns on.  LOCALIO uses it (together with the existing PF_MEMALLOC test) in a
new nfs_local_defer_io() helper to decide per-IO whether it must defer to
nfslocaliod_workqueue or may issue the IO inline.  Reclaim contexts still
defer and are unaffected; everything else runs inline.

  Patch 1 adds current_is_workqueue_mem_reclaim() and applies the gating to
          the read and write paths.
  Patch 2 removes never-taken FLUSH_SYNC handling from nfs_local_commit()
          (every caller supplies a FLUSH_SYNC-stripped "how"), which also
          drops the sole user of the ctx->done completion plumbing and the
          now-unused "how" argument.  No functional change.
  Patch 3 extends the same gating to the commit (fsync) path.  Note the
          writeback-triggered commit does reach here in reclaim context --
          nfs_write_inode() (the ->write_inode super_op) runs under wb_workfn
          on the WQ_MEM_RECLAIM bdi_wq -- so that case correctly keeps
          deferring; only app-context commits run inline.

Patch 1 touches the workqueue core (kernel/workqueue.c, include/linux/
workqueue.h), hence the Cc to Tejun Heo, Lai Jiangshan and LKML.  The new
export mirrors the existing current_is_workqueue_rescuer()/current_work()
context-introspection helpers.

Additional note for reviewers:
 - The inline path now stacks the NFS pgio path plus the underlying
   filesystem's ->write_iter/->read_iter (and vfs_fsync_range) in task
   context.  The reclaim-context stack-depth concern of b9f5dd57f4a5 (2) is
   avoided for the deferred paths; feedback on inline stack headroom under
   deeply-stacking filesystems (XFS especially) is welcome.

All review appreciated, thanks.
Mike

Mike Snitzer (3):
  NFS/localio: issue IO inline when not in a memory-reclaim context
  NFS/localio: remove dead FLUSH_SYNC handling from nfs_local_commit
  NFS/localio: issue commit inline when not in a memory-reclaim context

 fs/nfs/internal.h         |  4 +--
 fs/nfs/localio.c          | 56 ++++++++++++++++++++++++++++++---------
 fs/nfs/write.c            |  2 +-
 include/linux/workqueue.h |  1 +
 kernel/workqueue.c        | 24 +++++++++++++++++
 5 files changed, 71 insertions(+), 16 deletions(-)

-- 
2.44.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.