From 9ac7b993a71c1459eb707b596adf9f9a4e722651 Mon Sep 17 00:00:00 2001 From: Lucas DRAESCHER Date: Tue, 17 Mar 2026 17:26:11 +0100 Subject: [PATCH v3] Release io_uring resources on shmem exit io_uring_queue_init() allocates resources for each io_uring instance, but pgaio_uring_shmem_init() never registers a cleanup callback to free them. Add a shmem_cleanup callback to IoMethodOps registered in AioShmemInit(). Implement the shmem_cleanup for method_io_uring.c as pgaio_uring_shmem_cleanup() which calls io_uring_queue_exit(). --- src/backend/storage/aio/aio_init.c | 18 ++++++++++++++++++ src/backend/storage/aio/method_io_uring.c | 18 ++++++++++++++++++ src/include/storage/aio_internal.h | 6 ++++++ 3 files changed, 42 insertions(+) diff --git a/src/backend/storage/aio/aio_init.c b/src/backend/storage/aio/aio_init.c index da30d792a88..0f3572d4dba 100644 --- a/src/backend/storage/aio/aio_init.c +++ b/src/backend/storage/aio/aio_init.c @@ -172,6 +172,20 @@ AioShmemRequest(void *arg) pgaio_method_ops->shmem_callbacks.request_fn(pgaio_method_ops->shmem_callbacks.opaque_arg); } +/* + * Wrapper around pgaio_method_ops->shmem_cleanup to satisfy the + * on_shmem_exit() callback signature. + */ +static void +pgaio_shmem_cleanup(int code, Datum arg) +{ + /* + * No null check needed here; AioShmemInit only registers this callback + * when shmem_cleanup is non-null. + */ + pgaio_method_ops->shmem_cleanup(); +} + /* * Initialize AIO shared memory during postmaster startup. */ @@ -225,6 +239,10 @@ AioShmemInit(void *arg) if (pgaio_method_ops->shmem_callbacks.init_fn) pgaio_method_ops->shmem_callbacks.init_fn(pgaio_method_ops->shmem_callbacks.opaque_arg); + + /* Register callback to release any resources allocated above. */ + if (pgaio_method_ops->shmem_cleanup) + on_shmem_exit(pgaio_shmem_cleanup, 0); } static void diff --git a/src/backend/storage/aio/method_io_uring.c b/src/backend/storage/aio/method_io_uring.c index c0f9fc9c303..09f36102920 100644 --- a/src/backend/storage/aio/method_io_uring.c +++ b/src/backend/storage/aio/method_io_uring.c @@ -51,6 +51,7 @@ /* Entry points for IoMethodOps. */ static void pgaio_uring_shmem_request(void *arg); static void pgaio_uring_shmem_init(void *arg); +static void pgaio_uring_shmem_cleanup(void); static void pgaio_uring_init_backend(void); static int pgaio_uring_submit(uint16 num_staged_ios, PgAioHandle **staged_ios); static void pgaio_uring_wait_one(PgAioHandle *ioh, uint64 ref_generation); @@ -72,6 +73,7 @@ const IoMethodOps pgaio_uring_ops = { .shmem_callbacks.request_fn = pgaio_uring_shmem_request, .shmem_callbacks.init_fn = pgaio_uring_shmem_init, + .shmem_cleanup = pgaio_uring_shmem_cleanup, .init_backend = pgaio_uring_init_backend, .submit = pgaio_uring_submit, @@ -403,6 +405,22 @@ pgaio_uring_shmem_init(void *arg) } } +static void +pgaio_uring_shmem_cleanup(void) +{ + if (pgaio_uring_contexts != NULL) + { + int TotalProcs = pgaio_uring_procs(); + + elog(DEBUG1, "cleaning up %d io_uring processes", TotalProcs); + + for (int i = 0; i < TotalProcs; i++) + io_uring_queue_exit(&pgaio_uring_contexts[i].io_uring_ring); + + pgaio_uring_contexts = NULL; + } +} + static void pgaio_uring_init_backend(void) { diff --git a/src/include/storage/aio_internal.h b/src/include/storage/aio_internal.h index 9ca4087aa7f..96a3f86ea97 100644 --- a/src/include/storage/aio_internal.h +++ b/src/include/storage/aio_internal.h @@ -272,6 +272,12 @@ typedef struct IoMethodOps /* global initialization */ ShmemCallbacks shmem_callbacks; + /* + * Clean up shared memory resources before shutdown. Called during shmem + * exit. Optional. + */ + void (*shmem_cleanup) (void); + /* * Per-backend initialization. Optional. */ -- 2.53.0