* [PATCH v2] xfs: remove xfs_buf_cache.bc_lock
@ 2025-01-28 5:22 Christoph Hellwig
2025-01-28 6:44 ` Dave Chinner
2025-01-28 10:57 ` Carlos Maiolino
0 siblings, 2 replies; 3+ messages in thread
From: Christoph Hellwig @ 2025-01-28 5:22 UTC (permalink / raw)
To: cem; +Cc: djwong, dchinner, linux-xfs, Lai, Yi, Carlos Maiolino
xfs_buf_cache.bc_lock serializes adding buffers to and removing them from
the hashtable. But as the rhashtable code already uses fine grained
internal locking for inserts and removals the extra protection isn't
actually required.
It also happens to fix a lock order inversion vs b_lock added by the
recent lookup race fix.
Fixes: ee10f6fcdb96 ("xfs: fix buffer lookup vs release race")
Reported-by: "Lai, Yi" <yi1.lai@linux.intel.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
---
Changes since v1:
- document the initial buffer state vs lockless lookups
fs/xfs/xfs_buf.c | 31 +++++++++++++++++--------------
fs/xfs/xfs_buf.h | 1 -
2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index d1d4a0a22e13..5db1b9022865 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -41,8 +41,7 @@ struct kmem_cache *xfs_buf_cache;
*
* xfs_buf_rele:
* b_lock
- * pag_buf_lock
- * lru_lock
+ * lru_lock
*
* xfs_buftarg_drain_rele
* lru_lock
@@ -220,14 +219,21 @@ _xfs_buf_alloc(
*/
flags &= ~(XBF_UNMAPPED | XBF_TRYLOCK | XBF_ASYNC | XBF_READ_AHEAD);
- spin_lock_init(&bp->b_lock);
+ /*
+ * A new buffer is held and locked by the owner. This ensures that the
+ * buffer is owned by the caller and racing RCU lookups right after
+ * inserting into the hash table are safe (and will have to wait for
+ * the unlock to do anything non-trivial).
+ */
bp->b_hold = 1;
+ sema_init(&bp->b_sema, 0); /* held, no waiters */
+
+ spin_lock_init(&bp->b_lock);
atomic_set(&bp->b_lru_ref, 1);
init_completion(&bp->b_iowait);
INIT_LIST_HEAD(&bp->b_lru);
INIT_LIST_HEAD(&bp->b_list);
INIT_LIST_HEAD(&bp->b_li_list);
- sema_init(&bp->b_sema, 0); /* held, no waiters */
bp->b_target = target;
bp->b_mount = target->bt_mount;
bp->b_flags = flags;
@@ -502,7 +508,6 @@ int
xfs_buf_cache_init(
struct xfs_buf_cache *bch)
{
- spin_lock_init(&bch->bc_lock);
return rhashtable_init(&bch->bc_hash, &xfs_buf_hash_params);
}
@@ -652,17 +657,20 @@ xfs_buf_find_insert(
if (error)
goto out_free_buf;
- spin_lock(&bch->bc_lock);
+ /* The new buffer keeps the perag reference until it is freed. */
+ new_bp->b_pag = pag;
+
+ rcu_read_lock();
bp = rhashtable_lookup_get_insert_fast(&bch->bc_hash,
&new_bp->b_rhash_head, xfs_buf_hash_params);
if (IS_ERR(bp)) {
+ rcu_read_unlock();
error = PTR_ERR(bp);
- spin_unlock(&bch->bc_lock);
goto out_free_buf;
}
if (bp && xfs_buf_try_hold(bp)) {
/* found an existing buffer */
- spin_unlock(&bch->bc_lock);
+ rcu_read_unlock();
error = xfs_buf_find_lock(bp, flags);
if (error)
xfs_buf_rele(bp);
@@ -670,10 +678,8 @@ xfs_buf_find_insert(
*bpp = bp;
goto out_free_buf;
}
+ rcu_read_unlock();
- /* The new buffer keeps the perag reference until it is freed. */
- new_bp->b_pag = pag;
- spin_unlock(&bch->bc_lock);
*bpp = new_bp;
return 0;
@@ -1090,7 +1096,6 @@ xfs_buf_rele_cached(
}
/* we are asked to drop the last reference */
- spin_lock(&bch->bc_lock);
__xfs_buf_ioacct_dec(bp);
if (!(bp->b_flags & XBF_STALE) && atomic_read(&bp->b_lru_ref)) {
/*
@@ -1102,7 +1107,6 @@ xfs_buf_rele_cached(
bp->b_state &= ~XFS_BSTATE_DISPOSE;
else
bp->b_hold--;
- spin_unlock(&bch->bc_lock);
} else {
bp->b_hold--;
/*
@@ -1120,7 +1124,6 @@ xfs_buf_rele_cached(
ASSERT(!(bp->b_flags & _XBF_DELWRI_Q));
rhashtable_remove_fast(&bch->bc_hash, &bp->b_rhash_head,
xfs_buf_hash_params);
- spin_unlock(&bch->bc_lock);
if (pag)
xfs_perag_put(pag);
freebuf = true;
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 7e73663c5d4a..3b4ed42e11c0 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -80,7 +80,6 @@ typedef unsigned int xfs_buf_flags_t;
#define XFS_BSTATE_IN_FLIGHT (1 << 1) /* I/O in flight */
struct xfs_buf_cache {
- spinlock_t bc_lock;
struct rhashtable bc_hash;
};
--
2.45.2
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH v2] xfs: remove xfs_buf_cache.bc_lock
2025-01-28 5:22 [PATCH v2] xfs: remove xfs_buf_cache.bc_lock Christoph Hellwig
@ 2025-01-28 6:44 ` Dave Chinner
2025-01-28 10:57 ` Carlos Maiolino
1 sibling, 0 replies; 3+ messages in thread
From: Dave Chinner @ 2025-01-28 6:44 UTC (permalink / raw)
To: Christoph Hellwig
Cc: cem, djwong, dchinner, linux-xfs, Lai, Yi, Carlos Maiolino
On Tue, Jan 28, 2025 at 06:22:58AM +0100, Christoph Hellwig wrote:
> xfs_buf_cache.bc_lock serializes adding buffers to and removing them from
> the hashtable. But as the rhashtable code already uses fine grained
> internal locking for inserts and removals the extra protection isn't
> actually required.
>
> It also happens to fix a lock order inversion vs b_lock added by the
> recent lookup race fix.
>
> Fixes: ee10f6fcdb96 ("xfs: fix buffer lookup vs release race")
> Reported-by: "Lai, Yi" <yi1.lai@linux.intel.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
> ---
>
> Changes since v1:
> - document the initial buffer state vs lockless lookups
Looks fine.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH v2] xfs: remove xfs_buf_cache.bc_lock
2025-01-28 5:22 [PATCH v2] xfs: remove xfs_buf_cache.bc_lock Christoph Hellwig
2025-01-28 6:44 ` Dave Chinner
@ 2025-01-28 10:57 ` Carlos Maiolino
1 sibling, 0 replies; 3+ messages in thread
From: Carlos Maiolino @ 2025-01-28 10:57 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: djwong, dchinner, linux-xfs, Lai, Yi, Carlos Maiolino
On Tue, 28 Jan 2025 06:22:58 +0100, Christoph Hellwig wrote:
> xfs_buf_cache.bc_lock serializes adding buffers to and removing them from
> the hashtable. But as the rhashtable code already uses fine grained
> internal locking for inserts and removals the extra protection isn't
> actually required.
>
> It also happens to fix a lock order inversion vs b_lock added by the
> recent lookup race fix.
>
> [...]
Applied to for-next, thanks!
[1/1] xfs: remove xfs_buf_cache.bc_lock
commit: a9ab28b3d21aec6d0f56fe722953e20ce470237b
Best regards,
--
Carlos Maiolino <cem@kernel.org>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-01-28 10:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-28 5:22 [PATCH v2] xfs: remove xfs_buf_cache.bc_lock Christoph Hellwig
2025-01-28 6:44 ` Dave Chinner
2025-01-28 10:57 ` Carlos Maiolino
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox