All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 13/44] nfsd41: use static buffers for sessions DRC
@ 2009-06-16  1:19 Benny Halevy
  2009-06-17 22:03 ` J. Bruce Fields
  0 siblings, 1 reply; 3+ messages in thread
From: Benny Halevy @ 2009-06-16  1:19 UTC (permalink / raw)
  To: bfields; +Cc: pnfs, linux-nfs

From: Andy Adamson <andros@netapp.com>

Change from page based to memory based NFSv4.1 DRC.

We need to allocate memory for the session DRC in the CREATE_SESSION operation
because of the guarantee to the client that the memory resource is available
for caching responses.

In preparation to remove struct nfsd4_cache_entry, add static storage to
struct nfsd4_slot to hold up to NFSD_SLOT_CACH_SIZE of all encoded operation
data past the encoded sequence operation.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
 fs/nfsd/nfs4state.c        |    9 +++++++++
 fs/nfsd/nfs4xdr.c          |    1 +
 include/linux/nfsd/state.h |    2 ++
 include/linux/nfsd/xdr4.h  |    1 +
 4 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index a6a7968..bf40c6b 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1052,6 +1052,7 @@ nfsd4_copy_pages(struct page **topages, struct page **frompages, short count)
 void
 nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
 {
+	struct nfsd4_slot *slot = resp->cstate.slot;
 	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
 	struct svc_rqst *rqstp = resp->rqstp;
 	struct nfsd4_compoundargs *args = rqstp->rq_argp;
@@ -1076,10 +1077,14 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
 	if (nfsd4_not_cached(resp)) {
 		entry->ce_resused = 0;
 		entry->ce_rpchdrlen = 0;
+		slot->sl_datalen = 0;
 		dprintk("%s Just cache SEQUENCE. ce_cachethis %d\n", __func__,
 			resp->cstate.slot->sl_cache_entry.ce_cachethis);
 		return;
 	}
+	slot->sl_datalen = (char *)resp->p - (char *)resp->cstate.datap;
+	memcpy(slot->sl_data, resp->cstate.datap, slot->sl_datalen);
+
 	entry->ce_resused = rqstp->rq_resused;
 	if (entry->ce_resused > NFSD_PAGES_PER_SLOT + 1)
 		entry->ce_resused = NFSD_PAGES_PER_SLOT + 1;
@@ -1127,6 +1132,7 @@ __be32
 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
 			 struct nfsd4_sequence *seq)
 {
+	struct nfsd4_slot *slot = resp->cstate.slot;
 	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
 	__be32 status;
 
@@ -1147,6 +1153,9 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
 		return nfs_ok;
 	}
 
+	/* The sequence operation has been encoded, cstate->datap set. */
+	memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen);
+
 	if (!nfsd41_copy_replay_data(resp, entry)) {
 		/*
 		 * Not enough room to use the replay rpc header, send the
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c4eda89..7ab83cc 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3072,6 +3072,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
 	WRITE32(0);
 
 	ADJUST_ARGS();
+	resp->cstate.datap = p;	/* DRC cache data pointer */
 	return 0;
 }
 
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index 1ebb05e..8d5daf7 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -113,6 +113,8 @@ struct nfsd4_cache_entry {
 struct nfsd4_slot {
 	bool				sl_inuse;
 	u32				sl_seqid;
+	u32				sl_datalen;
+	char				sl_data[NFSD_SLOT_CACHE_SIZE];
 	struct nfsd4_cache_entry	sl_cache_entry;
 };
 
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 5e4beb0..5144c92 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -52,6 +52,7 @@ struct nfsd4_compound_state {
 	struct nfsd4_session	*session;
 	struct nfsd4_slot	*slot;
 	__be32			*statp;
+	__be32			*datap;
 	size_t			iovlen;
 	u32			minorversion;
 	u32			status;
-- 
1.6.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 13/44] nfsd41: use static buffers for sessions DRC
  2009-06-16  1:19 [PATCH 13/44] nfsd41: use static buffers for sessions DRC Benny Halevy
@ 2009-06-17 22:03 ` J. Bruce Fields
  2009-06-17 22:05   ` J. Bruce Fields
  0 siblings, 1 reply; 3+ messages in thread
From: J. Bruce Fields @ 2009-06-17 22:03 UTC (permalink / raw)
  To: Benny Halevy; +Cc: pnfs, linux-nfs

On Tue, Jun 16, 2009 at 04:19:49AM +0300, Benny Halevy wrote:
> From: Andy Adamson <andros@netapp.com>
> 
> Change from page based to memory based NFSv4.1 DRC.
> 
> We need to allocate memory for the session DRC in the CREATE_SESSION operation
> because of the guarantee to the client that the memory resource is available
> for caching responses.
> 
> In preparation to remove struct nfsd4_cache_entry, add static storage to
> struct nfsd4_slot to hold up to NFSD_SLOT_CACH_SIZE of all encoded operation
> data past the encoded sequence operation.
> 
> Signed-off-by: Andy Adamson <andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
>  fs/nfsd/nfs4state.c        |    9 +++++++++
>  fs/nfsd/nfs4xdr.c          |    1 +
>  include/linux/nfsd/state.h |    2 ++
>  include/linux/nfsd/xdr4.h  |    1 +
>  4 files changed, 13 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index a6a7968..bf40c6b 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -1052,6 +1052,7 @@ nfsd4_copy_pages(struct page **topages, struct page **frompages, short count)
>  void
>  nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
>  {
> +	struct nfsd4_slot *slot = resp->cstate.slot;
>  	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
>  	struct svc_rqst *rqstp = resp->rqstp;
>  	struct nfsd4_compoundargs *args = rqstp->rq_argp;
> @@ -1076,10 +1077,14 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
>  	if (nfsd4_not_cached(resp)) {
>  		entry->ce_resused = 0;
>  		entry->ce_rpchdrlen = 0;
> +		slot->sl_datalen = 0;
>  		dprintk("%s Just cache SEQUENCE. ce_cachethis %d\n", __func__,
>  			resp->cstate.slot->sl_cache_entry.ce_cachethis);
>  		return;
>  	}
> +	slot->sl_datalen = (char *)resp->p - (char *)resp->cstate.datap;
> +	memcpy(slot->sl_data, resp->cstate.datap, slot->sl_datalen);

A response (e.g. a read) can span multiple pages, even if it's short.
So this doesn't work.

--b.

> +
>  	entry->ce_resused = rqstp->rq_resused;
>  	if (entry->ce_resused > NFSD_PAGES_PER_SLOT + 1)
>  		entry->ce_resused = NFSD_PAGES_PER_SLOT + 1;
> @@ -1127,6 +1132,7 @@ __be32
>  nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
>  			 struct nfsd4_sequence *seq)
>  {
> +	struct nfsd4_slot *slot = resp->cstate.slot;
>  	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
>  	__be32 status;
>  
> @@ -1147,6 +1153,9 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
>  		return nfs_ok;
>  	}
>  
> +	/* The sequence operation has been encoded, cstate->datap set. */
> +	memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen);
> +
>  	if (!nfsd41_copy_replay_data(resp, entry)) {
>  		/*
>  		 * Not enough room to use the replay rpc header, send the
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index c4eda89..7ab83cc 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -3072,6 +3072,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
>  	WRITE32(0);
>  
>  	ADJUST_ARGS();
> +	resp->cstate.datap = p;	/* DRC cache data pointer */
>  	return 0;
>  }
>  
> diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
> index 1ebb05e..8d5daf7 100644
> --- a/include/linux/nfsd/state.h
> +++ b/include/linux/nfsd/state.h
> @@ -113,6 +113,8 @@ struct nfsd4_cache_entry {
>  struct nfsd4_slot {
>  	bool				sl_inuse;
>  	u32				sl_seqid;
> +	u32				sl_datalen;
> +	char				sl_data[NFSD_SLOT_CACHE_SIZE];
>  	struct nfsd4_cache_entry	sl_cache_entry;
>  };
>  
> diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
> index 5e4beb0..5144c92 100644
> --- a/include/linux/nfsd/xdr4.h
> +++ b/include/linux/nfsd/xdr4.h
> @@ -52,6 +52,7 @@ struct nfsd4_compound_state {
>  	struct nfsd4_session	*session;
>  	struct nfsd4_slot	*slot;
>  	__be32			*statp;
> +	__be32			*datap;
>  	size_t			iovlen;
>  	u32			minorversion;
>  	u32			status;
> -- 
> 1.6.3
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 13/44] nfsd41: use static buffers for sessions DRC
  2009-06-17 22:03 ` J. Bruce Fields
@ 2009-06-17 22:05   ` J. Bruce Fields
  0 siblings, 0 replies; 3+ messages in thread
From: J. Bruce Fields @ 2009-06-17 22:05 UTC (permalink / raw)
  To: Benny Halevy; +Cc: pnfs, linux-nfs

On Wed, Jun 17, 2009 at 06:03:25PM -0400, bfields wrote:
> On Tue, Jun 16, 2009 at 04:19:49AM +0300, Benny Halevy wrote:
> > From: Andy Adamson <andros@netapp.com>
> > 
> > Change from page based to memory based NFSv4.1 DRC.
> > 
> > We need to allocate memory for the session DRC in the CREATE_SESSION operation
> > because of the guarantee to the client that the memory resource is available
> > for caching responses.
> > 
> > In preparation to remove struct nfsd4_cache_entry, add static storage to
> > struct nfsd4_slot to hold up to NFSD_SLOT_CACH_SIZE of all encoded operation
> > data past the encoded sequence operation.
> > 
> > Signed-off-by: Andy Adamson <andros@netapp.com>
> > Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> > ---
> >  fs/nfsd/nfs4state.c        |    9 +++++++++
> >  fs/nfsd/nfs4xdr.c          |    1 +
> >  include/linux/nfsd/state.h |    2 ++
> >  include/linux/nfsd/xdr4.h  |    1 +
> >  4 files changed, 13 insertions(+), 0 deletions(-)
> > 
> > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> > index a6a7968..bf40c6b 100644
> > --- a/fs/nfsd/nfs4state.c
> > +++ b/fs/nfsd/nfs4state.c
> > @@ -1052,6 +1052,7 @@ nfsd4_copy_pages(struct page **topages, struct page **frompages, short count)
> >  void
> >  nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
> >  {
> > +	struct nfsd4_slot *slot = resp->cstate.slot;
> >  	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
> >  	struct svc_rqst *rqstp = resp->rqstp;
> >  	struct nfsd4_compoundargs *args = rqstp->rq_argp;
> > @@ -1076,10 +1077,14 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
> >  	if (nfsd4_not_cached(resp)) {
> >  		entry->ce_resused = 0;
> >  		entry->ce_rpchdrlen = 0;
> > +		slot->sl_datalen = 0;
> >  		dprintk("%s Just cache SEQUENCE. ce_cachethis %d\n", __func__,
> >  			resp->cstate.slot->sl_cache_entry.ce_cachethis);
> >  		return;
> >  	}
> > +	slot->sl_datalen = (char *)resp->p - (char *)resp->cstate.datap;
> > +	memcpy(slot->sl_data, resp->cstate.datap, slot->sl_datalen);
> 
> A response (e.g. a read) can span multiple pages, even if it's short.
> So this doesn't work.

(So: probably just write a function copy_xdr_to_buf(xdr_buf, n, p) (if
there isn't one already somewhere) that copies the first n bytes out of
an xdr buffer into a given destination buffer p.)

--b.

> 
> --b.
> 
> > +
> >  	entry->ce_resused = rqstp->rq_resused;
> >  	if (entry->ce_resused > NFSD_PAGES_PER_SLOT + 1)
> >  		entry->ce_resused = NFSD_PAGES_PER_SLOT + 1;
> > @@ -1127,6 +1132,7 @@ __be32
> >  nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
> >  			 struct nfsd4_sequence *seq)
> >  {
> > +	struct nfsd4_slot *slot = resp->cstate.slot;
> >  	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
> >  	__be32 status;
> >  
> > @@ -1147,6 +1153,9 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
> >  		return nfs_ok;
> >  	}
> >  
> > +	/* The sequence operation has been encoded, cstate->datap set. */
> > +	memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen);
> > +
> >  	if (!nfsd41_copy_replay_data(resp, entry)) {
> >  		/*
> >  		 * Not enough room to use the replay rpc header, send the
> > diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> > index c4eda89..7ab83cc 100644
> > --- a/fs/nfsd/nfs4xdr.c
> > +++ b/fs/nfsd/nfs4xdr.c
> > @@ -3072,6 +3072,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
> >  	WRITE32(0);
> >  
> >  	ADJUST_ARGS();
> > +	resp->cstate.datap = p;	/* DRC cache data pointer */
> >  	return 0;
> >  }
> >  
> > diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
> > index 1ebb05e..8d5daf7 100644
> > --- a/include/linux/nfsd/state.h
> > +++ b/include/linux/nfsd/state.h
> > @@ -113,6 +113,8 @@ struct nfsd4_cache_entry {
> >  struct nfsd4_slot {
> >  	bool				sl_inuse;
> >  	u32				sl_seqid;
> > +	u32				sl_datalen;
> > +	char				sl_data[NFSD_SLOT_CACHE_SIZE];
> >  	struct nfsd4_cache_entry	sl_cache_entry;
> >  };
> >  
> > diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
> > index 5e4beb0..5144c92 100644
> > --- a/include/linux/nfsd/xdr4.h
> > +++ b/include/linux/nfsd/xdr4.h
> > @@ -52,6 +52,7 @@ struct nfsd4_compound_state {
> >  	struct nfsd4_session	*session;
> >  	struct nfsd4_slot	*slot;
> >  	__be32			*statp;
> > +	__be32			*datap;
> >  	size_t			iovlen;
> >  	u32			minorversion;
> >  	u32			status;
> > -- 
> > 1.6.3
> > 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-06-17 22:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-16  1:19 [PATCH 13/44] nfsd41: use static buffers for sessions DRC Benny Halevy
2009-06-17 22:03 ` J. Bruce Fields
2009-06-17 22:05   ` J. Bruce Fields

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.