From fe0e4c340101489c062cad43f59d7b3a01407718 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Mon, 31 Aug 2026 18:35:41 +0300 Subject: [PATCH v8 2/2] Use RegisterPinCountWaiter() in LockBufferForCleanup() Replace the duplicated pincount-waiter registration logic in LockBufferForCleanup() with a call to RegisterPinCountWaiter(), which already encapsulates the same protocol for publishing BM_PIN_COUNT_WAITER, rechecking the refcount, and returning false when only our own pin remains. --- src/backend/storage/buffer/bufmgr.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 686265c3d48..277a1b4d993 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -6844,34 +6844,14 @@ LockBufferForCleanup(Buffer buffer) LockBuffer(buffer, BUFFER_LOCK_UNLOCK); elog(ERROR, "multiple backends attempting to wait for pincount 1"); } - bufHdr->wait_backend_pgprocno = MyProcNumber; - PinCountWaitBuf = bufHdr; - - /* - * Publish BM_PIN_COUNT_WAITER while retaining the buffer header lock. - * The shared refcount can be decremented while BM_LOCKED is set, so - * use an atomic operation that preserves concurrent refcount changes. - */ - pg_atomic_fetch_or_u64(&bufHdr->state, BM_PIN_COUNT_WAITER); - /* - * Recheck the refcount after publishing the waiter flag, while shared - * refcount increments are still prevented by BM_LOCKED. If only our - * pin remains, the cleanup-lock condition has already been satisfied, - * so remove the waiter state and return without sleeping. + * Register ourselves as the pincount waiter. If the shared refcount + * was concurrently reduced to 1 (only our own pin remains), + * RegisterPinCountWaiter() returns false and no wait is necessary. */ - buf_state = pg_atomic_read_u64(&bufHdr->state); - - if (BUF_STATE_GET_REFCOUNT(buf_state) == 1) - { - UnlockBufHdrExt(bufHdr, buf_state, - 0, BM_PIN_COUNT_WAITER, - 0); - PinCountWaitBuf = NULL; + if (!RegisterPinCountWaiter(bufHdr, buf_state)) goto cleanup_lock_acquired; - } - UnlockBufHdr(bufHdr); LockBuffer(buffer, BUFFER_LOCK_UNLOCK); /* Wait to be signaled by UnpinBuffer() */ -- 2.43.0