Linux NFS development
 help / color / mirror / Atom feed
From: Mike Snitzer <snitzer@kernel.org>
To: Anna Schumaker <anna@kernel.org>
Cc: Trond Myklebust <trondmy@kernel.org>, linux-nfs@vger.kernel.org
Subject: Re: [PATCH 3/3] NFS/localio: give the LOCALIO probe a short timeout of its own
Date: Mon, 9 Nov 2026 10:10:23 -0500	[thread overview]
Message-ID: <avHiX4PgUIEQFbX2@kernel.org> (raw)
In-Reply-To: <c8f51ae8-9b07-4187-ab11-349322f636b2@app.fastmail.com>

On Fri, Nov 06, 2026 at 05:02:09PM -0500, Anna Schumaker wrote:
> 
> 
> On Mon, Nov 2, 2026, at 4:52 PM, Mike Snitzer wrote:
> > The LOCALIO probe clones the NFS client with rpc_bind_new_program(),
> > which NULL-pings the new program before the probe sends UUID_IS_LOCAL.
> > Both calls use the mount's timeout.  With timeo=600 and the default
> > retrans, a server that does not answer the LOCALIO program holds each
> > probe for about 170 s.  The client then logs "nfslocalio: server ... not
> > responding, timed out".  On such a server, one mkdir took about 170 s
> > of a 202 s run and ended when the probe gave up.
> >
> > Give the probe a soft timeout of its own, with no retries and no log
> > message.  The new nfs module parameter localio_timeout sets it in
> > seconds, 10 by default and at most 600.  Set it on a private clone of
> > the NFS client before rpc_bind_new_program(), so that the ping uses it
> > as well.  Clear cl_noretranstimeo, which NFSv4 mounts set, because with
> > it a sent call does not time out while the connection stays up.  With
> > localio_timeout set to 0, the probe uses the NFS client's timeouts, as
> > before.  The probe still shares the NFS client's transport and runs
> > beside its RPCs.  The NFS client's own timeouts do not change.
> >
> > Tested through a proxy that drops every call to the LOCALIO program:
> > the probe gave up after 10.6 s and logged nothing.  With
> > localio_timeout=0 it took 182.9 s and logged the message above.  The
> > probe still succeeds against a server that supports LOCALIO: with no
> > proxy, a 64 MiB O_DIRECT write through LOCALIO sent no WRITE RPCs.
> >
> > Signed-off-by: Mike Snitzer <snitzer@kernel.org>
> > ---
> >  Documentation/filesystems/nfs/localio.rst |  9 ++++
> >  fs/nfs/localio.c                          | 54 +++++++++++++++++++++--
> >  2 files changed, 60 insertions(+), 3 deletions(-)
> >
> > diff --git a/Documentation/filesystems/nfs/localio.rst 
> > b/Documentation/filesystems/nfs/localio.rst
> > index e8f44332cc806..45c6981da0d89 100644
> > --- a/Documentation/filesystems/nfs/localio.rst
> > +++ b/Documentation/filesystems/nfs/localio.rst
> > @@ -316,6 +316,15 @@ It is checked on every I/O: setting it to N sends 
> > the next I/O of every
> >  client over the network, and setting it back to Y resumes LOCALIO.  A
> >  client that probed while it was N is probed again when it is set to Y.
> > 
> > +/sys/module/nfs/parameters/localio_timeout (uint)
> > +sets how many seconds the LOCALIO probe waits for each reply from the
> > +server, defaults to 10, at most 600.  A server that does not support
> > +LOCALIO may not answer the probe at all.  If no reply comes in time,
> > +the probe gives up without a log message.  The client then does not use
> > +LOCALIO.  The mount's timeouts do not apply to the probe.  Set to 0, the
> > +probe uses the mount's timeouts instead, as an NFS RPC would.  A change
> > +applies to the next probe.
> > +
> >  /sys/module/nfs/parameters/localio_O_DIRECT_semantics (bool)
> >  controls if O_DIRECT extends down to the underlying filesystem, defaults
> >  to N. Application IO must be logical blocksize aligned, otherwise
> > diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
> > index 80a496d6fe0d6..06d0755b1f203 100644
> > --- a/fs/nfs/localio.c
> > +++ b/fs/nfs/localio.c
> > @@ -82,6 +82,22 @@ static const struct kernel_param_ops localio_enabled_ops = {
> >  };
> >  module_param_cb(localio_enabled, &localio_enabled_ops, &localio_enabled, 0644);
> > 
> > +/* Seconds the LOCALIO probe waits for each reply; 0: the NFS client's 
> > own */
> 
> I'm having trouble parsing this. What does '0' mean here?
> 
> Thanks,
> Anna

Sorry about that, not sure what happened.  But how 0 is handled is
documented in localio.rst (above) and in the comment above
nfs_init_localioclient() (below).  In any case, this comment can be:

  /*
   * Seconds the LOCALIO probe waits for each reply.  With 0, the probe uses
   * the NFS client's timeouts instead.
   */

Can you fold this in or should I send v2?

Thanks,
Mike


> > @@ -156,13 +172,45 @@ const struct rpc_program nfslocalio_program = {
> > 
> >  /*
> >   * nfs_init_localioclient - Initialise an NFS localio client connection
> > + *
> > + * A server that does not support LOCALIO may not answer its RPCs at all.
> > + * The probe shares the NFS client's transport and runs beside its RPCs.
> > + * With localio_timeout set, it gets a quiet, soft timeout of that many
> > + * seconds of its own, whatever timeouts the mount uses.  With 0, it uses
> > + * the NFS client's timeouts, as an NFS RPC would.
> >   */
> >  static struct rpc_clnt *nfs_init_localioclient(struct nfs_client *clp)
> >  {
> > -	struct rpc_clnt *rpcclient_localio;
> > +	unsigned int timeout_secs = READ_ONCE(localio_timeout);
> > +	struct rpc_clnt *parent = clp->cl_rpcclient;
> > +	struct rpc_clnt *probe = NULL, *rpcclient_localio;
> > 
> > -	rpcclient_localio = rpc_bind_new_program(clp->cl_rpcclient,
> > -						 &nfslocalio_program, 1);
> > +	/*
> > +	 * rpc_bind_new_program() pings the new program with the timeout of
> > +	 * the client it clones, so set the probe's timeout on a private
> > +	 * clone first.  The clone's cl_timeout points at the transport's
> > +	 * timeout: give it its own copy rather than write through it.
> > +	 */
> > +	if (timeout_secs) {
> > +		probe = rpc_clone_client(parent);
> > +		if (IS_ERR(probe))
> > +			return probe;
> > +		probe->cl_timeout_default = (struct rpc_timeout) {
> > +			.to_initval	= timeout_secs * HZ,
> > +			.to_maxval	= timeout_secs * HZ,
> > +			.to_retries	= 0,
> > +		};
> > +		probe->cl_timeout = &probe->cl_timeout_default;
> > +		probe->cl_softrtry = 1;
> > +		probe->cl_noretranstimeo = 0;
> > +		probe->cl_chatty = 0;
> > +		parent = probe;
> > +	}
> > +
> > +	rpcclient_localio = rpc_bind_new_program(parent, &nfslocalio_program, 1);
> > +	/* The new client holds a reference to its parent, the probe clone */
> > +	if (probe)
> > +		rpc_shutdown_client(probe);
> > 
> >  	dprintk_rcu("%s: server (%s) %s NFS LOCALIO.\n",
> >  		__func__, rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR),
> > -- 
> > 2.52.0

  reply	other threads:[~2026-11-09 15:10 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 21:52 [PATCH 0/3] NFS/localio: make the LOCALIO probe safe, repeatable and bounded Mike Snitzer
2026-11-02 21:52 ` [PATCH 1/3] NFS/localio: hold the client across an asynchronous LOCALIO probe Mike Snitzer
2026-11-02 21:52 ` [PATCH 2/3] NFS/localio: probe again for LOCALIO when localio_enabled is set to Y Mike Snitzer
2026-11-02 21:52 ` [PATCH 3/3] NFS/localio: give the LOCALIO probe a short timeout of its own Mike Snitzer
2026-11-06 22:02   ` Anna Schumaker
2026-11-09 15:10     ` Mike Snitzer [this message]
2026-11-09 15:57       ` Anna Schumaker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=avHiX4PgUIEQFbX2@kernel.org \
    --to=snitzer@kernel.org \
    --cc=anna@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=trondmy@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox