public inbox for [email protected]
help / color / mirror / Atom feedFrom: Andres Freund <[email protected]>
Subject: [PATCH v5 3/3] bufmgr: Use atomic sub for unpinning buffers
Date: Mon, 22 Sep 2025 14:44:52 -0400
The prior commit made it legal to modify BufferDesc.state while the buffer
header spinlock is held. This allows us to replace the CAS loop
inUnpinBufferNoOwner() with an atomic sub. This improves scalability
significantly. See the prior commits for more background.
Reviewed-by: Matthias van de Meent <[email protected]>
Discussion: https://postgr.es/m/fvfmkr5kk4nyex56ejgxj3uzi63isfxovp2biecb4bspbjrze7@az2pljabhnff
---
src/backend/storage/buffer/bufmgr.c | 29 +++--------------------------
1 file changed, 3 insertions(+), 26 deletions(-)
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 42e1f50c7c8..3528a355eff 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -3272,7 +3272,6 @@ UnpinBufferNoOwner(BufferDesc *buf)
ref->refcount--;
if (ref->refcount == 0)
{
- uint32 buf_state;
uint32 old_buf_state;
/*
@@ -3290,33 +3289,11 @@ UnpinBufferNoOwner(BufferDesc *buf)
*/
Assert(!LWLockHeldByMe(BufferDescriptorGetContentLock(buf)));
- /*
- * Decrement the shared reference count.
- *
- * Since buffer spinlock holder can update status using just write,
- * it's not safe to use atomic decrement here; thus use a CAS loop.
- *
- * TODO: The above requirement does not hold anymore, in a future
- * commit this will be rewritten to release the pin in a single atomic
- * operation.
- */
- old_buf_state = pg_atomic_read_u32(&buf->state);
- for (;;)
- {
- if (old_buf_state & BM_LOCKED)
- old_buf_state = WaitBufHdrUnlocked(buf);
-
- buf_state = old_buf_state;
-
- buf_state -= BUF_REFCOUNT_ONE;
-
- if (pg_atomic_compare_exchange_u32(&buf->state, &old_buf_state,
- buf_state))
- break;
- }
+ /* decrement the shared reference count */
+ old_buf_state = pg_atomic_fetch_sub_u32(&buf->state, BUF_REFCOUNT_ONE);
/* Support LockBufferForCleanup() */
- if (buf_state & BM_PIN_COUNT_WAITER)
+ if (old_buf_state & BM_PIN_COUNT_WAITER)
WakePinCountWaiter(buf);
ForgetPrivateRefCountEntry(ref);
--
2.48.1.76.g4e746b1a31.dirty
--552mi4kotjb5rbyk--
view thread (4+ messages)
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v5 3/3] bufmgr: Use atomic sub for unpinning buffers
In-Reply-To: <no-message-id-1837107@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox