diff mbox series

[5/6] xfs: remove a superflous hash lookup when inserting new buffers

Message ID 20220627060841.244226-6-david@fromorbit.com (mailing list archive)
State Superseded
Headers show
Series xfs: lockless buffer lookups | expand

Commit Message

Dave Chinner June 27, 2022, 6:08 a.m. UTC
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>
---
 fs/xfs/xfs_buf.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

Comments

Christoph Hellwig June 29, 2022, 7:40 a.m. UTC | #1
Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>
Darrick J. Wong June 29, 2022, 10:01 p.m. UTC | #2
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 mbox series

Patch

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;