linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "NeilBrown" <neilb@suse.de>
To: "Jeff Layton" <jlayton@kernel.org>
Cc: "Mike Snitzer" <snitzer@kernel.org>,
	linux-nfs@vger.kernel.org, "Chuck Lever" <chuck.lever@oracle.com>,
	"Anna Schumaker" <anna@kernel.org>,
	"Trond Myklebust" <trondmy@hammerspace.com>,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v14 15/25] nfs_common: introduce nfs_localio_ctx struct and interfaces
Date: Fri, 30 Aug 2024 14:36:13 +1000	[thread overview]
Message-ID: <172499257359.4433.13078012410547323207@noble.neil.brown.name> (raw)
In-Reply-To: <95776943752608072e60f185e98f35a97175eecd.camel@kernel.org>

On Fri, 30 Aug 2024, Jeff Layton wrote:
> On Thu, 2024-08-29 at 12:52 -0400, Mike Snitzer wrote:
> > On Thu, Aug 29, 2024 at 12:40:27PM -0400, Jeff Layton wrote:
> > > On Wed, 2024-08-28 at 21:04 -0400, Mike Snitzer wrote:
> > > > Introduce struct nfs_localio_ctx and the interfaces
> > > > nfs_localio_ctx_alloc() and nfs_localio_ctx_free().  The next commit
> > > > will introduce nfsd_open_local_fh() which returns a nfs_localio_ctx
> > > > structure.
> > > > 
> > > > Also, expose localio's required NFSD symbols to NFS client:
> > > > - Cache nfsd_open_local_fh symbol and other required NFSD symbols in a
> > > >   globally accessible 'nfs_to' nfs_to_nfsd_t struct.  Add interfaces
> > > >   get_nfs_to_nfsd_symbols() and put_nfs_to_nfsd_symbols() to allow
> > > >   each NFS client to take a reference on NFSD symbols.
> > > > 
> > > > - Apologies for the DEFINE_NFS_TO_NFSD_SYMBOL macro that makes
> > > >   defining get_##NFSD_SYMBOL() and put_##NFSD_SYMBOL() functions far
> > > >   simpler (and avoids cut-n-paste bugs, which is what motivated the
> > > >   development and use of a macro for this). But as C macros go it is a
> > > >   very simple one and there are many like it all over the kernel.
> > > > 
> > > > - Given the unique nature of NFS LOCALIO being an optional feature
> > > >   that when used requires NFS share access to NFSD memory: a unique
> > > >   bridging of NFSD resources to NFS (via nfs_common) is needed.  But
> > > >   that bridge must be dynamic, hence the use of symbol_request() and
> > > >   symbol_put().  Proposed ideas to accomolish the same without using
> > > >   symbol_{request,put} would be far more tedious to implement and
> > > >   very likely no easier to review.  Anyway: sorry NeilBrown...
> > > > 
> > > > - Despite the use of indirect function calls, caching these nfsd
> > > >   symbols for use by the client offers a ~10% performance win
> > > >   (compared to always doing get+call+put) for high IOPS workloads.
> > > > 
> > > > - Introduce nfsd_file_file() wrapper that provides access to
> > > >   nfsd_file's backing file.  Keeps nfsd_file structure opaque to NFS
> > > >   client (as suggested by Jeff Layton).
> > > > 
> > > > - The addition of nfsd_file_get, nfsd_file_put and nfsd_file_file
> > > >   symbols prepares for the NFS client to use nfsd_file for localio.
> > > > 
> > > > Suggested-by: Trond Myklebust <trond.myklebust@hammerspace.com> # nfs_to
> > > > Suggested-by: Jeff Layton <jlayton@kernel.org> # nfsd_file_file
> > > > Signed-off-by: Mike Snitzer <snitzer@kernel.org>
> > > > ---
> > > >  fs/nfs_common/nfslocalio.c | 159 +++++++++++++++++++++++++++++++++++++
> > > >  fs/nfsd/filecache.c        |  25 ++++++
> > > >  fs/nfsd/filecache.h        |   1 +
> > > >  fs/nfsd/nfssvc.c           |   5 ++
> > > >  include/linux/nfslocalio.h |  38 +++++++++
> > > >  5 files changed, 228 insertions(+)
> > > > 
> > > > diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
> > > > index 1a35a4a6dbe0..cc30fdb0cb46 100644
> > > > --- a/fs/nfs_common/nfslocalio.c
> > > > +++ b/fs/nfs_common/nfslocalio.c
> > > > @@ -72,3 +72,162 @@ bool nfs_uuid_is_local(const uuid_t *uuid, struct net *net, struct auth_domain *
> > > >  	return is_local;
> > > >  }
> > > >  EXPORT_SYMBOL_GPL(nfs_uuid_is_local);
> > > > +
> > > > +/*
> > > > + * The nfs localio code needs to call into nfsd using various symbols (below),
> > > > + * but cannot be statically linked, because that will make the nfs module
> > > > + * depend on the nfsd module.
> > > > + *
> > > > + * Instead, do dynamic linking to the nfsd module (via nfs_common module). The
> > > > + * nfs_common module will only hold a reference on nfsd when localio is in use.
> > > > + * This allows some sanity checking, like giving up on localio if nfsd isn't loaded.
> > > > + */
> > > > +static DEFINE_SPINLOCK(nfs_to_nfsd_lock);
> > > > +nfs_to_nfsd_t nfs_to;
> > > > +EXPORT_SYMBOL_GPL(nfs_to);
> > > > +
> > > > +/* Macro to define nfs_to get and put methods, avoids copy-n-paste bugs */
> > > > +#define DEFINE_NFS_TO_NFSD_SYMBOL(NFSD_SYMBOL)		\
> > > > +static nfs_to_##NFSD_SYMBOL##_t get_##NFSD_SYMBOL(void)	\
> > > > +{							\
> > > > +	return symbol_request(NFSD_SYMBOL);		\
> > > > +}							\
> > > > +static void put_##NFSD_SYMBOL(void)			\
> > > > +{							\
> > > > +	symbol_put(NFSD_SYMBOL);			\
> > > > +	nfs_to.NFSD_SYMBOL = NULL;			\
> > > > +}
> > > > +
> > > > +/* The nfs localio code needs to call into nfsd to map filehandle -> struct nfsd_file */
> > > > +extern struct nfs_localio_ctx *
> > > > +nfsd_open_local_fh(struct net *, struct auth_domain *, struct rpc_clnt *,
> > > > +		   const struct cred *, const struct nfs_fh *, const fmode_t);
> > > > +DEFINE_NFS_TO_NFSD_SYMBOL(nfsd_open_local_fh);
> > > > +
> > > > +/* The nfs localio code needs to call into nfsd to acquire the nfsd_file */
> > > > +extern struct nfsd_file *nfsd_file_get(struct nfsd_file *nf);
> > > > +DEFINE_NFS_TO_NFSD_SYMBOL(nfsd_file_get);
> > > > +
> > > > +/* The nfs localio code needs to call into nfsd to release the nfsd_file */
> > > > +extern void nfsd_file_put(struct nfsd_file *nf);
> > > > +DEFINE_NFS_TO_NFSD_SYMBOL(nfsd_file_put);
> > > > +
> > > > +/* The nfs localio code needs to call into nfsd to access the nf->nf_file */
> > > > +extern struct file * nfsd_file_file(struct nfsd_file *nf);
> > > > +DEFINE_NFS_TO_NFSD_SYMBOL(nfsd_file_file);
> > > > +
> > > > +/* The nfs localio code needs to call into nfsd to release nn->nfsd_serv */
> > > > +extern void nfsd_serv_put(struct nfsd_net *nn);
> > > > +DEFINE_NFS_TO_NFSD_SYMBOL(nfsd_serv_put);
> > > > +#undef DEFINE_NFS_TO_NFSD_SYMBOL
> > > > +
> > > 
> > > I have the same concerns as Neil did with this patch in v13. An ops
> > > structure that nfsd registers with nfs_common and that has pointers to
> > > all of these functions would be a lot cleaner. I think it'll end up
> > > being less code too.
> > > 
> > > In fact, for that I'd probably break my usual guideline of not
> > > introducing new interfaces without callers, and just do a separate
> > > patch that adds the ops structure and sets up the handling of the
> > > pointer to it in nfs_common.
> > 
> > OK, as much as it pains me to set aside proven code that I put a
> > decent amount of time to honing: I'll humor you guys and try to make
> > an ops structure workable. (we can always fall back to my approach if
> > I/we come up short).
> > 
> > I'm just concerned about the optional use aspect.  There is the pain
> > point of how does NFS client come to _know_ NFSD loaded?  Using
> > symbol_request() deals with that nicely.
> > 
> 
> Have a pointer to a struct nfsd_localio_ops or something in the
> nfs_common module. That's initially set to NULL. Then, have a static
> structure of that type in nfsd.ko, and have its __init routine set the
> pointer in nfs_common to point to the right structure. The __exit
> routine will later set it to NULL.
> 
> > I really don't want all calls in NFS client (or nfs_common) to have to
> > first check if nfs_common's 'nfs_to' ops structure is NULL or not.
> 
> Neil seems to think that's not necessary:
> 
> "If nfs/localio holds an auth_domain, then it implicitly holds a
> reference to the nfsd module and the functions cannot disappear."

On reflection that isn't quite right, but it is the sort of approach
that I think we need to take.
There are several things that the NFS client needs to hold one to.

1/ It needs a reference to the nfsd module (or symbols in the module).
   I think this can be held long term but we need a clear mechanism for
   it to be dropped.
2/ It needs a reference to the nfsd_serv which it gets through the
   'struct net' pointer.  I've posted patches to handle that better.
3/ It needs a reference to an auth_domain.  This can safely be a long
   term reference.  It can already be invalidated and the code to free
   it is in sunrpc which nfs already pins.  Any delay in freeing it only
   wastes memory (not much), it doesn't impact anything else.
4/ It needs a reference to the nfsd_file and/or file.  This is currently
   done only while the ref to the nfsd_serv is held, so I think there is
   no problem there.

So possibly we could take a reference to the nfsd module whenever we
store a net in nfs_uuid. and drop the ref whenever we clear that.

That means we cannot call nfsd_open_local_fh() without first getting a
ref on the nfsd_serv which my latest code doesn't do.  That is easily
fixed.  I'll send a patch for consideration...

Thanks,
NeilBrown

  reply	other threads:[~2024-08-30  4:36 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-29  1:03 [PATCH v14 00/25] nfs/nfsd: add support for LOCALIO Mike Snitzer
2024-08-29  1:03 ` [PATCH v14 01/25] nfs_common: factor out nfs_errtbl and nfs_stat_to_errno Mike Snitzer
2024-08-29 14:17   ` Jeff Layton
2024-08-29  1:03 ` [PATCH v14 02/25] nfs_common: factor out nfs4_errtbl and nfs4_stat_to_errno Mike Snitzer
2024-08-29 14:17   ` Jeff Layton
2024-08-29  1:03 ` [PATCH v14 03/25] nfs: factor out {encode,decode}_opaque_fixed to nfs_xdr.h Mike Snitzer
2024-08-29 14:19   ` Jeff Layton
2024-08-29  1:03 ` [PATCH v14 04/25] NFSD: Handle @rqstp == NULL in check_nfsd_access() Mike Snitzer
2024-08-29 14:20   ` Jeff Layton
2024-08-29  1:04 ` [PATCH v14 05/25] NFSD: Refactor nfsd_setuser_and_check_port() Mike Snitzer
2024-08-29 14:23   ` Jeff Layton
2024-08-29  1:04 ` [PATCH v14 06/25] NFSD: Avoid using rqstp->rq_vers in nfsd_set_fh_dentry() Mike Snitzer
2024-08-29  1:45   ` [PATCH v14.5 " Mike Snitzer
2024-08-29 16:52     ` Jeff Layton
2024-08-29 14:28   ` [PATCH v14 " Jeff Layton
2024-08-29 15:28     ` Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 07/25] NFSD: Short-circuit fh_verify tracepoints for LOCALIO Mike Snitzer
2024-08-29 14:33   ` Jeff Layton
2024-08-29 14:35     ` Chuck Lever
2024-08-29  1:04 ` [PATCH v14 08/25] nfsd: factor out __fh_verify to allow NULL rqstp to be passed Mike Snitzer
2024-08-29 14:39   ` Jeff Layton
2024-08-29 15:35     ` Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 09/25] nfsd: add nfsd_file_acquire_local() Mike Snitzer
2024-08-29 14:49   ` Jeff Layton
2024-08-29 15:47   ` Chuck Lever
2024-08-29 15:59     ` Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 10/25] nfsd: add nfsd_serv_try_get and nfsd_serv_put Mike Snitzer
2024-08-29 15:49   ` Chuck Lever
2024-08-29 15:57   ` Jeff Layton
2024-08-29 16:01     ` Mike Snitzer
2024-08-29 16:04       ` Chuck Lever
2024-08-29  1:04 ` [PATCH v14 11/25] SUNRPC: remove call_allocate() BUG_ONs Mike Snitzer
2024-08-29 15:58   ` Jeff Layton
2024-08-29  1:04 ` [PATCH v14 12/25] SUNRPC: add svcauth_map_clnt_to_svc_cred_local Mike Snitzer
2024-08-29 15:50   ` Chuck Lever
2024-08-29 16:01   ` Jeff Layton
2024-08-29  1:04 ` [PATCH v14 13/25] SUNRPC: replace program list with program array Mike Snitzer
2024-08-29 16:02   ` Jeff Layton
2024-08-29  1:04 ` [PATCH v14 14/25] nfs_common: add NFS LOCALIO auxiliary protocol enablement Mike Snitzer
2024-08-29 16:07   ` Jeff Layton
2024-08-29 16:22     ` Mike Snitzer
2024-08-29 23:39   ` NeilBrown
2024-08-30  1:45     ` Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 15/25] nfs_common: introduce nfs_localio_ctx struct and interfaces Mike Snitzer
2024-08-29 16:40   ` Jeff Layton
2024-08-29 16:52     ` Mike Snitzer
2024-08-29 17:48       ` Jeff Layton
2024-08-30  4:36         ` NeilBrown [this message]
2024-08-30  5:01           ` Mike Snitzer
2024-08-30  5:08             ` Mike Snitzer
2024-08-30  5:12             ` Mike Snitzer
2024-08-30  5:34             ` NeilBrown
2024-08-30  6:02               ` Mike Snitzer
2024-08-30  5:46   ` NeilBrown
2024-08-30  5:56     ` Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 16/25] nfsd: add localio support Mike Snitzer
2024-08-29 16:01   ` Chuck Lever
2024-08-29 16:15     ` Mike Snitzer
2024-08-29 23:10     ` NeilBrown
2024-08-29 16:49   ` Jeff Layton
2024-08-29 16:59     ` Mike Snitzer
2024-08-29 17:18       ` Chuck Lever
2024-08-29  1:04 ` [PATCH v14 17/25] nfsd: implement server support for NFS_LOCALIO_PROGRAM Mike Snitzer
2024-08-29 16:50   ` Jeff Layton
2024-08-29  1:04 ` [PATCH v14 18/25] nfs: pass struct nfs_localio_ctx to nfs_init_pgio and nfs_init_commit Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 19/25] nfs: add localio support Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 20/25] nfs: enable localio for non-pNFS IO Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 21/25] pnfs/flexfiles: enable localio support Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 22/25] nfs/localio: use dedicated workqueues for filesystem read and write Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 23/25] nfs: implement client support for NFS_LOCALIO_PROGRAM Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 24/25] nfs: add Documentation/filesystems/nfs/localio.rst Mike Snitzer
2024-08-29  1:04 ` [PATCH v14 25/25] nfs: add FAQ section to Documentation/filesystems/nfs/localio.rst Mike Snitzer
2024-08-29  1:47   ` [PATCH v14.5 " Mike Snitzer
2024-08-29  1:42 ` [PATCH v14 00/25] nfs/nfsd: add support for LOCALIO Mike Snitzer
2024-08-29  1:50   ` Mike Snitzer

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=172499257359.4433.13078012410547323207@noble.neil.brown.name \
    --to=neilb@suse.de \
    --cc=anna@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=snitzer@kernel.org \
    --cc=trondmy@hammerspace.com \
    /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;
as well as URLs for NNTP newsgroup(s).