aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/aio/read_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/aio/read_stream.c')
-rw-r--r--src/backend/storage/aio/read_stream.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/backend/storage/aio/read_stream.c b/src/backend/storage/aio/read_stream.c
index 26e5dfe77db..36c54fb695b 100644
--- a/src/backend/storage/aio/read_stream.c
+++ b/src/backend/storage/aio/read_stream.c
@@ -102,6 +102,7 @@ struct ReadStream
int16 initialized_buffers;
int read_buffers_flags;
bool sync_mode; /* using io_method=sync */
+ bool batch_mode; /* READ_STREAM_USE_BATCHING */
bool advice_enabled;
bool temporary;
@@ -403,6 +404,15 @@ read_stream_start_pending_read(ReadStream *stream)
static void
read_stream_look_ahead(ReadStream *stream)
{
+ /*
+ * Allow amortizing the cost of submitting IO over multiple IOs. This
+ * requires that we don't do any operations that could lead to a deadlock
+ * with staged-but-unsubmitted IO. The callback needs to opt-in to being
+ * careful.
+ */
+ if (stream->batch_mode)
+ pgaio_enter_batchmode();
+
while (stream->ios_in_progress < stream->max_ios &&
stream->pinned_buffers + stream->pending_read_nblocks < stream->distance)
{
@@ -450,6 +460,8 @@ read_stream_look_ahead(ReadStream *stream)
{
/* We've hit the buffer or I/O limit. Rewind and stop here. */
read_stream_unget_block(stream, blocknum);
+ if (stream->batch_mode)
+ pgaio_exit_batchmode();
return;
}
}
@@ -484,6 +496,9 @@ read_stream_look_ahead(ReadStream *stream)
* time.
*/
Assert(stream->pinned_buffers > 0 || stream->distance == 0);
+
+ if (stream->batch_mode)
+ pgaio_exit_batchmode();
}
/*
@@ -617,6 +632,7 @@ read_stream_begin_impl(int flags,
MAXALIGN(&stream->ios[Max(1, max_ios)]);
stream->sync_mode = io_method == IOMETHOD_SYNC;
+ stream->batch_mode = flags & READ_STREAM_USE_BATCHING;
#ifdef USE_PREFETCH