All of lore.kernel.org
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.de>
To: Chuck Lever <chuck.lever@oracle.com>, Jeff Layton <jlayton@kernel.org>
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: [PATCH 6/7] nfsd: filecache: change garbage collection to a timer.
Date: Mon, 27 Jan 2025 12:20:37 +1100	[thread overview]
Message-ID: <20250127012257.1803314-7-neilb@suse.de> (raw)
In-Reply-To: <20250127012257.1803314-1-neilb@suse.de>

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 */
-	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);
 }
 
 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));
-- 
2.47.1


  parent reply	other threads:[~2025-01-27  1:24 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 ` NeilBrown [this message]
2025-01-27 14:39   ` [PATCH 6/7] nfsd: filecache: change garbage collection to a timer Jeff Layton
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=20250127012257.1803314-7-neilb@suse.de \
    --to=neilb@suse.de \
    --cc=Dai.Ngo@oracle.com \
    --cc=chuck.lever@oracle.com \
    --cc=david@fromorbit.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --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.