From 13c18cda92f396f36c9383dfb062e184d2dbcd0a Mon Sep 17 00:00:00 2001
From: Yuhang Qiu <iamqyh@gmail.com>
Date: Mon, 3 Nov 2025 09:57:02 +0800
Subject: [PATCH] Add CHECK_FOR_INTERRUPTS in Evict{Rel,All}UnpinnedBuffers

The pg_buffercache_evict_{relation,all} operations can become extremely
slow when dealing with large buffer pool containing many dirty buffers.
This commit adds CHECK_FOR_INTERRUPTS calls within the underlying
Evict{Rel,All}UnpinnedBuffers functions to ensure these operations
cancellable.
---
 src/backend/storage/buffer/bufmgr.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index e8544acb784..00719c7aea2 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -6685,6 +6685,8 @@ EvictAllUnpinnedBuffers(int32 *buffers_evicted, int32 *buffers_flushed,
 		uint32		buf_state;
 		bool		buffer_flushed;

+		CHECK_FOR_INTERRUPTS();
+
 		buf_state = pg_atomic_read_u32(&desc->state);
 		if (!(buf_state & BM_VALID))
 			continue;
@@ -6735,6 +6737,8 @@ EvictRelUnpinnedBuffers(Relation rel, int32 *buffers_evicted,
 		uint32		buf_state = pg_atomic_read_u32(&(desc->state));
 		bool		buffer_flushed;

+		CHECK_FOR_INTERRUPTS();
+
 		/* An unlocked precheck should be safe and saves some cycles. */
 		if ((buf_state & BM_VALID) == 0 ||
 			!BufTagMatchesRelFileLocator(&desc->tag, &rel->rd_locator))
--
2.43.5

