public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: NeilBrown <neilb@suse.de>, Chuck Lever <chuck.lever@oracle.com>
Cc: linux-nfs@vger.kernel.org,
	Olga Kornievskaia <okorniev@redhat.com>,
	Dai Ngo	 <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
	Dave Chinner	 <david@fromorbit.com>
Subject: Re: [PATCH 6/7] nfsd: filecache: change garbage collection to a timer.
Date: Mon, 27 Jan 2025 09:39:09 -0500	[thread overview]
Message-ID: <7735374ea376d966042160332bb8e9012a54187e.camel@kernel.org> (raw)
In-Reply-To: <20250127012257.1803314-7-neilb@suse.de>

On Mon, 2025-01-27 at 12:20 +1100, NeilBrown wrote:
> garbage collection never sleeps and no longer walks a list so it runs
> quickly only requiring a spinlock.
> 
> This means we don't need to use a workqueue, we can use a simple timer
> instead.
> 
> Rather than taking the lock in the timer callback, which would require
> using _bh locking, simply test a flag and wake an nfsd thread.  That
> thread checks the flag and ages the lists when needed.
> 
> Signed-off-by: NeilBrown <neilb@suse.de>
> ---
>  fs/nfsd/filecache.c | 43 ++++++++++++++++++++++++-------------------
>  1 file changed, 24 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
> index 7264faa57280..eb95a53f806f 100644
> --- a/fs/nfsd/filecache.c
> +++ b/fs/nfsd/filecache.c
> @@ -67,10 +67,12 @@ struct nfsd_fcache_disposal {
>  	struct list_head older;	/* haven't been used in last 0-2 seconds */
>  	struct list_head freeme; /* ready to be discarded */
>  	unsigned long num_gc; /* Approximate size of recent plus older */

Dang, adding flags would push this into 
> -	struct delayed_work filecache_laundrette;
> +	struct timer_list timer;
>  	struct shrinker *file_shrinker;
>  	struct nfsd_net *nn;
> +	unsigned long flags;
>  };
> +#define NFSD_FCACHE_DO_AGE	BIT(0)	/* time to age the lists */
>  
>  static struct kmem_cache		*nfsd_file_slab;
>  static struct kmem_cache		*nfsd_file_mark_slab;
> @@ -115,8 +117,8 @@ static const struct rhashtable_params nfsd_file_rhash_params = {
>  static void
>  nfsd_file_schedule_laundrette(struct nfsd_fcache_disposal *l)
>  {
> -	queue_delayed_work(system_unbound_wq, &l->filecache_laundrette,
> -			   NFSD_LAUNDRETTE_DELAY);
> +	if (!timer_pending(&l->timer))
> +		mod_timer(&l->timer, jiffies + NFSD_LAUNDRETTE_DELAY);
>  }
>  
>  static void
> @@ -521,6 +523,19 @@ void nfsd_file_net_dispose(struct nfsd_net *nn)
>  {
>  	struct nfsd_fcache_disposal *l = nn->fcache_disposal;
>  
> +	if (test_and_clear_bit(NFSD_FCACHE_DO_AGE, &l->flags)) {
> +		spin_lock(&l->lock);
> +		list_splice_init(&l->older, &l->freeme);
> +		list_splice_init(&l->recent, &l->older);
> +		/* We don't know how many were moved to 'freeme' and don't want
> +		 * to waste time counting - guess a half.  This is only used
> +		 * for the shrinker which doesn't need complete precision.
> +		 */
> +		l->num_gc /= 2;
> +		if (!list_empty(&l->older) || !list_empty(&l->recent))
> +			mod_timer(&l->timer, jiffies + NFSD_LAUNDRETTE_DELAY);
> +		spin_unlock(&l->lock);
> +	}
>  	if (!list_empty(&l->freeme)) {
>  		LIST_HEAD(dispose);
>  		int i;
> @@ -557,23 +572,13 @@ void nfsd_file_net_dispose(struct nfsd_net *nn)
>  }
>  
>  static void
> -nfsd_file_gc_worker(struct work_struct *work)
> +nfsd_file_gc_worker(struct timer_list *t)
>  {
>  	struct nfsd_fcache_disposal *l = container_of(
> -		work, struct nfsd_fcache_disposal, filecache_laundrette.work);
> +		t, struct nfsd_fcache_disposal, timer);
>  
> -	spin_lock(&l->lock);
> -	list_splice_init(&l->older, &l->freeme);
> -	list_splice_init(&l->recent, &l->older);
> -	/* We don't know how many were moved to 'freeme' and don't want
> -	 * to waste time counting - guess a half.
> -	 */
> -	l->num_gc /= 2;
> -	if (!list_empty(&l->freeme))
> -		svc_wake_up(l->nn->nfsd_serv);
> -	if (!list_empty(&l->older) || !list_empty(&l->recent))
> -		nfsd_file_schedule_laundrette(l);
> -	spin_unlock(&l->lock);
> +	set_bit(NFSD_FCACHE_DO_AGE, &l->flags);
> +	svc_wake_up(l->nn->nfsd_serv);

Disregard my earlier comment about the cacheline. It still wouldn't
hurt to do, but since you're not actually taking the lock inside the
timer callback in this version, it's not as big a deal.

This seems better.

>  }
>  
>  static unsigned long
> @@ -868,7 +873,7 @@ nfsd_alloc_fcache_disposal(void)
>  	if (!l)
>  		return NULL;
>  	spin_lock_init(&l->lock);
> -	INIT_DELAYED_WORK(&l->filecache_laundrette, nfsd_file_gc_worker);
> +	timer_setup(&l->timer, nfsd_file_gc_worker, 0);
>  	INIT_LIST_HEAD(&l->recent);
>  	INIT_LIST_HEAD(&l->older);
>  	INIT_LIST_HEAD(&l->freeme);
> @@ -891,7 +896,7 @@ nfsd_alloc_fcache_disposal(void)
>  static void
>  nfsd_free_fcache_disposal(struct nfsd_fcache_disposal *l)
>  {
> -	cancel_delayed_work_sync(&l->filecache_laundrette);
> +	del_timer_sync(&l->timer);
>  	shrinker_free(l->file_shrinker);
>  	nfsd_file_release_list(&l->recent);
>  	WARN_ON_ONCE(!list_empty(&l->recent));

Reviewed-by: Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2025-01-27 14:39 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-27  1:20 [PATCH 0/7] nfsd: filecache: change garbage collection lists NeilBrown
2025-01-27  1:20 ` [PATCH 1/7] nfsd: filecache: remove race handling NeilBrown
2025-01-27 13:42   ` Jeff Layton
2025-01-27  1:20 ` [PATCH 2/7] nfsd: filecache: use nfsd_file_dispose_list() in nfsd_file_close_inode_sync() NeilBrown
2025-01-27  1:20 ` [PATCH 3/7] nfsd: filecache: move globals nfsd_file_lru and nfsd_file_shrinker to be per-net NeilBrown
2025-01-27  1:20 ` [PATCH 4/7] nfsd: filecache: change garbage collection list management NeilBrown
2025-01-27 14:15   ` Jeff Layton
2025-01-27  1:20 ` [PATCH 5/7] nfsd: filecache: document the arbitrary limit on file-disposes-per-loop NeilBrown
2025-01-27 14:40   ` Jeff Layton
2025-01-27  1:20 ` [PATCH 6/7] nfsd: filecache: change garbage collection to a timer NeilBrown
2025-01-27 14:39   ` Jeff Layton [this message]
2025-01-27  1:20 ` [PATCH 7/7] nfsd: filecache: give disposal lock a unique class name NeilBrown
2025-01-27 14:29   ` Chuck Lever
2025-01-27 14:40   ` Jeff Layton
2025-01-28  6:37 ` [PATCH 0/7] nfsd: filecache: change garbage collection lists Dave Chinner
2025-01-28 14:27   ` Chuck Lever
2025-01-28 16:05     ` Chuck Lever
2025-01-29 21:34   ` NeilBrown
2025-02-06  2:21     ` Dave Chinner
2025-02-06  3:04       ` NeilBrown
2025-02-06 14:35         ` Chuck Lever
2025-02-05 23:04 ` NeilBrown
2025-02-06  3:02   ` Chuck Lever

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=7735374ea376d966042160332bb8e9012a54187e.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=Dai.Ngo@oracle.com \
    --cc=chuck.lever@oracle.com \
    --cc=david@fromorbit.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neilb@suse.de \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox