All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Chuck Lever <cel@kernel.org>, NeilBrown <neil@brown.name>,
	Olga Kornievskaia <okorniev@redhat.com>,
	Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH 2/5] NFSD: Eliminate percpu counter contention in DRC memory accounting
Date: Fri, 17 Jul 2026 07:35:54 -0400	[thread overview]
Message-ID: <8468bd59a86850d7aee57186ef53feff2f493a61.camel@kernel.org> (raw)
In-Reply-To: <20260717001232.438792-3-cel@kernel.org>

On Thu, 2026-07-16 at 20:12 -0400, Chuck Lever wrote:
> The DRC memory usage counter (NFSD_STATS_DRC_MEM_USAGE) tracks
> bytes, but percpu_counter_add() uses the global percpu_counter_batch
> threshold of max(32, 2*nr_cpus). Each DRC entry add or removal
> updates the counter by sizeof(struct nfsd_cacherep) (~144 bytes),
> which always exceeds the batch threshold. percpu_counter_add()
> then acquires the counter's global spinlock on every update,
> serializing all nfsd threads.
> 

Dear god -- I had no idea that this was a thing. I wonder if we have
other places we're using percpu_counter_add() where we shouldn't?

> On a 10-CPU NFS server handling a high rate of non-idempotent
> NFSv3 operations, this lock accounts for a measurable fraction
> of total spin lock overhead because nfsd_cache_lookup() both
> inserts a new entry and prunes up to three old entries per RPC,
> producing 4-7 global lock acquisitions per operation.
> 
> Switch to percpu_counter_add_local() and percpu_counter_sub_local(),
> which batch with INT_MAX so that updates always remain on the per-CPU
> fast path regardless of the amount. The only reader of this counter uses
> percpu_counter_sum_positive(), which sums the per-CPU deltas under the
> global lock, so read accuracy is unaffected.
> 
> Signed-off-by: Chuck Lever <cel@kernel.org>
> ---
>  fs/nfsd/stats.h | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfsd/stats.h b/fs/nfsd/stats.h
> index 87736b7fbf28..15d30c045dc3 100644
> --- a/fs/nfsd/stats.h
> +++ b/fs/nfsd/stats.h
> @@ -60,14 +60,32 @@ static inline void nfsd_stats_payload_misses_inc(struct nfsd_net *nn)
>  	percpu_counter_inc(&nn->counter[NFSD_STATS_PAYLOAD_MISSES]);
>  }
>  
> +/**
> + * nfsd_stats_drc_mem_usage_add - Add memory used by a cache item
> + * @nn: target network namespace
> + * @amount: byte count
> + *
> + * percpu_counter_add_local() keeps updates on the per-CPU fast
> + * path. The sole reader, percpu_counter_sum_positive(), sums the
> + * per-CPU deltas, so batching locally does not lose accuracy.
> + */
>  static inline void nfsd_stats_drc_mem_usage_add(struct nfsd_net *nn, s64 amount)
>  {
> -	percpu_counter_add(&nn->counter[NFSD_STATS_DRC_MEM_USAGE], amount);
> +	percpu_counter_add_local(&nn->counter[NFSD_STATS_DRC_MEM_USAGE],
> +				 amount);
>  }
>  
> +/**
> + * nfsd_stats_drc_mem_usage_sub - Subtract memory used by a cache item
> + * @nn: target network namespace
> + * @amount: byte count
> + *
> + * See nfsd_stats_drc_mem_usage_add() for batching rationale.
> + */
>  static inline void nfsd_stats_drc_mem_usage_sub(struct nfsd_net *nn, s64 amount)
>  {
> -	percpu_counter_sub(&nn->counter[NFSD_STATS_DRC_MEM_USAGE], amount);
> +	percpu_counter_sub_local(&nn->counter[NFSD_STATS_DRC_MEM_USAGE],
> +				 amount);
>  }
>  
>  #ifdef CONFIG_NFSD_V4

-- 
Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2026-07-17 11:35 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-17  0:12 [PATCH 0/5] Minor NFSD global DRC clean-ups Chuck Lever
2026-07-17  0:12 ` [PATCH 1/5] NFSD: Fix off-by-one in DRC bucket pruning limit Chuck Lever
2026-07-17  0:12 ` [PATCH 2/5] NFSD: Eliminate percpu counter contention in DRC memory accounting Chuck Lever
2026-07-17 11:35   ` Jeff Layton [this message]
2026-07-17  0:12 ` [PATCH 3/5] NFSD: Eliminate percpu counter contention in reply cache statistics Chuck Lever
2026-07-17  0:12 ` [PATCH 4/5] NFSD: Eliminate percpu counter contention in IO byte accounting Chuck Lever
2026-07-17  0:12 ` [PATCH 5/5] NFSD: Document reply_cache_stats ABI Chuck Lever
2026-07-17  4:44 ` [PATCH 0/5] Minor NFSD global DRC clean-ups NeilBrown
2026-07-17 11:38 ` Jeff Layton

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=8468bd59a86850d7aee57186ef53feff2f493a61.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=cel@kernel.org \
    --cc=dai.ngo@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --cc=okorniev@redhat.com \
    --cc=tom@talpey.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 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.