From c5b2933107664e70ec10d6d2597521b11358b532 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Tue, 3 Mar 2026 16:50:50 -0500 Subject: [PATCH v19 10/18] bufmgr: Return whether WaitReadBuffers() needed to wait Thanks to the previous commit, pgaio_wref_check_done() will now detect whether IO has completed even if userspace has not yet consumed the kernel completion. To allow read_stream.c to use that knowledge to control readahead aggressiveness, WaitReadBuffers() needs to return whether it actually needed to wait. Author: Reviewed-by: Discussion: https://postgr.es/m/ Backpatch: --- src/include/storage/bufmgr.h | 2 +- src/backend/storage/buffer/bufmgr.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index dd41b92f9..aa61a39d9 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -251,7 +251,7 @@ extern bool StartReadBuffers(ReadBuffersOperation *operation, BlockNumber blockNum, int *nblocks, int flags); -extern void WaitReadBuffers(ReadBuffersOperation *operation); +extern bool WaitReadBuffers(ReadBuffersOperation *operation); extern void ReleaseBuffer(Buffer buffer); extern void UnlockReleaseBuffer(Buffer buffer); diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index cd21ae3fc..af0e05247 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1740,12 +1740,19 @@ ProcessReadBuffersResult(ReadBuffersOperation *operation) Assert(operation->nblocks_done <= operation->nblocks); } -void +/* + * Wait for the IO operation initiated by StartReadBuffers() et al to + * complete. + * + * Returns true if we needed to wait for the IO operation, false otherwise. + */ +bool WaitReadBuffers(ReadBuffersOperation *operation) { PgAioReturn *aio_ret = &operation->io_return; IOContext io_context; IOObject io_object; + bool needed_wait = false; if (operation->persistence == RELPERSISTENCE_TEMP) { @@ -1810,6 +1817,7 @@ WaitReadBuffers(ReadBuffersOperation *operation) instr_time io_start = pgstat_prepare_io_time(track_io_timing); pgaio_wref_wait(&operation->io_wref); + needed_wait = true; /* * The IO operation itself was already counted earlier, in @@ -1874,6 +1882,12 @@ WaitReadBuffers(ReadBuffersOperation *operation) CHECK_FOR_INTERRUPTS(); + /* + * If the IO completed only partially, we need to perform additional + * work, consider that a form of having had to wait. + */ + needed_wait = true; + /* * This may only complete the IO partially, either because some * buffers were already valid, or because of a partial read. @@ -1890,6 +1904,7 @@ WaitReadBuffers(ReadBuffersOperation *operation) CheckReadBuffersOperation(operation, true); /* NB: READ_DONE tracepoint was already executed in completion callback */ + return needed_wait; } /* -- 2.53.0