All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: linux-xfs@vger.kernel.org
Subject: [PATCH 20/27] libxfs: add internal lru to btcache
Date: Thu, 15 Oct 2020 18:21:48 +1100	[thread overview]
Message-ID: <20201015072155.1631135-21-david@fromorbit.com> (raw)
In-Reply-To: <20201015072155.1631135-1-david@fromorbit.com>

From: Dave Chinner <dchinner@redhat.com>

THis tracks all the buffers in a given btcache, hence allowing us to
purge all the buffers from a cache without having to walk the global
buffer cache LRU list.

This will useful for per-AG scan operations, allowing us to purge
the cache when we've completed processing on specific AGs and don't
need the cache anymore.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 libxfs/buftarg.c     | 63 +++++++++++++++++++++++++++++++++++++++++++-
 libxfs/libxfs_io.h   |  8 ++++++
 libxfs/rdwr.c        |  4 +--
 libxfs/xfs_buftarg.h |  2 ++
 4 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/libxfs/buftarg.c b/libxfs/buftarg.c
index 4f4254e4fd70..dbecab833cb2 100644
--- a/libxfs/buftarg.c
+++ b/libxfs/buftarg.c
@@ -428,8 +428,16 @@ xfs_buf_associate_memory(
 
 /*
  * Buffer cache hash implementation
+*
+ * Lock orders:
+ *
+ * hash->lock		cache hash chain lock
+ *  btc->lock		cache lock
+ *
+ * btc->lock		cache lock
+ *  bp->b_lock		buffer state lock
+ *
  */
-
 struct btcache *
 btc_init(
 	unsigned int	hashsize)
@@ -456,6 +464,7 @@ btc_init(
 	btc->hashsize = hashsize;
 	btc->hashshift = libxfs_highbit32(hashsize);
 	pthread_mutex_init(&btc->lock, NULL);
+	list_head_init(&btc->lru);
 
 	for (i = 0; i < hashsize; i++) {
 		list_head_init(&btc->hash[i].chain);
@@ -475,6 +484,7 @@ btc_destroy(
 	if (!btc)
 		return;
 
+	list_head_destroy(&btc->lru);
 	for (i = 0; i < btc->hashsize; i++) {
 		list_head_destroy(&btc->hash[i].chain);
 		pthread_mutex_destroy(&btc->hash[i].lock);
@@ -635,6 +645,10 @@ btc_node_insert(
 	head = &hash->chain;
 
 	pthread_mutex_lock(&hash->lock);
+	pthread_mutex_lock(&btc->lock);
+	list_add(&bp->b_btc_list, &btc->lru);
+	pthread_mutex_unlock(&btc->lock);
+
 	list_add(&bp->b_hash, head);
 	hash->count++;
 	atomic_inc(&btc->count);
@@ -653,8 +667,55 @@ btc_node_remove(
 	hash = btc->hash + hashidx;
 
 	pthread_mutex_lock(&hash->lock);
+	pthread_mutex_lock(&btc->lock);
+	list_del(&bp->b_btc_list);
+	pthread_mutex_unlock(&btc->lock);
+
 	list_del(&bp->b_hash);
 	hash->count--;
 	atomic_dec(&btc->count);
 	pthread_mutex_unlock(&hash->lock);
 }
+
+/*
+ * Purge the buffers from the cache list.
+ *
+ * This is nasty - it steals the buffer cache LRU reference and drops it,
+ * using the dispose flag to indicate it's about to go away.
+ */
+static void
+btc_purge_buffers(
+	struct btcache		*btc)
+{
+	struct xfs_buf          *bp, *n;
+	LIST_HEAD               (dispose);
+
+	pthread_mutex_lock(&btc->lock);
+	list_for_each_entry_safe(bp, n, &btc->lru, b_btc_list) {
+		if (bp->b_state & XFS_BSTATE_DISPOSE)
+			continue;
+		spin_lock(&bp->b_lock);
+		atomic_set(&bp->b_lru_ref, 0);
+		bp->b_state |= XFS_BSTATE_DISPOSE;
+		list_move(&bp->b_btc_list, &dispose);
+		spin_unlock(&bp->b_lock);
+	}
+	pthread_mutex_unlock(&btc->lock);
+
+	while (!list_empty(&dispose)) {
+		bp = list_first_entry(&dispose, struct xfs_buf, b_btc_list);
+		list_del_init(&bp->b_btc_list);
+		libxfs_brelse(&bp->b_node);
+	}
+}
+
+void
+xfs_buftarg_purge_ag(
+	struct xfs_buftarg	*btp,
+	xfs_agnumber_t		agno)
+{
+	struct xfs_perag	*pag = xfs_perag_get(btp->bt_mount, agno);
+
+	btc_purge_buffers(pag->pag_buf_hash);
+	xfs_perag_put(pag);
+}
diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
index 31c21abce8c9..2e7c943d8978 100644
--- a/libxfs/libxfs_io.h
+++ b/libxfs/libxfs_io.h
@@ -42,6 +42,8 @@ struct xfs_buf_ops {
 	xfs_failaddr_t (*verify_struct)(struct xfs_buf *);
 };
 
+#define XFS_BSTATE_DISPOSE       (1 << 0)       /* buffer being discarded */
+
 struct xfs_buf {
 	struct cache_node	b_node;
 	struct list_head	b_hash;	/* will replace b_node */
@@ -66,6 +68,10 @@ struct xfs_buf {
 	int			b_io_remaining;
 	int			b_io_error;
 	struct list_head	b_list;
+
+	struct list_head	b_btc_list;
+	unsigned int		b_state;
+	atomic_t		b_lru_ref;
 };
 
 bool xfs_verify_magic(struct xfs_buf *bp, __be32 dmagic);
@@ -98,6 +104,8 @@ int libxfs_buf_priority(struct xfs_buf *bp);
 
 extern struct cache	*libxfs_bcache;
 extern struct cache_operations	libxfs_bcache_operations;
+void libxfs_brelse(struct cache_node *node);
+
 
 #define LIBXFS_GETBUF_TRYLOCK	(1 << 0)
 
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 371a6d221bb2..fcc4ff9b394e 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -21,8 +21,6 @@
 
 #include "libxfs.h"
 
-static void libxfs_brelse(struct cache_node *node);
-
 /*
  * Important design/architecture note:
  *
@@ -740,7 +738,7 @@ libxfs_whine_dirty_buf(
 	bp->b_target->flags |= XFS_BUFTARG_LOST_WRITE;
 }
 
-static void
+void
 libxfs_brelse(
 	struct cache_node	*node)
 {
diff --git a/libxfs/xfs_buftarg.h b/libxfs/xfs_buftarg.h
index fee20c60db1c..129b43e037ad 100644
--- a/libxfs/xfs_buftarg.h
+++ b/libxfs/xfs_buftarg.h
@@ -55,6 +55,7 @@ struct xfs_buftarg *xfs_buftarg_alloc(struct xfs_mount *mp, dev_t bdev);
 void xfs_buftarg_free(struct xfs_buftarg *target);
 void xfs_buftarg_wait(struct xfs_buftarg *target);
 int xfs_buftarg_setsize(struct xfs_buftarg *target, unsigned int size);
+void xfs_buftarg_purge_ag(struct xfs_buftarg *btp, xfs_agnumber_t agno);
 
 #define xfs_getsize_buftarg(buftarg)	block_size((buftarg)->bt_bdev)
 
@@ -136,6 +137,7 @@ struct btcache {
 	unsigned long long	misses;		/* cache misses */
 	unsigned long long	hits;		/* cache hits */
 	unsigned int		max;		/* max nodes ever used */
+	struct list_head	lru;		/* list of all items in cache */
 };
 
 struct btcache *btc_init(unsigned int hashsize);
-- 
2.28.0


  parent reply	other threads:[~2020-10-15  7:22 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-15  7:21 [PATCH 00/27] [RFC, WIP] xfsprogs: xfs_buf unification and AIO Dave Chinner
2020-10-15  7:21 ` [PATCH 01/27] xfsprogs: remove unused buffer tracing code Dave Chinner
2020-10-15  7:21 ` [PATCH 02/27] xfsprogs: remove unused IO_DEBUG functionality Dave Chinner
2020-11-16  2:31   ` Eric Sandeen
2020-10-15  7:21 ` [PATCH 03/27] libxfs: get rid of b_bcount from xfs_buf Dave Chinner
2020-11-23 19:53   ` Eric Sandeen
2020-10-15  7:21 ` [PATCH 04/27] libxfs: rename buftarg->dev to btdev Dave Chinner
2020-11-16  2:33   ` Eric Sandeen
2020-10-15  7:21 ` [PATCH 05/27] xfsprogs: get rid of ancient btree tracing fragments Dave Chinner
2020-11-16  2:35   ` Eric Sandeen
2020-10-15  7:21 ` [PATCH 06/27] xfsprogs: remove xfs_buf_t typedef Dave Chinner
2020-10-15 15:22   ` Darrick J. Wong
2020-10-15 20:54     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 07/27] xfsprogs: introduce liburcu support Dave Chinner
2020-10-15  7:21 ` [PATCH 08/27] libxfs: add spinlock_t wrapper Dave Chinner
2020-10-15  7:21 ` [PATCH 09/27] atomic: convert to uatomic Dave Chinner
2020-10-15  7:21 ` [PATCH 10/27] libxfs: add kernel-compatible completion API Dave Chinner
2020-10-15 17:09   ` Darrick J. Wong
2020-10-19 22:21     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 11/27] libxfs: add wrappers for kernel semaphores Dave Chinner
2020-10-15  7:21 ` [PATCH 12/27] xfsprogs: convert use-once buffer reads to uncached IO Dave Chinner
2020-10-15 17:12   ` Darrick J. Wong
2020-10-19 22:36     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 13/27] libxfs: introduce userspace buftarg infrastructure Dave Chinner
2020-10-15  7:21 ` [PATCH 14/27] xfs: rename libxfs_buftarg_init to libxfs_open_devices() Dave Chinner
2020-10-15  7:21 ` [PATCH 15/27] libxfs: introduce userspace buftarg infrastructure Dave Chinner
2020-10-15 17:16   ` Darrick J. Wong
2020-10-15  7:21 ` [PATCH 16/27] libxfs: add a synchronous IO engine to the buftarg Dave Chinner
2020-10-15  7:21 ` [PATCH 17/27] xfsprogs: convert libxfs_readbufr to libxfs_buf_read_uncached Dave Chinner
2020-10-15  7:21 ` [PATCH 18/27] libxfs: convert libxfs_bwrite to buftarg IO Dave Chinner
2020-10-15  7:21 ` [PATCH 19/27] libxfs: add cache infrastructure to buftarg Dave Chinner
2020-10-15  7:21 ` Dave Chinner [this message]
2020-10-15  7:21 ` [PATCH 21/27] libxfs: Add kernel list_lru wrapper Dave Chinner
2020-10-15  7:21 ` [PATCH 22/27] libxfs: introduce new buffer cache infrastructure Dave Chinner
2020-10-15 17:46   ` Darrick J. Wong
2020-10-15  7:21 ` [PATCH 23/27] libxfs: use PSI information to detect memory pressure Dave Chinner
2020-10-15 17:56   ` Darrick J. Wong
2020-10-15 21:20     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 24/27] libxfs: add a buftarg cache shrinker implementation Dave Chinner
2020-10-15 18:01   ` Darrick J. Wong
2020-10-15 21:33     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 25/27] libxfs: switch buffer cache implementations Dave Chinner
2020-10-15  7:21 ` [PATCH 26/27] build: set platform_defs.h.in dependency correctly Dave Chinner
2020-10-15  7:21 ` [PATCH 27/27] libxfs: convert sync IO buftarg engine to AIO Dave Chinner
2020-10-15 18:26   ` Darrick J. Wong
2020-10-15 21:42     ` Dave Chinner
2020-10-15  7:29 ` [PATCH 00/27] [RFC, WIP] xfsprogs: xfs_buf unification and AIO Dave Chinner
2020-10-15 18:37 ` Darrick J. Wong
2020-10-15 22:35   ` Dave Chinner

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=20201015072155.1631135-21-david@fromorbit.com \
    --to=david@fromorbit.com \
    --cc=linux-xfs@vger.kernel.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.