Message ID | 20220627060841.244226-6-david@fromorbit.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | xfs: lockless buffer lookups | expand |
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
On Mon, Jun 27, 2022 at 04:08:40PM +1000, Dave Chinner wrote: > From: Dave Chinner <dchinner@redhat.com> > > Currently on the slow path insert we repeat the initial hash table > lookup before we attempt the insert, resulting in a two traversals > of the hash table to ensure the insert is valid. The rhashtable API > provides a method for an atomic lookup and insert operation, so we > can avoid one of the hash table traversals by using this method. > > Adapted from a large patch containing this optimisation by Christoph > Hellwig. > > Signed-off-by: Dave Chinner <dchinner@redhat.com> That's pretty neat! Reviewed-by: Darrick J. Wong <djwong@kernel.org> --D > --- > fs/xfs/xfs_buf.c | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > > diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c > index 3bcb691c6d95..3461ef3ebc1c 100644 > --- a/fs/xfs/xfs_buf.c > +++ b/fs/xfs/xfs_buf.c > @@ -623,8 +623,15 @@ xfs_buf_find_insert( > } > > spin_lock(&pag->pag_buf_lock); > - bp = rhashtable_lookup(&pag->pag_buf_hash, cmap, xfs_buf_hash_params); > + bp = rhashtable_lookup_get_insert_fast(&pag->pag_buf_hash, > + &new_bp->b_rhash_head, xfs_buf_hash_params); > + if (IS_ERR(bp)) { > + error = PTR_ERR(bp); > + spin_unlock(&pag->pag_buf_lock); > + goto out_free_buf; > + } > if (bp) { > + /* found an existing buffer */ > atomic_inc(&bp->b_hold); > spin_unlock(&pag->pag_buf_lock); > error = xfs_buf_find_lock(bp, flags); > @@ -635,10 +642,8 @@ xfs_buf_find_insert( > goto out_free_buf; > } > > - /* The buffer keeps the perag reference until it is freed. */ > + /* The new buffer keeps the perag reference until it is freed. */ > new_bp->b_pag = pag; > - rhashtable_insert_fast(&pag->pag_buf_hash, &new_bp->b_rhash_head, > - xfs_buf_hash_params); > spin_unlock(&pag->pag_buf_lock); > *bpp = new_bp; > return 0; > -- > 2.36.1 >
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 3bcb691c6d95..3461ef3ebc1c 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -623,8 +623,15 @@ xfs_buf_find_insert( } spin_lock(&pag->pag_buf_lock); - bp = rhashtable_lookup(&pag->pag_buf_hash, cmap, xfs_buf_hash_params); + bp = rhashtable_lookup_get_insert_fast(&pag->pag_buf_hash, + &new_bp->b_rhash_head, xfs_buf_hash_params); + if (IS_ERR(bp)) { + error = PTR_ERR(bp); + spin_unlock(&pag->pag_buf_lock); + goto out_free_buf; + } if (bp) { + /* found an existing buffer */ atomic_inc(&bp->b_hold); spin_unlock(&pag->pag_buf_lock); error = xfs_buf_find_lock(bp, flags); @@ -635,10 +642,8 @@ xfs_buf_find_insert( goto out_free_buf; } - /* The buffer keeps the perag reference until it is freed. */ + /* The new buffer keeps the perag reference until it is freed. */ new_bp->b_pag = pag; - rhashtable_insert_fast(&pag->pag_buf_hash, &new_bp->b_rhash_head, - xfs_buf_hash_params); spin_unlock(&pag->pag_buf_lock); *bpp = new_bp; return 0;