public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: andros@netapp.com
To: bfields@fieldses.org
Cc: linux-nfs@vger.kernel.org, pnfs@linux-nfs.org,
	Andy Adamson <andros@netapp.com>
Subject: [PATCH 12/29] nfsd41: allocate and use drc cache buffers
Date: Thu, 23 Apr 2009 12:42:51 -0400	[thread overview]
Message-ID: <1240504988-9572-13-git-send-email-andros@netapp.com> (raw)
In-Reply-To: <1240504988-9572-12-git-send-email-andros@netapp.com>

From: Andy Adamson <andros@netapp.com>

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

Use the existing nfsd4_cache_entry ce_datav kvec to hold up to
NFSD_SLOT_CACH_SIZE of all encoded operation data past the encoded sequence
operation.  Allocate the buffer on demand, and keep it for the life of the
session.

Wnen we have dynamic slots negotiation we need to shutdown the slot upon
allocation error.

Signed-off-by: Andy Adamson <andros@netapp.com>
---
 fs/nfsd/nfs4state.c        |   31 ++++++++++++++++++++++++-------
 fs/nfsd/nfs4xdr.c          |    2 ++
 include/linux/nfsd/state.h |    2 +-
 include/linux/nfsd/xdr4.h  |    3 ++-
 4 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 5666feb..9e79e0c 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1048,20 +1048,19 @@ nfsd4_copy_pages(struct page **topages, struct page **frompages, short count)
  * Store the base and length of the rq_req.head[0] page
  * of the NFSv4.1 data, just past the rpc header.
  */
-void
+__be32
 nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
 {
 	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
 	struct svc_rqst *rqstp = resp->rqstp;
 	struct nfsd4_compoundargs *args = rqstp->rq_argp;
 	struct nfsd4_op *op = &args->ops[resp->opcnt];
-	struct kvec *resv = &rqstp->rq_res.head[0];
 
 	dprintk("--> %s entry %p\n", __func__, entry);
 
 	/* Don't cache a failed OP_SEQUENCE. */
 	if (resp->opcnt == 1 && op->opnum == OP_SEQUENCE && resp->cstate.status)
-		return;
+		return 0;
 
 	nfsd4_release_respages(entry->ce_respages, entry->ce_resused);
 	entry->ce_opcnt = resp->opcnt;
@@ -1075,21 +1074,35 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
 	if (nfsd4_not_cached(resp)) {
 		entry->ce_resused = 0;
 		entry->ce_rpchdrlen = 0;
+		entry->ce_datav.iov_len = 0;
 		dprintk("%s Just cache SEQUENCE. ce_cachethis %d\n", __func__,
 			resp->cstate.slot->sl_cache_entry.ce_cachethis);
-		return;
+		return 0;
 	}
+
+	/* allocate the buffer on demand and keep it for the life of the slot */
+	if (entry->ce_datav.iov_base == NULL) {
+		entry->ce_datav.iov_base = kmalloc(NFSD_SLOT_CACHE_SIZE,
+						   GFP_KERNEL);
+		if (!entry->ce_datav.iov_base) {
+			/* FIXME: Should remove slot from session */
+			printk(KERN_WARNING "NFSD: No memory for DRC\n");
+			return -ENOMEM;
+		}
+	}
+	entry->ce_datav.iov_len = (char *)resp->p - (char *)resp->cstate.datap;
+	memcpy(entry->ce_datav.iov_base, resp->cstate.datap,
+	       entry->ce_datav.iov_len);
+
 	entry->ce_resused = rqstp->rq_resused;
 	if (entry->ce_resused > NFSD_PAGES_PER_SLOT + 1)
 		entry->ce_resused = NFSD_PAGES_PER_SLOT + 1;
 	nfsd4_copy_pages(entry->ce_respages, rqstp->rq_respages,
 			 entry->ce_resused);
-	entry->ce_datav.iov_base = resp->cstate.statp;
-	entry->ce_datav.iov_len = resv->iov_len - ((char *)resp->cstate.statp -
-				(char *)page_address(rqstp->rq_respages[0]));
 	/* Current request rpc header length*/
 	entry->ce_rpchdrlen = (char *)resp->cstate.statp -
 				(char *)page_address(rqstp->rq_respages[0]);
+	return 0;
 }
 
 /*
@@ -1146,6 +1159,10 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
 		return nfs_ok;
 	}
 
+	/* The sequence operation has been encoded, cstate->datap set. */
+	memcpy(resp->cstate.datap, entry->ce_datav.iov_base,
+	       entry->ce_datav.iov_len);
+
 	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 7459900..f4bba66 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3113,6 +3113,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
 	WRITE32(0);
 
 	ADJUST_ARGS();
+	resp->cstate.datap = p; /* DRC cache data pointer */
 	return 0;
 }
 
@@ -3362,6 +3363,7 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
 				!nfsd4_not_cached(resp)) {
 			iov->iov_len = resp->cstate.iovlen;
 		} else {
+			/* FIXME: return ignored for now. Can have -ENOMEM */
 			nfsd4_store_cache_entry(resp);
 			dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__);
 			resp->cstate.slot->sl_inuse = 0;
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index 473eb0d..b8aa47a 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -116,7 +116,7 @@ struct nfs4_callback {
 
 struct nfsd4_cache_entry {
 	__be32		ce_status;
-	struct kvec	ce_datav; /* encoded NFSv4.1 data in rq_res.head[0] */
+	struct kvec	ce_datav; /* encoded cached operations */
 	struct page	*ce_respages[NFSD_PAGES_PER_SLOT + 1];
 	int		ce_cachethis;
 	short		ce_resused;
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 8fd5eb1..5622e56 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;
@@ -514,7 +515,7 @@ extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
 extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
 		struct nfsd4_compound_state *,
 		struct nfsd4_setclientid_confirm *setclientid_confirm);
-extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp);
+extern __be32 nfsd4_store_cache_entry(struct nfsd4_compoundres *resp);
 extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
 		struct nfsd4_sequence *seq);
 extern void nfsd4_cache_create_session(struct nfsd4_create_session *cr_ses,
-- 
1.5.4.3


  reply	other threads:[~2009-04-23 16:43 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-23 16:42 [PATCH 0/29] NFSv4.1 Server DRC rewrite andros
2009-04-23 16:42 ` [PATCH 01/29] nfsd41: add create session slot buffer to struc nfs4_client andros
2009-04-23 16:42   ` [PATCH 02/29] nfsd41: encode create_session result into cache andros
2009-04-23 16:42     ` [PATCH 03/29] nfsd41: create_session check replay first andros
2009-04-23 16:42       ` [PATCH 04/29] nfsd41: replay solo and embedded create session andros
2009-04-23 16:42         ` [PATCH 05/29] nfsd41: create_session cache hold client reference andros
2009-04-23 16:42           ` [PATCH 06/29] nfsd41: no nfsd4_release_respages for the clientid cache andros
2009-04-23 16:42             ` [PATCH 07/29] nfsd41: slots are freed with session andros
2009-04-23 16:42               ` [PATCH 08/29] nfsd41: protect sv_drc_pages_used with spinlock andros
2009-04-23 16:42                 ` [PATCH 09/29] nfsd41: sanity check client drc maxreqs andros
2009-04-23 16:42                   ` [PATCH 10/29] nfsd41: change from page to memory based drc limits andros
2009-04-23 16:42                     ` [PATCH 11/29] nfsd41: set the session maximum response size cached andros
2009-04-23 16:42                       ` andros [this message]
2009-04-23 16:42                         ` [PATCH 13/29] nfsd41: free drc cache buffers andros
2009-04-23 16:42                           ` [PATCH 14/29] nfsd41: obliterate nfsd4_copy_pages andros
2009-04-23 16:42                             ` [PATCH 15/29] nfsd41: obliterate nfsd41_copy_replay_data andros
2009-04-23 16:42                               ` [PATCH 16/29] nfsd41: obliterate nfsd4_release_respages andros
2009-04-23 16:42                                 ` [PATCH 17/29] nfsd41: remove unused nfsd4_cache_entry fields andros
2009-04-23 16:42                                   ` [PATCH 18/29] nfsd41: obliterate nfsd4_set_statp andros
2009-04-23 16:42                                     ` [PATCH 19/29] nfsd41: rename nfsd4_enc_uncached_replay andros
2009-04-23 16:42                                       ` [PATCH 20/29] nfsd41: encode replay sequence from the slot values andros
2009-04-23 16:43                                         ` [PATCH 21/29] nfsd41: remove iovlen field from nfsd4_compound_state andros
2009-04-23 16:43                                           ` [PATCH 22/29] nfsd41: obliterate nfsd41_copy_replay_data andros
2009-04-23 16:43                                             ` [PATCH 23/29] nfsd41: fix nfsd4_store_cache_entry comments andros
2009-04-23 16:43                                               ` [PATCH 24/29] nfsd41: support 16 slots per session andros
2009-04-23 16:43                                                 ` [PATCH 25/29] nfsd41: use the maximum operations per compound in nfsd4_compoundargs andros
2009-04-23 16:43                                                   ` [PATCH 26/29] nfsd41: fix nfsd4_store_cache_entry dprintk andros
2009-04-23 16:43                                                     ` [PATCH 27/29] nfsd41: add test for failed sequence operation andros
2009-04-23 16:43                                                       ` [PATCH 28/29] nfsd41: remove redundant failed sequence check andros
2009-04-23 16:43                                                         ` [PATCH 29/29] nfsd41: remove check for session andros
2009-04-23 23:39                           ` [PATCH 13/29] nfsd41: free drc cache buffers J. Bruce Fields
2009-04-24 14:11                             ` [pnfs] " William A. (Andy) Adamson
2009-04-23 23:36                 ` [PATCH 08/29] nfsd41: protect sv_drc_pages_used with spinlock J. Bruce Fields
2009-04-24 14:11                   ` [pnfs] " William A. (Andy) Adamson
2009-04-23 23:28           ` [PATCH 05/29] nfsd41: create_session cache hold client reference J. Bruce Fields
2009-04-24 13:52             ` Andy Adamson
2009-04-24 14:02               ` J. Bruce Fields
2009-04-24 14:06                 ` [pnfs] " William A. (Andy) Adamson
2009-04-23 23:25         ` [PATCH 04/29] nfsd41: replay solo and embedded create session J. Bruce Fields
2009-04-23 23:21     ` [PATCH 02/29] nfsd41: encode create_session result into cache J. Bruce Fields
2009-04-23 23:32       ` J. Bruce Fields
2009-04-24 13:56         ` Andy Adamson
2009-04-24 13:52       ` Andy Adamson
2009-04-23 22:55   ` [PATCH 01/29] nfsd41: add create session slot buffer to struc nfs4_client J. Bruce Fields
2009-04-23 23:41 ` [PATCH 0/29] NFSv4.1 Server DRC rewrite J. Bruce Fields
2009-04-24 14:12   ` [pnfs] " William A. (Andy) Adamson

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=1240504988-9572-13-git-send-email-andros@netapp.com \
    --to=andros@netapp.com \
    --cc=bfields@fieldses.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=pnfs@linux-nfs.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