From 1ad41a1f07343fd676ee7bb9741dbf539889f50f Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 11 Apr 2025 21:17:26 +1200
Subject: [PATCH v3 2/3] aio: Improve I/O worker behavior on full queue.

Previously, when the submission queue was full we'd run all remaining
IOs in a batch synchronously.  Now we'll try again between synchronous
operations, because the I/O workers might have drained some of the
queue.

Suggested-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/CA%2BhUKG%2Bm4xV0LMoH2c%3DoRAdEXuCnh%2BtGBTWa7uFeFMGgTLAw%2BQ%40mail.gmail.com
---
 src/backend/storage/aio/method_worker.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/backend/storage/aio/method_worker.c b/src/backend/storage/aio/method_worker.c
index e24357a7a0a..b1b0b6848a0 100644
--- a/src/backend/storage/aio/method_worker.c
+++ b/src/backend/storage/aio/method_worker.c
@@ -295,11 +295,29 @@ pgaio_worker_submit(uint16 num_staged_ios, PgAioHandle **staged_ios)
 		SetLatch(wakeup);
 
 	/* Run whatever is left synchronously. */
-	if (nsync > 0)
+	while (nsync > 0)
 	{
-		for (int i = 0; i < nsync; ++i)
+		pgaio_io_perform_synchronously(*synchronous_ios++);
+		nsync--;
+
+		/* Between synchronous operations, try to enqueue again. */
+		if (nsync > 0)
 		{
-			pgaio_io_perform_synchronously(synchronous_ios[i]);
+			wakeup = NULL;
+			if (LWLockConditionalAcquire(AioWorkerSubmissionQueueLock, LW_EXCLUSIVE))
+			{
+				while (nsync > 0 &&
+					   pgaio_worker_submission_queue_insert(*synchronous_ios))
+				{
+					synchronous_ios++;
+					nsync--;
+					if (wakeup == NULL && (worker = pgaio_worker_choose_idle()) >= 0)
+						wakeup = io_worker_control->workers[worker].latch;
+				}
+				LWLockRelease(AioWorkerSubmissionQueueLock);
+			}
+			if (wakeup)
+				SetLatch(wakeup);
 		}
 	}
 
-- 
2.53.0

