Commit 35308e7f authored by Chuck Lever's avatar Chuck Lever

NFSD: Refactor nfsd_reply_cache_free_locked()

To reduce contention on the bucket locks, we must avoid calling
kfree() while each bucket lock is held.

Start by refactoring nfsd_reply_cache_free_locked() into a helper
that removes an entry from the bucket (and must therefore run under
the lock) and a second helper that frees the entry (which does not
need to hold the lock).

For readability, rename the helpers nfsd_cacherep_<verb>.
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 2a9893f7
...@@ -110,21 +110,33 @@ nfsd_reply_cache_alloc(struct svc_rqst *rqstp, __wsum csum, ...@@ -110,21 +110,33 @@ nfsd_reply_cache_alloc(struct svc_rqst *rqstp, __wsum csum,
return rp; return rp;
} }
static void nfsd_cacherep_free(struct svc_cacherep *rp)
{
if (rp->c_type == RC_REPLBUFF)
kfree(rp->c_replvec.iov_base);
kmem_cache_free(drc_slab, rp);
}
static void static void
nfsd_reply_cache_free_locked(struct nfsd_drc_bucket *b, struct svc_cacherep *rp, nfsd_cacherep_unlink_locked(struct nfsd_net *nn, struct nfsd_drc_bucket *b,
struct nfsd_net *nn) struct svc_cacherep *rp)
{ {
if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) { if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base)
nfsd_stats_drc_mem_usage_sub(nn, rp->c_replvec.iov_len); nfsd_stats_drc_mem_usage_sub(nn, rp->c_replvec.iov_len);
kfree(rp->c_replvec.iov_base);
}
if (rp->c_state != RC_UNUSED) { if (rp->c_state != RC_UNUSED) {
rb_erase(&rp->c_node, &b->rb_head); rb_erase(&rp->c_node, &b->rb_head);
list_del(&rp->c_lru); list_del(&rp->c_lru);
atomic_dec(&nn->num_drc_entries); atomic_dec(&nn->num_drc_entries);
nfsd_stats_drc_mem_usage_sub(nn, sizeof(*rp)); nfsd_stats_drc_mem_usage_sub(nn, sizeof(*rp));
} }
kmem_cache_free(drc_slab, rp); }
static void
nfsd_reply_cache_free_locked(struct nfsd_drc_bucket *b, struct svc_cacherep *rp,
struct nfsd_net *nn)
{
nfsd_cacherep_unlink_locked(nn, b, rp);
nfsd_cacherep_free(rp);
} }
static void static void
...@@ -132,8 +144,9 @@ nfsd_reply_cache_free(struct nfsd_drc_bucket *b, struct svc_cacherep *rp, ...@@ -132,8 +144,9 @@ nfsd_reply_cache_free(struct nfsd_drc_bucket *b, struct svc_cacherep *rp,
struct nfsd_net *nn) struct nfsd_net *nn)
{ {
spin_lock(&b->cache_lock); spin_lock(&b->cache_lock);
nfsd_reply_cache_free_locked(b, rp, nn); nfsd_cacherep_unlink_locked(nn, b, rp);
spin_unlock(&b->cache_lock); spin_unlock(&b->cache_lock);
nfsd_cacherep_free(rp);
} }
int nfsd_drc_slab_create(void) int nfsd_drc_slab_create(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment