From 8c9488e9b467e0f405c59dd04143e19cbc1bd34d Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Tue, 2 Dec 2025 18:44:54 -0500 Subject: [PATCH v7 04/15] bufmgr: Optimize LockBufHdr() by delaying spin-delay setup 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