From: Benny Halevy <bhalevy@panasas.com>
To: pnfs@linux-nfs.org
Cc: "J. Bruce Fields" <bfields@fieldses.org>, linux-nfs@vger.kernel.org
Subject: Re: [pnfs] [RFC 45/51] nfsd41: DRC save, restore, and clear functions
Date: Mon, 17 Nov 2008 16:14:50 +0200 [thread overview]
Message-ID: <49217C5A.1060406@panasas.com> (raw)
In-Reply-To: <1226350569-11808-1-git-send-email-bhalevy@panasas.com>
On Nov. 10, 2008, 22:56 +0200, Benny Halevy <bhalevy@panasas.com> wrote:
> From: Andy Adamson <andros@netapp.com>
>
> Cache all the result pages, including the rpc header in rq_respages[0],
> for a request in the slot table cache entry.
>
> Cache the statp pointer from nfsd_dispatch which points into rq_respages[0]
> just past the rpc header. When setting a cache entry, calculate and save the
> length of the nfs data minus the rpc header for rq_respages[0].
>
> When replaying a cache entry, replace the cached rpc header with the
> replayed request rpc result header, unless there is not enough room in the
> cached results first page. In that case, use the cached rpc header.
>
> Signed-off-by: Andy Adamson<andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfsd/nfs4state.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
> fs/nfsd/nfssvc.c | 6 +++
> include/linux/nfsd/cache.h | 3 +
> include/linux/nfsd/state.h | 17 +++++--
> include/linux/nfsd/xdr4.h | 7 +++
> 5 files changed, 134 insertions(+), 5 deletions(-)
>
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index ba6ab19..230ce1d 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -412,6 +412,7 @@ alloc_init_session(struct nfs4_client *clp, struct nfsd4_create_session *cses)
> for (i = 0; i < new->se_fnumslots; i++) {
> new->se_slots[i].sl_session = new;
> nfs41_set_slot_state(&new->se_slots[i], NFS4_SLOT_AVAILABLE);
> + spin_lock_init(&new->se_slots[i].sl_cache_entry.ce_lock);
> }
>
> new->se_client = clp;
> @@ -997,6 +998,111 @@ nfsd4_clear_respages(struct page **respages, short resused)
> }
>
> #if defined(CONFIG_NFSD_V4_1)
> +
> +void
> +nfsd41_set_statp(struct svc_rqst *rqstp, __be32 *statp)
> +{
> + struct nfsd4_compoundres *resp = rqstp->rq_resp;
> +
> + resp->statp = statp;
> +}
> +
> +/*
> + * Cache the reply pages, clearing the previous pages.
> + * Store the base and length of the rq_req.head[0] page
> + * of the NFSv4.1 data, just past the rpc header.
> + */
> +void
> +nfsd41_set_cache_entry(struct nfsd4_compoundres *resp)
> +{
> + struct nfs41_cache_entry *entry =
> + &resp->current_ses->cs_slot->sl_cache_entry;
> + struct svc_rqst *rqstp = resp->rqstp;
> + 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 && resp->status)
> + return;
> + spin_lock(&entry->ce_lock);
review 11-13: we can probably get rid of the spinlock
and s/nfsd4_clear_respages/nfsd4_release_respages/
> + nfsd4_clear_respages(entry->ce_respages, entry->ce_resused);
> + nfsd4_cache_rqst_pages(rqstp, entry->ce_respages, &entry->ce_resused);
> + entry->ce_status = resp->status;
> + entry->ce_datav.iov_base = resp->statp;
> + entry->ce_datav.iov_len = resv->iov_len - ((char *)resp->statp -
> + (char *)page_address(rqstp->rq_respages[0]));
> + spin_unlock(&entry->ce_lock);
> +}
> +
> +/*
> + * Copy the cached NFSv4.1 reply skipping the cached rpc header into the
> + * replay result res.head[0] past the rpc header to end up with replay
> + * rpc header and cached NFSv4.1 reply.
> + */
> +static int
> +nfsd41_copy_replay_data(struct nfsd4_compoundres *resp,
> + struct nfs41_cache_entry *entry)
> +{
> + struct svc_rqst *rqstp = resp->rqstp;
> + struct kvec *resv = &resp->rqstp->rq_res.head[0];
> + int len;
> +
> + /* Current request rpc header length*/
> + len = (char *)resp->statp - (char *)page_address(rqstp->rq_respages[0]);
> + if (entry->ce_datav.iov_len + len > PAGE_SIZE) {
> + dprintk("%s v41 cached reply too large (%Zd).\n", __func__,
> + entry->ce_datav.iov_len);
> + return 0;
> + }
> + /* copy the cached reply nfsd data past the current rpc header */
> + memcpy((char *)resv->iov_base + len, entry->ce_datav.iov_base,
> + entry->ce_datav.iov_len);
> + resv->iov_len = len + entry->ce_datav.iov_len;
> + return 1;
> +}
> +
> +/*
> + * Keep the first page of the replay. Copy the NFSv4.1 data from the first
> + * cached page. Replace any futher replay pages from the cache.
> + */
> +__be32
> +nfsd41_replay_cache_entry(struct nfsd4_compoundres *resp)
> +{
> + struct nfs41_cache_entry *entry =
> + &resp->current_ses->cs_slot->sl_cache_entry;
> + __be32 status;
> +
> + dprintk("--> %s entry %p\n", __func__, entry);
> +
> + spin_lock(&entry->ce_lock);
review 11-13: no spin lock, yes state lock
do this in nfsd4_sequence under the state lock.
do nothing in nfs4svc_encode_compoundres
> +
> + if (!nfsd41_copy_replay_data(resp, entry)) {
> + /*
> + * Not enough room to use the replay rpc header, send the
> + * cached header. Release all the allocated result pages.
> + */
> + svc_free_res_pages(resp->rqstp);
> + nfsd4_move_pages(resp->rqstp->rq_respages, entry->ce_respages,
> + entry->ce_resused);
> + } else {
> + /* Release all but the first allocatek result page */
review 11-13: s/allocatek/allocated/
> +
> + resp->rqstp->rq_resused--;
> + svc_free_res_pages(resp->rqstp);
> +
> + nfsd4_move_pages(&resp->rqstp->rq_respages[1],
> + &entry->ce_respages[1],
> + entry->ce_resused - 1);
> + }
> +
> + resp->rqstp->rq_resused = entry->ce_resused;
> + status = entry->ce_status;
> + spin_unlock(&entry->ce_lock);
> +
> + return status;
> +}
> +
> /*
> * Set the exchange_id flags returned by the server.
> */
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index 07e4f5d..a9f90b6 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -543,6 +543,12 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
> + rqstp->rq_res.head[0].iov_len;
> rqstp->rq_res.head[0].iov_len += sizeof(__be32);
>
> +#ifdef CONFIG_NFSD_V4_1
> + /* NFSv4.1 DRC requires statp */
> + if (rqstp->rq_vers == 4)
> + nfsd41_set_statp(rqstp, statp);
> +#endif /* CONFIG_NFSD_V4_1 */
> +
> /* Now call the procedure handler, and encode NFS status. */
> nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
> nfserr = map_new_errors(rqstp->rq_vers, nfserr);
> diff --git a/include/linux/nfsd/cache.h b/include/linux/nfsd/cache.h
> index 04b355c..9315699 100644
> --- a/include/linux/nfsd/cache.h
> +++ b/include/linux/nfsd/cache.h
> @@ -75,5 +75,8 @@ int nfsd_reply_cache_init(void);
> void nfsd_reply_cache_shutdown(void);
> int nfsd_cache_lookup(struct svc_rqst *, int);
> void nfsd_cache_update(struct svc_rqst *, int, __be32 *);
> +#ifdef CONFIG_NFSD_V4_1
> +void nfsd41_set_statp(struct svc_rqst *, __be32*);
> +#endif /* CONFIG_NFSD_V4_1 */
>
> #endif /* NFSCACHE_H */
> diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
> index 4f37e2f..e4dc32f 100644
> --- a/include/linux/nfsd/state.h
> +++ b/include/linux/nfsd/state.h
> @@ -125,15 +125,22 @@ enum {
> NFS4_SLOT_INPROGRESS
> };
>
> +struct nfs41_cache_entry {
> + spinlock_t ce_lock;
> + __be32 ce_status;
> + struct kvec ce_datav; /* encoded NFSv4.1 data in rq_res.head[0] */
> + struct page *ce_respages[RPCSVC_MAXPAGES];
> + short ce_resused;
> +};
> +
> /*
> * nfs41_slot
> - *
> - * for now, just slot sequence number - will hold DRC for this slot.
> */
> struct nfs41_slot {
> - atomic_t sl_state;
> - struct nfs41_session *sl_session;
> - u32 sl_seqid;
> + atomic_t sl_state;
> + struct nfs41_session *sl_session;
> + u32 sl_seqid;
> + struct nfs41_cache_entry sl_cache_entry;
> };
>
> /*
> diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
> index fc42fba..554f2cd 100644
> --- a/include/linux/nfsd/xdr4.h
> +++ b/include/linux/nfsd/xdr4.h
> @@ -491,6 +491,11 @@ struct nfsd4_compoundres {
> u32 opcnt;
> __be32 * tagp; /* where to encode tag and opcount */
> u32 minorversion;
> +#if defined(CONFIG_NFSD_V4_1)
> + __be32 *statp;
> + u32 status;
> + struct current_session *current_ses;
> +#endif /* CONFIG_NFSD_V4_1 */
> };
>
> #define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs)
> @@ -534,6 +539,8 @@ extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
> #if defined(CONFIG_NFSD_V4_1)
> extern void nfsd41_current_session_free(struct current_session *cses);
> extern struct current_session *nfsd41_current_session_alloc(void);
> +extern void nfsd41_set_cache_entry(struct nfsd4_compoundres *resp);
> +extern __be32 nfsd41_replay_cache_entry(struct nfsd4_compoundres *resp);
> extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
> struct nfsd4_compound_state *,
> struct nfsd4_exchange_id *);
next prev parent reply other threads:[~2008-11-17 14:14 UTC|newest]
Thread overview: 85+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-10 20:12 [RFC 0/51] nfs41 server patches for review Benny Halevy
2008-11-10 20:16 ` [RFC 01/51] nfsd: add etoosmall to nfserrno Benny Halevy
2008-11-10 20:39 ` [pnfs] [RFC 0/51] nfs41 server patches for review Benny Halevy
2008-11-10 20:40 ` [RFC 01/51] nfsd: add etoosmall to nfserrno Benny Halevy
2008-11-10 20:41 ` [RFC 02/51] nfsd: dprint each op status in nfsd4_proc_compound Benny Halevy
2008-11-17 13:56 ` [pnfs] " Benny Halevy
2008-11-10 20:41 ` [RFC 03/51] nfsd: git rid of nfs4_cb_null_ops declaration Benny Halevy
2008-11-10 20:41 ` [RFC 04/51] nfsd: fix file comment in fs/nfsd/nfs4xdr.c Benny Halevy
2008-11-17 13:56 ` [pnfs] " Benny Halevy
2008-11-10 20:42 ` [RFC 05/51] nfsd41: Add Kconfig symbols for NFSv4.1 Benny Halevy
2008-11-10 20:42 ` [RFC 06/51] nfsd41: define nfs41 error codes Benny Halevy
2008-11-10 20:43 ` [RFC 07/51] nfsd41: sessions basic data types Benny Halevy
2008-11-17 13:57 ` [pnfs] " Benny Halevy
2008-11-10 20:43 ` [RFC 08/51] nfsd41: introduce nfs4_client cl_sessions list Benny Halevy
2008-11-17 13:58 ` [pnfs] " Benny Halevy
2008-11-10 20:43 ` [RFC 09/51] nfsd41: destroy_session when client is expired Benny Halevy
2008-11-10 20:44 ` [RFC 10/51] nfsd41: sessionid hashing Benny Halevy
2008-11-17 13:58 ` [pnfs] " Benny Halevy
2008-11-10 20:44 ` [RFC 11/51] FIXME: nfsd41: reduce server lease time for nfs41 Benny Halevy
2008-11-17 13:59 ` [pnfs] " Benny Halevy
2008-11-10 20:44 ` [RFC 12/51] nfsd41: provide support for minor version 1 at rpc level Benny Halevy
2008-11-17 14:00 ` [pnfs] " Benny Halevy
2008-11-10 20:45 ` [RFC 13/51] FIXME: nfsd41: introduce current_session Benny Halevy
2008-11-17 14:00 ` [pnfs] " Benny Halevy
2008-11-10 20:45 ` [RFC 14/51] nfsd41: introduce nfs41_{get,set}_slot_state Benny Halevy
2008-11-17 14:01 ` [pnfs] " Benny Halevy
2008-11-10 20:45 ` [RFC 15/51] FIXME: nfsd41: free up slot unless operation is dropped Benny Halevy
2008-11-17 14:01 ` [pnfs] " Benny Halevy
2008-11-10 20:46 ` [RFC 16/51] nfsd41: stateid handling Benny Halevy
2008-11-17 14:02 ` [pnfs] " Benny Halevy
2008-11-10 20:46 ` [RFC 17/51] nfsd41: clientid handling Benny Halevy
2008-11-17 14:03 ` [pnfs] " Benny Halevy
2008-11-10 20:46 ` [RFC 18/51] nfsd41: access_valid Benny Halevy
2008-11-17 14:04 ` [pnfs] " Benny Halevy
2008-11-10 20:47 ` [RFC 19/51] nfsd41: add OPEN4_SHARE_ACCESS_WANT nfs4_stateid bmap Benny Halevy
2008-11-17 14:05 ` [pnfs] " Benny Halevy
2008-11-10 20:47 ` [RFC 20/51] nfsd: last_byte_offset Benny Halevy
2008-11-17 14:06 ` [pnfs] " Benny Halevy
2008-11-10 20:47 ` [RFC 21/51] nfsd41: xdr stubs Benny Halevy
2008-11-17 14:06 ` [pnfs] " Benny Halevy
2008-11-10 20:48 ` [RFC 22/51] nfsd41: proc stubs Benny Halevy
2008-11-17 14:07 ` [pnfs] " Benny Halevy
2008-11-10 20:48 ` [RFC 23/51] nfsd41: exchange_id operation Benny Halevy
2008-11-17 14:07 ` [pnfs] " Benny Halevy
2008-11-10 20:48 ` [RFC 24/51] nfsd41: print exchange flags when purging client Benny Halevy
2008-11-17 14:08 ` [pnfs] " Benny Halevy
2008-11-10 20:49 ` [RFC 25/51] nfsd41: create_session operation Benny Halevy
2008-11-17 14:09 ` [pnfs] " Benny Halevy
2008-11-10 20:49 ` [RFC 26/51] nfsd41: destroy_session operation Benny Halevy
2008-11-17 14:10 ` [pnfs] " Benny Halevy
2008-11-10 20:49 ` [RFC 27/51] nfsd41: sequence operation Benny Halevy
2008-11-17 14:10 ` [pnfs] " Benny Halevy
2008-11-10 20:50 ` [RFC 28/51] FIXME: nfsd41: sunrpc: Added rpc server-side backchannel handling Benny Halevy
2008-11-17 14:11 ` [pnfs] " Benny Halevy
2008-11-10 20:50 ` [RFC 29/51] nfsd: BUG_ON_UNLOCKED_STATE Benny Halevy
2008-11-10 20:50 ` [RFC 30/51] nfsd: lock state around nfs4_put_delegation in nfsd_break_deleg_cb err path Benny Halevy
2008-11-10 20:51 ` [RFC 31/51] FIXME: nfsd: kref_get cb_client while doing the callback Benny Halevy
2008-11-10 20:51 ` [RFC 32/51] nfsd41: callback infrastructure Benny Halevy
2008-11-17 14:12 ` [pnfs] " Benny Halevy
2008-11-10 20:52 ` [RFC 33/51] nfsd41: introduce cl_cb_mutex Benny Halevy
2008-11-10 20:52 ` [RFC 34/51] nfsd41: cb_sequence callback Benny Halevy
2008-11-10 20:52 ` [RFC 35/51] nfsd41: introduce nfs4_cb_call_sync for nfs4 and nfs41 Benny Halevy
2008-11-10 20:53 ` [RFC 36/51] nfsd41: cb_recall callback Benny Halevy
2008-11-10 20:53 ` [RFC 37/51] nfsd41: pass writable attrs mask to nfsd4_decode_fattr Benny Halevy
2008-11-10 20:53 ` [RFC 38/51] nfsd41: support for 3-word long attribute bitmask Benny Halevy
2008-11-17 14:13 ` [pnfs] " Benny Halevy
2008-11-10 20:54 ` [RFC 39/51] nfsd41: SUPPATTR_EXCLCREAT attribute Benny Halevy
2008-11-10 20:54 ` [RFC 40/51] nfsd41: CREATE_EXCLUSIVE4_1 Benny Halevy
2008-11-17 14:13 ` [pnfs] " Benny Halevy
2008-11-10 20:54 ` [RFC 41/51] sunrpc: Add deferral save and restore state callback Benny Halevy
2008-11-10 20:55 ` [RFC 42/51] nfsd: save and restore defer result pages Benny Halevy
2008-11-10 20:55 ` [RFC 43/51] nfsd: deferral processing Benny Halevy
2008-11-10 20:55 ` [RFC 44/51] nfsd41: slab cache for current session Benny Halevy
2008-11-17 14:14 ` [pnfs] " Benny Halevy
2008-11-10 20:56 ` [RFC 45/51] nfsd41: DRC save, restore, and clear functions Benny Halevy
2008-11-17 14:14 ` Benny Halevy [this message]
2008-11-10 20:56 ` [RFC 46/51] nfsd41: nfsd nfsd4_sequence DRC logic Benny Halevy
2008-11-10 20:56 ` [RFC 47/51] nfsd41: enforce NFS4ERR_SEQUENCE_POS operation order rules Benny Halevy
2008-11-17 14:15 ` [pnfs] " Benny Halevy
2008-11-10 20:57 ` [RFC 48/51] nfsd41: nfsd DRC logic Benny Halevy
2008-11-10 20:57 ` [RFC 49/51] nfsd41: clear DRC cache on free_session Benny Halevy
2008-11-10 20:57 ` [RFC 50/51] nfsd41: Add a create session replay cache Benny Halevy
2008-11-17 14:16 ` [pnfs] " Benny Halevy
2008-11-10 20:58 ` [RFC 51/51] nfsd41: print DRC statistics Benny Halevy
2008-11-17 14:17 ` [pnfs] " Benny Halevy
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=49217C5A.1060406@panasas.com \
--to=bhalevy@panasas.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 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.