Linux-XFS Archive on lore.kernel.org
 help / color / 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
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 index

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

Linux-XFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-xfs/0 linux-xfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-xfs linux-xfs/ https://lore.kernel.org/linux-xfs \
		linux-xfs@vger.kernel.org
	public-inbox-index linux-xfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-xfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git