Subject: [PATCH] check kernel version for io_method

From: Pierre <[email-masked]>
Date: Tue, 13 Jan 2026 23:05:29 +0100

Hello,

Please find a patch proposal for bug BUG #19369: Not documented that 
io_uring on kernel versions between 5.1 and below 5.6 does not work.

This is not  a document patch but code patch using a GUC hook to :

- check liburing setup

- check kernel version

to allow/disallow io_method=io_uring

I have made successfull tests on:

- Alma Linux 9.7/ kernel 5.14 without liburing setup

- Debian 12 / kernel 6.1 with liburing-dev

NB:

This is my first patch and I apologize if it is not fully compliant with 
patching rules.

Thanks.

From 8e0bd6948f7a75472891965b126356903934dfd2 Mon Sep 17 00:00:00 2001
From: Pierre Forstmann <[email-masked]>
Date: Tue, 13 Jan 2026 22:53:03 +0100
Subject: [PATCH] patch: check kernel version for io_method

---
 src/backend/storage/aio/aio.c             | 47 +++++++++++++++++++++++
 src/backend/utils/misc/guc_parameters.dat |  1 +
 src/include/utils/guc_hooks.h             |  2 +
 3 files changed, 50 insertions(+)

diff --git a/src/backend/storage/aio/aio.c b/src/backend/storage/aio/aio.c
index d2c9cd6f20a..f7610498467 100644
--- a/src/backend/storage/aio/aio.c
+++ b/src/backend/storage/aio/aio.c
@@ -50,6 +50,7 @@
 #include "utils/resowner.h"
 #include "utils/wait_event_types.h"
 
+#include <sys/utsname.h>
 
 static inline void pgaio_io_update_state(PgAioHandle *ioh, PgAioHandleState new_state);
 static void pgaio_io_reclaim(PgAioHandle *ioh);
@@ -1346,3 +1347,49 @@ check_io_max_concurrency(int *newval, void **extra, GucSource source)
 
 	return true;
 }
+
+
+bool
+check_io_method(int *newval, void **extra, GucSource source) 
+{
+#ifdef IOMETHOD_IO_URING_ENABLED
+	if (*newval == IOMETHOD_IO_URING)
+	{
+		struct utsname uname_buf;
+		int major;
+		int minor;
+		int rc;
+
+		uname(&uname_buf);
+	 	rc = sscanf(uname_buf.release, "%d.%d", &major, &minor);
+
+		if (rc == 2 && ((major >= 5 && minor >= 6) || major >= 6))             
+		{
+			/*
+			 * OK
+			 */
+		}
+		else 
+        	{
+			GUC_check_errdetail("io_uring requires Linux kernel 5.6 or later.");
+			return false;
+        	}
+	}	
+
+	return true;
+#else
+	if (*newval == IOMETHOD_WORKER || *newval == IOMETHOD_SYNC)
+	{
+		/*
+		 * OK
+		 */
+	} 
+	else 
+	{
+		GUC_check_errdetail("io_uring requires Linux kernel 5.6 or later.");
+		return false;
+	}
+
+	return true;
+#endif
+}
diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat
index 7c60b125564..2246af79808 100644
--- a/src/backend/utils/misc/guc_parameters.dat
+++ b/src/backend/utils/misc/guc_parameters.dat
@@ -1339,6 +1339,7 @@
   boot_val => 'DEFAULT_IO_METHOD',
   options => 'io_method_options',
   assign_hook => 'assign_io_method',
+  check_hook => 'check_io_method',
 },
 
 { name => 'io_workers', type => 'int', context => 'PGC_SIGHUP', group => 'RESOURCES_IO',
diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h
index f723668da9e..1c33dff4b55 100644
--- a/src/include/utils/guc_hooks.h
+++ b/src/include/utils/guc_hooks.h
@@ -176,4 +176,6 @@ extern bool check_synchronized_standby_slots(char **newval, void **extra,
 											 GucSource source);
 extern void assign_synchronized_standby_slots(const char *newval, void *extra);
 
+extern bool check_io_method(int *newval, void **extra, GucSource source);
+
 #endif							/* GUC_HOOKS_H */
-- 
2.47.3

---

From: Andreas Karlsson <[email-masked]>
Date: Wed, 14 Jan 2026 02:07:43 +0100

> io_uring on kernel versions between 5.1 and below 5.6 does not work.
Wouldn't it make more sense to use io_uring_get_probe_ring() and 
io_uring_opcode_supported() to actually check for the required opcode? 
Then if someone uses a Kernel with the required features backported 
everything will still work.

Andreas