From c2a68e08b13f3cb437c92102fb11ab0f45dbd67f Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Thu, 26 Mar 2026 10:50:44 -0400 Subject: [PATCH] bufmgr: Pass io_object and io_context through to PinBufferForBlock() PinBufferForBlock() is always_inline and called in a loop in StartReadBuffersImpl(). Previously it computed io_context and io_object internally, which required calling IOContextForStrategy() -- a non-inline function the compiler cannot prove is side-effect-free. This could potential cause unneeded redundant function calls. Compute io_context and io_object in the callers instead, allowing StartReadBuffersImpl() to do so once before entering the loop. Author: Melanie Plageman Suggested-by: Andres Freund Discussion: https://postgr.es/m/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw@3p3zu522yykv --- src/backend/storage/buffer/bufmgr.c | 45 ++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 10afae1990b..ab9c2a4b904 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1223,11 +1223,11 @@ PinBufferForBlock(Relation rel, ForkNumber forkNum, BlockNumber blockNum, BufferAccessStrategy strategy, + IOObject io_object, + IOContext io_context, bool *foundPtr) { BufferDesc *bufHdr; - IOContext io_context; - IOObject io_object; Assert(blockNum != P_NEW); @@ -1236,17 +1236,6 @@ PinBufferForBlock(Relation rel, persistence == RELPERSISTENCE_PERMANENT || persistence == RELPERSISTENCE_UNLOGGED)); - if (persistence == RELPERSISTENCE_TEMP) - { - io_context = IOCONTEXT_NORMAL; - io_object = IOOBJECT_TEMP_RELATION; - } - else - { - io_context = IOContextForStrategy(strategy); - io_object = IOOBJECT_RELATION; - } - TRACE_POSTGRESQL_BUFFER_READ_START(forkNum, blockNum, smgr->smgr_rlocator.locator.spcOid, smgr->smgr_rlocator.locator.dbOid, @@ -1339,9 +1328,23 @@ ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, mode == RBM_ZERO_AND_LOCK)) { bool found; + IOContext io_context; + IOObject io_object; + + if (persistence == RELPERSISTENCE_TEMP) + { + io_context = IOCONTEXT_NORMAL; + io_object = IOOBJECT_TEMP_RELATION; + } + else + { + io_context = IOContextForStrategy(strategy); + io_object = IOOBJECT_RELATION; + } buffer = PinBufferForBlock(rel, smgr, persistence, - forkNum, blockNum, strategy, &found); + forkNum, blockNum, strategy, + io_object, io_context, &found); ZeroAndLockBuffer(buffer, mode, found); return buffer; } @@ -1379,11 +1382,24 @@ StartReadBuffersImpl(ReadBuffersOperation *operation, int actual_nblocks = *nblocks; int maxcombine = 0; bool did_start_io; + IOContext io_context; + IOObject io_object; Assert(*nblocks == 1 || allow_forwarding); Assert(*nblocks > 0); Assert(*nblocks <= MAX_IO_COMBINE_LIMIT); + if (operation->persistence == RELPERSISTENCE_TEMP) + { + io_context = IOCONTEXT_NORMAL; + io_object = IOOBJECT_TEMP_RELATION; + } + else + { + io_context = IOContextForStrategy(operation->strategy); + io_object = IOOBJECT_RELATION; + } + for (int i = 0; i < actual_nblocks; ++i) { bool found; @@ -1432,6 +1448,7 @@ StartReadBuffersImpl(ReadBuffersOperation *operation, operation->forknum, blockNum + i, operation->strategy, + io_object, io_context, &found); }