[PATCH v7 04/15] bufmgr: Optimize LockBufHdr() by delaying spin-delay setup
Andres Freund <andres@anarazel.de>
From: Andres Freund <andres@anarazel.de>
To:
Date: 2025-12-02T23:44:54Z
Lists: pgsql-hackers
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"