From: "Darrick J. Wong" <djwong@kernel.org>
To: djwong@kernel.org, ebiggers@kernel.org, aalbersh@redhat.com
Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
fsverity@lists.linux.dev
Subject: [PATCH 16/29] xfs: shrink verity blob cache
Date: Fri, 29 Mar 2024 17:40:14 -0700 [thread overview]
Message-ID: <171175868826.1988170.6498728857662092789.stgit@frogsfrogsfrogs> (raw)
In-Reply-To: <171175868489.1988170.9803938936906955260.stgit@frogsfrogsfrogs>
From: Darrick J. Wong <djwong@kernel.org>
Add some shrinkers so that reclaim can free cached merkle tree blocks
when memory is tight. We add a shrinkref variable to bias reclaim
against freeing the upper levels of the merkle tree in the hope of
maintaining read performance.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/xfs_fsverity.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++-
fs/xfs/xfs_trace.h | 1 +
2 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_fsverity.c b/fs/xfs/xfs_fsverity.c
index 37876ce612540..d675b0f71bde5 100644
--- a/fs/xfs/xfs_fsverity.c
+++ b/fs/xfs/xfs_fsverity.c
@@ -44,6 +44,9 @@ struct xfs_merkle_blob {
/* refcount of this item; the cache holds its own ref */
refcount_t refcount;
+ /* number of times the shrinker should ignore this item */
+ atomic_t shrinkref;
+
unsigned long flags;
/* Pointer to the merkle tree block, which is power-of-2 sized */
@@ -74,6 +77,7 @@ xfs_merkle_blob_alloc(
/* Caller owns this refcount. */
refcount_set(&mk->refcount, 1);
+ atomic_set(&mk->shrinkref, 0);
mk->flags = 0;
return mk;
}
@@ -106,8 +110,10 @@ xfs_fsverity_cache_drop(
struct xfs_inode *ip)
{
XA_STATE(xas, &ip->i_merkle_blocks, 0);
+ struct xfs_mount *mp = ip->i_mount;
struct xfs_merkle_blob *mk;
unsigned long flags;
+ s64 freed = 0;
xas_lock_irqsave(&xas, flags);
xas_for_each(&xas, mk, ULONG_MAX) {
@@ -115,10 +121,13 @@ xfs_fsverity_cache_drop(
trace_xfs_fsverity_cache_drop(ip, xas.xa_index, _RET_IP_);
+ freed++;
xas_store(&xas, NULL);
xfs_merkle_blob_rele(mk);
}
+ percpu_counter_sub(&mp->m_verity_blocks, freed);
xas_unlock_irqrestore(&xas, flags);
+ xfs_inode_clear_verity_tag(ip);
}
/* Destroy the merkle tree block cache */
@@ -177,6 +186,7 @@ xfs_fsverity_cache_store(
unsigned long key,
struct xfs_merkle_blob *mk)
{
+ struct xfs_mount *mp = ip->i_mount;
struct xfs_merkle_blob *old;
unsigned long flags;
@@ -191,6 +201,8 @@ xfs_fsverity_cache_store(
old = __xa_cmpxchg(&ip->i_merkle_blocks, key, NULL, mk,
GFP_KERNEL);
} while (old && !refcount_inc_not_zero(&old->refcount));
+ if (!old)
+ percpu_counter_add(&mp->m_verity_blocks, 1);
xa_unlock_irqrestore(&ip->i_merkle_blocks, flags);
if (old == NULL) {
@@ -303,12 +315,73 @@ struct xfs_fsverity_scan {
unsigned long freed;
};
+/* Reclaim inactive merkle tree blocks that have run out of second chances. */
+static void
+xfs_fsverity_cache_reclaim(
+ struct xfs_inode *ip,
+ struct xfs_fsverity_scan *vs)
+{
+ XA_STATE(xas, &ip->i_merkle_blocks, 0);
+ struct xfs_mount *mp = ip->i_mount;
+ struct xfs_merkle_blob *mk;
+ unsigned long flags;
+ s64 freed = 0;
+
+ xas_lock_irqsave(&xas, flags);
+ xas_for_each(&xas, mk, ULONG_MAX) {
+ /*
+ * Tell the shrinker that we scanned this merkle tree block,
+ * even if we don't remove it.
+ */
+ vs->scanned++;
+ if (vs->sc->nr_to_scan-- == 0)
+ break;
+
+ /* Retain if there are active references */
+ if (refcount_read(&mk->refcount) > 1)
+ continue;
+
+ /* Ignore if the item still has lru refcount */
+ if (atomic_add_unless(&mk->shrinkref, -1, 0))
+ continue;
+
+ trace_xfs_fsverity_cache_reclaim(ip, xas.xa_index, _RET_IP_);
+
+ freed++;
+ xas_store(&xas, NULL);
+ xfs_merkle_blob_rele(mk);
+ }
+ percpu_counter_sub(&mp->m_verity_blocks, freed);
+ xas_unlock_irqrestore(&xas, flags);
+
+ /*
+ * Try to clear the verity tree tag if we reclaimed all the cached
+ * blocks. On the flag setting side, we should have IOLOCK_SHARED.
+ */
+ xfs_ilock(ip, XFS_IOLOCK_EXCL);
+ if (xa_empty(&ip->i_merkle_blocks))
+ xfs_inode_clear_verity_tag(ip);
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+
+ vs->freed += freed;
+}
+
/* Scan an inode as part of a verity scan. */
int
xfs_fsverity_scan_inode(
- struct xfs_inode *ip,
- struct xfs_icwalk *icw)
+ struct xfs_inode *ip,
+ struct xfs_icwalk *icw)
{
+ struct xfs_fsverity_scan *vs;
+
+ vs = container_of(icw, struct xfs_fsverity_scan, icw);
+
+ if (vs->sc->nr_to_scan > 0)
+ xfs_fsverity_cache_reclaim(ip, vs);
+
+ if (vs->sc->nr_to_scan == 0)
+ xfs_icwalk_verity_stop(icw);
+
xfs_irele(ip);
return 0;
}
@@ -606,6 +679,13 @@ xfs_fsverity_read_merkle(
* Free the new cache blob and continue with the existing one.
*/
xfs_merkle_blob_rele(new_mk);
+ } else {
+ /*
+ * We added this merkle tree block to the cache; tag the inode
+ * so that reclaim will scan this inode. The caller holds
+ * IOLOCK_SHARED this will not race with the shrinker.
+ */
+ xfs_inode_set_verity_tag(ip);
}
out_hit:
@@ -613,6 +693,13 @@ xfs_fsverity_read_merkle(
block->context = mk;
block->verified = test_bit(XFS_MERKLE_BLOB_VERIFIED_BIT, &mk->flags);
+ /*
+ * Prioritize keeping the root-adjacent levels cached if this isn't a
+ * streaming read.
+ */
+ if (req->level >= 0)
+ atomic_set(&mk->shrinkref, req->level + 1);
+
return 0;
out_new_mk:
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index a5b811c1731d7..ac7201a24b107 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -5938,6 +5938,7 @@ DEFINE_EVENT(xfs_fsverity_cache_class, name, \
DEFINE_XFS_FSVERITY_CACHE_EVENT(xfs_fsverity_cache_load);
DEFINE_XFS_FSVERITY_CACHE_EVENT(xfs_fsverity_cache_store);
DEFINE_XFS_FSVERITY_CACHE_EVENT(xfs_fsverity_cache_drop);
+DEFINE_XFS_FSVERITY_CACHE_EVENT(xfs_fsverity_cache_reclaim);
TRACE_EVENT(xfs_fsverity_shrinker_count,
TP_PROTO(struct xfs_mount *mp, unsigned long long count,
next prev parent reply other threads:[~2024-03-30 0:40 UTC|newest]
Thread overview: 111+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-30 0:30 [PATCHBOMB v5.5] fs-verity support for XFS Darrick J. Wong
2024-03-30 0:32 ` [PATCHSET v5.5 1/2] fs-verity: support merkle tree access by blocks Darrick J. Wong
2024-03-30 0:32 ` [PATCH 01/13] fs: add FS_XFLAG_VERITY for verity files Darrick J. Wong
2024-03-30 0:33 ` [PATCH 02/13] fsverity: pass tree_blocksize to end_enable_verity() Darrick J. Wong
2024-03-30 0:33 ` [PATCH 03/13] fsverity: support block-based Merkle tree caching Darrick J. Wong
2024-04-05 2:31 ` Eric Biggers
2024-04-24 21:25 ` Darrick J. Wong
2024-04-24 22:08 ` Eric Biggers
2024-04-25 0:27 ` Darrick J. Wong
2024-04-25 0:46 ` Eric Biggers
2024-04-25 0:53 ` Darrick J. Wong
2024-03-30 0:33 ` [PATCH 04/13] fsverity: add per-sb workqueue for post read processing Darrick J. Wong
2024-04-05 2:39 ` Eric Biggers
2024-04-24 21:33 ` Darrick J. Wong
2024-03-30 0:33 ` [PATCH 05/13] fsverity: add tracepoints Darrick J. Wong
2024-03-30 0:34 ` [PATCH 06/13] fsverity: send the level of the merkle tree block to ->read_merkle_tree_block Darrick J. Wong
2024-04-05 2:42 ` Eric Biggers
2024-04-25 0:30 ` Darrick J. Wong
2024-03-30 0:34 ` [PATCH 07/13] fsverity: pass the new tree size and block size to ->begin_enable_verity Darrick J. Wong
2024-04-05 2:46 ` Eric Biggers
2024-04-24 21:36 ` Darrick J. Wong
2024-03-30 0:34 ` [PATCH 08/13] fsverity: expose merkle tree geometry to callers Darrick J. Wong
2024-04-05 2:50 ` Eric Biggers
2024-04-25 0:45 ` Darrick J. Wong
2024-04-25 0:49 ` Eric Biggers
2024-04-25 1:01 ` Darrick J. Wong
2024-04-25 1:04 ` Eric Biggers
2024-03-30 0:35 ` [PATCH 09/13] fsverity: box up the write_merkle_tree_block parameters too Darrick J. Wong
2024-04-05 2:52 ` Eric Biggers
2024-04-25 0:46 ` Darrick J. Wong
2024-03-30 0:35 ` [PATCH 10/13] fsverity: pass the zero-hash value to the implementation Darrick J. Wong
2024-04-05 2:57 ` Eric Biggers
2024-04-24 19:02 ` Darrick J. Wong
2024-04-24 19:19 ` Eric Biggers
2024-04-24 20:23 ` Darrick J. Wong
2024-04-24 20:59 ` Eric Biggers
2024-04-24 21:43 ` Darrick J. Wong
2024-03-30 0:35 ` [PATCH 11/13] fsverity: report validation errors back to the filesystem Darrick J. Wong
2024-04-05 3:09 ` Eric Biggers
2024-04-24 18:18 ` Darrick J. Wong
2024-04-24 18:52 ` Eric Biggers
2024-04-24 19:03 ` Darrick J. Wong
2024-03-30 0:35 ` [PATCH 12/13] fsverity: remove system-wide workqueue Darrick J. Wong
2024-04-05 3:14 ` Eric Biggers
2024-04-24 18:05 ` Darrick J. Wong
2024-04-24 18:41 ` Eric Biggers
2024-04-29 10:15 ` Andrey Albershteyn
2024-04-29 16:35 ` Darrick J. Wong
2024-03-30 0:36 ` [PATCH 13/13] iomap: integrate fs-verity verification into iomap's read path Darrick J. Wong
2024-03-30 0:32 ` [PATCHSET v5.5 2/2] xfs: fs-verity support Darrick J. Wong
2024-03-30 0:36 ` [PATCH 01/29] xfs: use unsigned ints for non-negative quantities in xfs_attr_remote.c Darrick J. Wong
2024-04-02 9:51 ` Andrey Albershteyn
2024-04-02 16:25 ` Darrick J. Wong
2024-03-30 0:36 ` [PATCH 02/29] xfs: turn XFS_ATTR3_RMT_BUF_SPACE into a function Darrick J. Wong
2024-04-02 10:09 ` Andrey Albershteyn
2024-03-30 0:36 ` [PATCH 03/29] xfs: create a helper to compute the blockcount of a max sized remote value Darrick J. Wong
2024-04-02 10:09 ` Andrey Albershteyn
2024-03-30 0:37 ` [PATCH 04/29] xfs: minor cleanups of xfs_attr3_rmt_blocks Darrick J. Wong
2024-04-02 10:11 ` Andrey Albershteyn
2024-03-30 0:37 ` [PATCH 05/29] xfs: add attribute type for fs-verity Darrick J. Wong
2024-03-30 0:37 ` [PATCH 06/29] xfs: do not use xfs_attr3_rmt_hdr for remote verity value blocks Darrick J. Wong
2024-03-30 0:37 ` [PATCH 07/29] xfs: add fs-verity ro-compat flag Darrick J. Wong
2024-03-30 0:38 ` [PATCH 08/29] xfs: add inode on-disk VERITY flag Darrick J. Wong
2024-03-30 0:38 ` [PATCH 09/29] xfs: initialize fs-verity on file open and cleanup on inode destruction Darrick J. Wong
2024-03-30 0:38 ` [PATCH 10/29] xfs: don't allow to enable DAX on fs-verity sealed inode Darrick J. Wong
2024-03-30 0:38 ` [PATCH 11/29] xfs: disable direct read path for fs-verity files Darrick J. Wong
2024-03-30 0:39 ` [PATCH 12/29] xfs: widen flags argument to the xfs_iflags_* helpers Darrick J. Wong
2024-04-02 12:37 ` Andrey Albershteyn
2024-04-02 16:27 ` Darrick J. Wong
2024-03-30 0:39 ` [PATCH 13/29] xfs: add fs-verity support Darrick J. Wong
2024-04-02 8:42 ` Andrey Albershteyn
2024-04-02 16:34 ` Darrick J. Wong
2024-04-25 1:14 ` Darrick J. Wong
2024-03-30 0:39 ` [PATCH 14/29] xfs: create a per-mount shrinker for verity inodes merkle tree blocks Darrick J. Wong
2024-04-05 3:16 ` Eric Biggers
2024-04-24 17:39 ` Darrick J. Wong
2024-03-30 0:39 ` [PATCH 15/29] xfs: create an icache tag for files with cached " Darrick J. Wong
2024-03-30 0:40 ` Darrick J. Wong [this message]
2024-03-30 0:40 ` [PATCH 17/29] xfs: only allow the verity iflag for regular files Darrick J. Wong
2024-04-02 12:52 ` Andrey Albershteyn
2024-03-30 0:40 ` [PATCH 18/29] xfs: don't store trailing zeroes of merkle tree blocks Darrick J. Wong
2024-03-30 0:41 ` [PATCH 19/29] xfs: use merkle tree offset as attr hash Darrick J. Wong
2024-03-30 0:41 ` [PATCH 20/29] xfs: don't bother storing merkle tree blocks for zeroed data blocks Darrick J. Wong
2024-03-30 0:41 ` [PATCH 21/29] xfs: add fs-verity ioctls Darrick J. Wong
2024-03-30 0:41 ` [PATCH 22/29] xfs: advertise fs-verity being available on filesystem Darrick J. Wong
2024-04-02 13:44 ` Andrey Albershteyn
2024-03-30 0:42 ` [PATCH 23/29] xfs: make scrub aware of verity dinode flag Darrick J. Wong
2024-03-30 0:42 ` [PATCH 24/29] xfs: teach online repair to evaluate fsverity xattrs Darrick J. Wong
2024-04-02 15:42 ` Andrey Albershteyn
2024-04-02 16:42 ` Darrick J. Wong
2024-03-30 0:42 ` [PATCH 25/29] xfs: report verity failures through the health system Darrick J. Wong
2024-04-02 16:16 ` Andrey Albershteyn
2024-03-30 0:42 ` [PATCH 26/29] xfs: clear the verity iflag when not appropriate Darrick J. Wong
2024-04-02 16:26 ` Andrey Albershteyn
2024-03-30 0:43 ` [PATCH 27/29] xfs: make it possible to disable fsverity Darrick J. Wong
2024-04-02 17:15 ` Andrey Albershteyn
2024-04-02 23:25 ` Eric Biggers
2024-04-03 1:26 ` Darrick J. Wong
2024-03-30 0:43 ` [PATCH 28/29] xfs: allow verity files to be opened even if the fsverity metadata is damaged Darrick J. Wong
2024-04-02 18:04 ` Andrey Albershteyn
2024-04-02 20:00 ` Colin Walters
2024-04-02 22:52 ` Darrick J. Wong
2024-04-02 23:45 ` Eric Biggers
2024-04-03 1:34 ` Darrick J. Wong
2024-04-03 0:10 ` Colin Walters
2024-04-03 1:39 ` Darrick J. Wong
2024-04-03 1:59 ` Dave Chinner
2024-04-03 3:19 ` Darrick J. Wong
2024-04-03 22:22 ` Dave Chinner
2024-04-03 8:35 ` Alexander Larsson
2024-03-30 0:43 ` [PATCH 29/29] xfs: enable ro-compat fs-verity flag Darrick J. Wong
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=171175868826.1988170.6498728857662092789.stgit@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=aalbersh@redhat.com \
--cc=ebiggers@kernel.org \
--cc=fsverity@lists.linux.dev \
--cc=linux-fsdevel@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).