Thread

  1. [PATCH v7 04/15] bufmgr: Optimize LockBufHdr() by delaying spin-delay setup

    Andres Freund <andres@anarazel.de> — 2025-12-02T23:44:54Z

    Previously we always initialized the SpinDelayStatus. That is sufficiently
    expensive / buffer header lock acquisitions are sufficiently frequent to make
    it worthwhile to instead have a fastpath that does not initialize the
    SpinDelayStatus.
    
    While this is a small gain on its own, it mainly is aimed at preventing a
    regression after a future commit, which requires additional locking to set
    hint bits.
    
    Discussion: https://postgr.es/m/fvfmkr5kk4nyex56ejgxj3uzi63isfxovp2biecb4bspbjrze7@az2pljabhnff
    ---
     src/backend/storage/buffer/bufmgr.c | 32 ++++++++++++++++++++---------
     1 file changed, 22 insertions(+), 10 deletions(-)
    
    diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
    index 62f420dd344..0ffad2cd735 100644
    --- a/src/backend/storage/buffer/bufmgr.c
    +++ b/src/backend/storage/buffer/bufmgr.c
    @@ -6263,23 +6263,35 @@ rlocator_comparator(const void *p1, const void *p2)
     uint32
     LockBufHdr(BufferDesc *desc)
     {
    -	SpinDelayStatus delayStatus;
     	uint32		old_buf_state;
     
     	Assert(!BufferIsLocal(BufferDescriptorGetBuffer(desc)));
     
    -	init_local_spin_delay(&delayStatus);
    +	/*
    +	 * Try to acquire the lock once, without setting up the spin-delay
    +	 * infrastructure. The work necessary for that shows up in profiles and is
    +	 * rarely necessary.
    +	 */
    +	old_buf_state = pg_atomic_fetch_or_u32(&desc->state, BM_LOCKED);
     
    -	while (true)
    +	if (unlikely(old_buf_state & BM_LOCKED))
     	{
    -		/* set BM_LOCKED flag */
    -		old_buf_state = pg_atomic_fetch_or_u32(&desc->state, BM_LOCKED);
    -		/* if it wasn't set before we're OK */
    -		if (!(old_buf_state & BM_LOCKED))
    -			break;
    -		perform_spin_delay(&delayStatus);
    +		SpinDelayStatus delayStatus;
    +
    +		init_local_spin_delay(&delayStatus);
    +
    +		while (true)
    +		{
    +			/* set BM_LOCKED flag */
    +			old_buf_state = pg_atomic_fetch_or_u32(&desc->state, BM_LOCKED);
    +			/* if it wasn't set before we're OK */
    +			if (!(old_buf_state & BM_LOCKED))
    +				break;
    +			perform_spin_delay(&delayStatus);
    +		}
    +		finish_spin_delay(&delayStatus);
     	}
    -	finish_spin_delay(&delayStatus);
    +
     	return old_buf_state | BM_LOCKED;
     }
     
    -- 
    2.48.1.76.g4e746b1a31.dirty
    
    
    --kad4mm4awdo7v2ki
    Content-Type: text/x-diff; charset=us-ascii
    Content-Disposition: attachment;
    	filename="v7-0005-bufmgr-Separate-keys-for-private-refcount-infrast.patch"