[PATCH 12/12] xfs: add lockless xfs_buf_readahead_map fast path

Christoph Hellwig <[email protected]> Tue, 28 Jul 2026 10:11:20 +0200
Newsgroups org.kernel.vger.linux-xfs
Message-ID <[email protected]>
Readahead currently always locks the buffer, which can cause contention
with actual users of the buffer.  Add a fast path without taking any
locks if the buffer is uptodate and not stale.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Brian Foster <[email protected]>
Reviewed-by: "Darrick J. Wong" <[email protected]>
---
 fs/xfs/xfs_buf.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index bc23fa59680e..9d8a8b395a23 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -775,13 +775,23 @@ xfs_buf_readahead_map(
 
 	if (__xfs_find_get_buf(target, map, nmaps, flags, &bp))
 		return;
-	if (xfs_buf_find_lock(bp, XBF_TRYLOCK))
+
+	/*
+	 * Do a lockless fast path check for a valid uptodate buffer and avoid
+	 * locking entirely in this case.
+	 */
+	if ((READ_ONCE(bp->b_flags) & (XBF_DONE | XBF_STALE)) == XBF_DONE)
 		goto out_rele;
 
-	trace_xfs_buf_readahead(bp, 0, _RET_IP_);
-	if (bp->b_flags & XBF_DONE)
+	/* Otherwise lock the buffer to stabilize the state */
+	if (!xfs_buf_trylock(bp))
+		goto out_rele;
+
+	/* Let the actual reader deal with stale buffers. */
+	if (bp->b_flags & (XBF_STALE | XBF_DONE))
 		goto out_unlock;
 
+	trace_xfs_buf_readahead(bp, 0, _RET_IP_);
 	XFS_STATS_INC(target->bt_mount, xb_get_read);
 	bp->b_ops = ops;
 	xfs_buf_clear_flags(bp, XBF_WRITE | XBF_DONE);
-- 
2.53.0