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.
This knowledge can be useful for callers of WaitReadBuffers() to know whether
it needed to wait or not, e.g. for adjusting read-ahead aggressiveness or for
instrumentation.

Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Discussion: https://postgr.es/m/f3xxfrkafjxpyqxywcxricxgyizjirfceychyxsgn7bwjp5eda@kwbduhy7tfmu
Discussion: https://postgr.es/m/CAH2-Wz%3DkMg3PNay96cHMT0LFwtxP-cQSRZTZzh1Cixxf8G%3Dzrw%40mail.gmail.com
Discussion: https://postgr.es/m/a177a6dd-240b-455a-8f25-aca0b1c08c6e@vondra.me
This commit is contained in:
Andres Freund 2026-04-01 09:26:43 -04:00
parent 6e648e353f
commit 513374a47a
2 changed files with 17 additions and 2 deletions

View file

@ -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;
}
/*

View file

@ -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);