public inbox for [email protected]
 help / color / mirror / Atom feed
* [PATCH liburing 0/4] Tests for absolute timeouts and clockids
@ 2024-08-18 18:55 Pavel Begunkov
  2024-08-18 18:55 ` [PATCH liburing 1/4] Sync kernel headers Pavel Begunkov
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Pavel Begunkov @ 2024-08-18 18:55 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Add definitions, tests and documentation for IORING_ENTER_ABS_TIMER
and IORING_REGISTER_CLOCK.

It also adds helpers for registering clocks but not for absolute
timeouts. Currently, liburing does't provide a way to pass custom
enter flags.

Pavel Begunkov (4):
  Sync kernel headers
  src/register: add clock id registration helper
  test: test clockids and abs timeouts
  man: document clock id and IORING_ENTER_ABS_TIMER

 man/io_uring_enter.2            |  12 ++
 man/io_uring_register.2         |  20 +++
 src/include/liburing.h          |   3 +
 src/include/liburing/io_uring.h |  67 +++++---
 src/liburing-ffi.map            |   2 +
 src/liburing.map                |   2 +
 src/register.c                  |   6 +
 test/Makefile                   |   1 +
 test/wait-timeout.c             | 283 ++++++++++++++++++++++++++++++++
 9 files changed, 369 insertions(+), 27 deletions(-)
 create mode 100644 test/wait-timeout.c

-- 
2.45.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH liburing 1/4] Sync kernel headers
  2024-08-18 18:55 [PATCH liburing 0/4] Tests for absolute timeouts and clockids Pavel Begunkov
@ 2024-08-18 18:55 ` Pavel Begunkov
  2024-08-18 18:55 ` [PATCH liburing 2/4] src/register: add clock id registration helper Pavel Begunkov
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pavel Begunkov @ 2024-08-18 18:55 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Synchronise io_uring.h with kernel, pull IORING_REGISTER_CLOCK and all
other changes.

Signed-off-by: Pavel Begunkov <[email protected]>
---
 src/include/liburing/io_uring.h | 67 ++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h
index 01c36a8..48c440e 100644
--- a/src/include/liburing/io_uring.h
+++ b/src/include/liburing/io_uring.h
@@ -116,7 +116,7 @@ struct io_uring_sqe {
  */
 #define IORING_FILE_INDEX_ALLOC		(~0U)
 
-enum {
+enum io_uring_sqe_flags_bit {
 	IOSQE_FIXED_FILE_BIT,
 	IOSQE_IO_DRAIN_BIT,
 	IOSQE_IO_LINK_BIT,
@@ -184,7 +184,7 @@ enum {
 #define IORING_SETUP_DEFER_TASKRUN	(1U << 13)
 
 /*
- * Application provides ring memory
+ * Application provides the memory for the rings
  */
 #define IORING_SETUP_NO_MMAP		(1U << 14)
 
@@ -265,11 +265,12 @@ enum io_uring_op {
 };
 
 /*
- * sqe->uring_cmd_flags
+ * sqe->uring_cmd_flags		top 8bits aren't available for userspace
  * IORING_URING_CMD_FIXED	use registered buffer; pass this flag
  *				along with setting sqe->buf_index.
  */
 #define IORING_URING_CMD_FIXED	(1U << 0)
+#define IORING_URING_CMD_MASK	IORING_URING_CMD_FIXED
 
 
 /*
@@ -317,15 +318,19 @@ enum io_uring_op {
  * ASYNC_CANCEL flags.
  *
  * IORING_ASYNC_CANCEL_ALL	Cancel all requests that match the given key
- * IORING_ASYNC_CANCEL_FD	  Key off 'fd' for cancelation rather than the
+ * IORING_ASYNC_CANCEL_FD	Key off 'fd' for cancelation rather than the
  *				request 'user_data'
  * IORING_ASYNC_CANCEL_ANY	Match any request
  * IORING_ASYNC_CANCEL_FD_FIXED	'fd' passed in is a fixed descriptor
+ * IORING_ASYNC_CANCEL_USERDATA	Match on user_data, default for no other key
+ * IORING_ASYNC_CANCEL_OP	Match request based on opcode
  */
 #define IORING_ASYNC_CANCEL_ALL	(1U << 0)
 #define IORING_ASYNC_CANCEL_FD	(1U << 1)
 #define IORING_ASYNC_CANCEL_ANY	(1U << 2)
 #define IORING_ASYNC_CANCEL_FD_FIXED	(1U << 3)
+#define IORING_ASYNC_CANCEL_USERDATA	(1U << 4)
+#define IORING_ASYNC_CANCEL_OP	(1U << 5)
 
 /*
  * send/sendmsg and recv/recvmsg flags (sqe->ioprio)
@@ -350,13 +355,13 @@ enum io_uring_op {
  *				IORING_NOTIF_USAGE_ZC_COPIED if data was copied
  *				(at least partially).
  *
- * IORING_RECVSEND_BUNDLE	Used with IOSQE_BUFFER_SELECT. If set, send wil
- *				grab as many buffers from the buffer group ID
- *				given and send them all. The completion result
- *				will be the number of buffers send, with the
- *				starting buffer ID in cqe->flags as per usual
- *				for provided buffer usage. The buffers will be
- *				contigious from the starting buffer ID.
+ * IORING_RECVSEND_BUNDLE	Used with IOSQE_BUFFER_SELECT. If set, send or
+ *				recv will grab as many buffers from the buffer
+ *				group ID given and send them all. The completion
+ *				result 	will be the number of buffers send, with
+ *				the starting buffer ID in cqe->flags as per
+ *				usual for provided buffer usage. The buffers
+ *				will be	contigious from the starting buffer ID.
  */
 #define IORING_RECVSEND_POLL_FIRST	(1U << 0)
 #define IORING_RECV_MULTISHOT		(1U << 1)
@@ -383,7 +388,7 @@ enum io_uring_op {
 /*
  * IORING_OP_MSG_RING command types, stored in sqe->addr
  */
-enum {
+enum io_uring_msg_ring_flags {
 	IORING_MSG_DATA,	/* pass sqe->len as 'res' and off as user_data */
 	IORING_MSG_SEND_FD,	/* send a registered fd to another ring */
 };
@@ -416,7 +421,7 @@ enum {
  * IO completion data structure (Completion Queue Entry)
  */
 struct io_uring_cqe {
-	__u64	user_data;	/* sqe->user_data value passed back */
+	__u64	user_data;	/* sqe->data submission passed back */
 	__s32	res;		/* result code for this event */
 	__u32	flags;
 
@@ -441,9 +446,7 @@ struct io_uring_cqe {
 #define IORING_CQE_F_SOCK_NONEMPTY	(1U << 2)
 #define IORING_CQE_F_NOTIF		(1U << 3)
 
-enum {
-	IORING_CQE_BUFFER_SHIFT		= 16,
-};
+#define IORING_CQE_BUFFER_SHIFT		16
 
 /*
  * Magic offsets for the application to mmap the data it needs
@@ -504,6 +507,7 @@ struct io_cqring_offsets {
 #define IORING_ENTER_SQ_WAIT		(1U << 2)
 #define IORING_ENTER_EXT_ARG		(1U << 3)
 #define IORING_ENTER_REGISTERED_RING	(1U << 4)
+#define IORING_ENTER_ABS_TIMER		(1U << 5)
 
 /*
  * Passed in for io_uring_setup(2). Copied back with updated info on success
@@ -543,7 +547,7 @@ struct io_uring_params {
 /*
  * io_uring_register(2) opcodes and arguments
  */
-enum {
+enum io_uring_register_op {
 	IORING_REGISTER_BUFFERS			= 0,
 	IORING_UNREGISTER_BUFFERS		= 1,
 	IORING_REGISTER_FILES			= 2,
@@ -592,6 +596,8 @@ enum {
 	IORING_REGISTER_NAPI			= 27,
 	IORING_UNREGISTER_NAPI			= 28,
 
+	IORING_REGISTER_CLOCK			= 29,
+
 	/* this goes last */
 	IORING_REGISTER_LAST,
 
@@ -600,7 +606,7 @@ enum {
 };
 
 /* io-wq worker categories */
-enum {
+enum io_wq_type {
 	IO_WQ_BOUND,
 	IO_WQ_UNBOUND,
 };
@@ -672,6 +678,11 @@ struct io_uring_restriction {
 	__u32 resv2[3];
 };
 
+struct io_uring_clock_register {
+	__u32	clockid;
+	__u32	__resv[3];
+};
+
 struct io_uring_buf {
 	__u64	addr;
 	__u32	len;
@@ -691,7 +702,7 @@ struct io_uring_buf_ring {
 			__u16	resv3;
 			__u16	tail;
 		};
-		struct io_uring_buf	bufs[0];
+		__DECLARE_FLEX_ARRAY(struct io_uring_buf, bufs);
 	};
 };
 
@@ -705,7 +716,7 @@ struct io_uring_buf_ring {
  *			IORING_OFF_PBUF_RING | (bgid << IORING_OFF_PBUF_SHIFT)
  *			to get a virtual mapping for the ring.
  */
-enum {
+enum io_uring_register_pbuf_ring_flags {
 	IOU_PBUF_RING_MMAP	= 1,
 };
 
@@ -727,16 +738,16 @@ struct io_uring_buf_status {
 
 /* argument for IORING_(UN)REGISTER_NAPI */
 struct io_uring_napi {
-	__u32   busy_poll_to;
-	__u8    prefer_busy_poll;
-	__u8    pad[3];
-	__u64   resv;
+	__u32	busy_poll_to;
+	__u8	prefer_busy_poll;
+	__u8	pad[3];
+	__u64	resv;
 };
 
 /*
  * io_uring_restriction->opcode values
  */
-enum {
+enum io_uring_register_restriction_op {
 	/* Allow an io_uring_register(2) opcode */
 	IORING_RESTRICTION_REGISTER_OP		= 0,
 
@@ -767,7 +778,9 @@ struct io_uring_sync_cancel_reg {
 	__s32				fd;
 	__u32				flags;
 	struct __kernel_timespec	timeout;
-	__u64				pad[4];
+	__u8				opcode;
+	__u8				pad[7];
+	__u64				pad2[3];
 };
 
 /*
@@ -790,7 +803,7 @@ struct io_uring_recvmsg_out {
 /*
  * Argument for IORING_OP_URING_CMD when file is a socket
  */
-enum {
+enum io_uring_socket_op {
 	SOCKET_URING_OP_SIOCINQ		= 0,
 	SOCKET_URING_OP_SIOCOUTQ,
 	SOCKET_URING_OP_GETSOCKOPT,
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH liburing 2/4] src/register: add clock id registration helper
  2024-08-18 18:55 [PATCH liburing 0/4] Tests for absolute timeouts and clockids Pavel Begunkov
  2024-08-18 18:55 ` [PATCH liburing 1/4] Sync kernel headers Pavel Begunkov
@ 2024-08-18 18:55 ` Pavel Begunkov
  2024-08-18 18:55 ` [PATCH liburing 3/4] test: test clockids and abs timeouts Pavel Begunkov
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pavel Begunkov @ 2024-08-18 18:55 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Signed-off-by: Pavel Begunkov <[email protected]>
---
 src/include/liburing.h | 3 +++
 src/liburing-ffi.map   | 2 ++
 src/liburing.map       | 2 ++
 src/register.c         | 6 ++++++
 4 files changed, 13 insertions(+)

diff --git a/src/include/liburing.h b/src/include/liburing.h
index 1092f3b..53c94c4 100644
--- a/src/include/liburing.h
+++ b/src/include/liburing.h
@@ -241,6 +241,9 @@ int io_uring_register_file_alloc_range(struct io_uring *ring,
 int io_uring_register_napi(struct io_uring *ring, struct io_uring_napi *napi);
 int io_uring_unregister_napi(struct io_uring *ring, struct io_uring_napi *napi);
 
+int io_uring_register_clock(struct io_uring *ring,
+			    struct io_uring_clock_register *arg);
+
 int io_uring_get_events(struct io_uring *ring);
 int io_uring_submit_and_get_events(struct io_uring *ring);
 
diff --git a/src/liburing-ffi.map b/src/liburing-ffi.map
index 476d7fd..a0bea31 100644
--- a/src/liburing-ffi.map
+++ b/src/liburing-ffi.map
@@ -206,4 +206,6 @@ LIBURING_2.7 {
 } LIBURING_2.6;
 
 LIBURING_2.8 {
+	global:
+		io_uring_register_clock;
 } LIBURING_2.7;
diff --git a/src/liburing.map b/src/liburing.map
index fa096bb..79f6068 100644
--- a/src/liburing.map
+++ b/src/liburing.map
@@ -97,4 +97,6 @@ LIBURING_2.7 {
 } LIBURING_2.6;
 
 LIBURING_2.8 {
+	global:
+		io_uring_register_clock;
 } LIBURING_2.7;
diff --git a/src/register.c b/src/register.c
index 9acc36f..c0690a8 100644
--- a/src/register.c
+++ b/src/register.c
@@ -366,3 +366,9 @@ int io_uring_unregister_napi(struct io_uring *ring, struct io_uring_napi *napi)
 {
 	return do_register(ring, IORING_UNREGISTER_NAPI, napi, 1);
 }
+
+int io_uring_register_clock(struct io_uring *ring,
+			    struct io_uring_clock_register *arg)
+{
+	return do_register(ring, IORING_REGISTER_CLOCK, arg, 0);
+}
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH liburing 3/4] test: test clockids and abs timeouts
  2024-08-18 18:55 [PATCH liburing 0/4] Tests for absolute timeouts and clockids Pavel Begunkov
  2024-08-18 18:55 ` [PATCH liburing 1/4] Sync kernel headers Pavel Begunkov
  2024-08-18 18:55 ` [PATCH liburing 2/4] src/register: add clock id registration helper Pavel Begunkov
@ 2024-08-18 18:55 ` Pavel Begunkov
  2024-08-18 18:55 ` [PATCH liburing 4/4] man: document clock id and IORING_ENTER_ABS_TIMER Pavel Begunkov
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pavel Begunkov @ 2024-08-18 18:55 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Signed-off-by: Pavel Begunkov <[email protected]>
---
 test/Makefile       |   1 +
 test/wait-timeout.c | 283 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 284 insertions(+)
 create mode 100644 test/wait-timeout.c

diff --git a/test/Makefile b/test/Makefile
index 0538a75..f4fccd7 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -213,6 +213,7 @@ test_srcs := \
 	unlink.c \
 	version.c \
 	waitid.c \
+	wait-timeout.c \
 	wakeup-hang.c \
 	wq-aff.c \
 	xattr.c \
diff --git a/test/wait-timeout.c b/test/wait-timeout.c
new file mode 100644
index 0000000..1fc8e28
--- /dev/null
+++ b/test/wait-timeout.c
@@ -0,0 +1,283 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: run various timeout tests
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#include "helpers.h"
+#include "liburing.h"
+#include "../src/syscall.h"
+
+#define IO_NSEC_PER_SEC			1000000000LU
+
+static bool support_abs = false;
+static bool support_clock = false;
+
+static unsigned long long timespec_to_ns(struct timespec *ts)
+{
+	return ts->tv_nsec + ts->tv_sec * IO_NSEC_PER_SEC;
+}
+static struct timespec ns_to_timespec(unsigned long long t)
+{
+	struct timespec ts;
+
+	ts.tv_sec = t / IO_NSEC_PER_SEC;
+	ts.tv_nsec = t - ts.tv_sec * IO_NSEC_PER_SEC;
+	return ts;
+}
+
+static long long ns_since(struct timespec *ts)
+{
+	struct timespec now;
+	int ret;
+
+	ret = clock_gettime(CLOCK_MONOTONIC, &now);
+	if (ret) {
+		fprintf(stderr, "clock_gettime failed\n");
+		exit(T_EXIT_FAIL);
+	}
+
+	return timespec_to_ns(&now) - timespec_to_ns(ts);
+
+}
+
+static int t_io_uring_wait(struct io_uring *ring, int nr, unsigned enter_flags,
+			   struct timespec *ts)
+{
+	struct io_uring_getevents_arg arg = {
+		.sigmask	= 0,
+		.sigmask_sz	= _NSIG / 8,
+		.ts		= (unsigned long)ts
+	};
+	int ret;
+
+	enter_flags |= IORING_ENTER_GETEVENTS | IORING_ENTER_EXT_ARG;
+	ret = io_uring_enter2(ring->ring_fd, 0, nr, enter_flags,
+			      (void *)&arg, sizeof(arg));
+	return ret;
+}
+
+static int probe_timers(void)
+{
+	struct io_uring_clock_register cr = { .clockid = CLOCK_MONOTONIC, };
+	struct io_uring ring;
+	struct timespec ts;
+	int ret;
+
+	ret = io_uring_queue_init(8, &ring, 0);
+	if (ret) {
+		fprintf(stderr, "probe ring setup failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+	if (ret) {
+		fprintf(stderr, "clock_gettime failed\n");
+		return ret;
+	}
+
+	ret = t_io_uring_wait(&ring, 0, IORING_ENTER_ABS_TIMER, &ts);
+	if (!ret) {
+		support_abs = true;
+	} else if (ret != -EINVAL) {
+		fprintf(stderr, "wait failed %i\n", ret);
+		return ret;
+	}
+
+	ret = io_uring_register_clock(&ring, &cr);
+	if (!ret) {
+		support_clock = true;
+	} else if (ret != -EINVAL) {
+		fprintf(stderr, "io_uring_register_clock %i\n", ret);
+		return ret;
+	}
+
+	io_uring_queue_exit(&ring);
+	return 0;
+}
+
+static int test_timeout(bool abs, bool set_clock)
+{
+	unsigned enter_flags = abs ? IORING_ENTER_ABS_TIMER : 0;
+	struct io_uring ring;
+	struct timespec start, end, ts;
+	long long dt;
+	int ret;
+
+	ret = io_uring_queue_init(8, &ring, 0);
+	if (ret) {
+		fprintf(stderr, "ring setup failed: %d\n", ret);
+		return 1;
+	}
+
+	if (set_clock) {
+		struct io_uring_clock_register cr = {};
+
+		cr.clockid = CLOCK_BOOTTIME;
+		ret = io_uring_register_clock(&ring, &cr);
+		if (ret) {
+			fprintf(stderr, "io_uring_register_clock failed\n");
+			return 1;
+		}
+	}
+
+	/* pass current time */
+	ret = clock_gettime(CLOCK_MONOTONIC, &start);
+	assert(ret == 0);
+
+	ts = abs ? start : ns_to_timespec(0);
+	ret = t_io_uring_wait(&ring, 1, enter_flags, &ts);
+	if (ret != -ETIME) {
+		fprintf(stderr, "wait current time failed, %i\n", ret);
+		return 1;
+	}
+
+	if (ns_since(&start) >= IO_NSEC_PER_SEC) {
+		fprintf(stderr, "current time test failed\n");
+		return 1;
+	}
+
+	if (abs) {
+		/* expired time */
+		ret = clock_gettime(CLOCK_MONOTONIC, &start);
+		assert(ret == 0);
+		ts = ns_to_timespec(timespec_to_ns(&start) - IO_NSEC_PER_SEC);
+
+		ret = t_io_uring_wait(&ring, 1, enter_flags, &ts);
+		if (ret != -ETIME) {
+			fprintf(stderr, "expired timeout wait failed, %i\n", ret);
+			return 1;
+		}
+
+		ret = clock_gettime(CLOCK_MONOTONIC, &end);
+		assert(ret == 0);
+
+		if (ns_since(&start) >= IO_NSEC_PER_SEC) {
+			fprintf(stderr, "expired timer test failed\n");
+			return 1;
+		}
+	}
+
+	/* 1s wait */
+	ret = clock_gettime(CLOCK_MONOTONIC, &start);
+	assert(ret == 0);
+
+	dt = 2 * IO_NSEC_PER_SEC + (abs ? timespec_to_ns(&start) : 0);
+	ts = ns_to_timespec(dt);
+	ret = t_io_uring_wait(&ring, 1, enter_flags, &ts);
+	if (ret != -ETIME) {
+		fprintf(stderr, "wait timeout failed, %i\n", ret);
+		return 1;
+	}
+
+	dt = ns_since(&start);
+	if (dt < IO_NSEC_PER_SEC || dt > 3 * IO_NSEC_PER_SEC) {
+		fprintf(stderr, "early wake up, %lld\n", dt);
+		return 1;
+	}
+	return 0;
+}
+
+static int test_clock_setup(void)
+{
+	struct io_uring ring;
+	struct io_uring_clock_register cr = {};
+	int ret;
+
+	ret = io_uring_queue_init(8, &ring, 0);
+	if (ret) {
+		fprintf(stderr, "ring setup failed: %d\n", ret);
+		return T_EXIT_FAIL;
+	}
+
+	ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, NULL, 0);
+	if (!ret) {
+		fprintf(stderr, "invalid null clock registration %i\n", ret);
+		return T_EXIT_FAIL;
+	}
+
+	cr.clockid = -1;
+	ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, &cr, 0);
+	if (ret != -EINVAL) {
+		fprintf(stderr, "invalid clockid registration %i\n", ret);
+		return T_EXIT_FAIL;
+	}
+
+	cr.clockid = CLOCK_MONOTONIC;
+	ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, &cr, 0);
+	if (ret) {
+		fprintf(stderr, "clock monotonic registration failed %i\n", ret);
+		return T_EXIT_FAIL;
+	}
+
+	cr.clockid = CLOCK_BOOTTIME;
+	ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, &cr, 0);
+	if (ret) {
+		fprintf(stderr, "clock boottime registration failed %i\n", ret);
+		return T_EXIT_FAIL;
+	}
+
+	cr.clockid = CLOCK_MONOTONIC;
+	ret = __sys_io_uring_register(ring.ring_fd, IORING_REGISTER_CLOCK, &cr, 0);
+	if (ret) {
+		fprintf(stderr, "2nd clock monotonic registration failed %i\n", ret);
+		return T_EXIT_FAIL;
+	}
+
+	io_uring_queue_exit(&ring);
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	int ret, i;
+
+	if (argc > 1)
+		return 0;
+
+	ret = probe_timers();
+	if (ret) {
+		fprintf(stderr, "probe failed\n");
+		return T_EXIT_FAIL;
+	}
+	if (!support_abs && !support_clock)
+		return T_EXIT_SKIP;
+
+	if (support_clock) {
+		ret = test_clock_setup();
+		if (ret) {
+			fprintf(stderr, "test_clock_setup failed\n");
+			return T_EXIT_FAIL;
+		}
+	}
+
+	for (i = 0; i < 4; i++) {
+		bool abs = i & 1;
+		bool clock = i & 2;
+
+		if (abs && !support_abs)
+			continue;
+		if (clock && !support_clock)
+			continue;
+
+		ret = test_timeout(abs, clock);
+		if (ret) {
+			fprintf(stderr, "test_timeout failed %i %i\n",
+					abs, clock);
+			return ret;
+		}
+	}
+
+	return 0;
+}
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH liburing 4/4] man: document clock id and IORING_ENTER_ABS_TIMER
  2024-08-18 18:55 [PATCH liburing 0/4] Tests for absolute timeouts and clockids Pavel Begunkov
                   ` (2 preceding siblings ...)
  2024-08-18 18:55 ` [PATCH liburing 3/4] test: test clockids and abs timeouts Pavel Begunkov
@ 2024-08-18 18:55 ` Pavel Begunkov
  2024-08-18 19:39 ` [PATCH liburing 0/4] Tests for absolute timeouts and clockids Jens Axboe
  2024-08-18 19:40 ` Jens Axboe
  5 siblings, 0 replies; 7+ messages in thread
From: Pavel Begunkov @ 2024-08-18 18:55 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Signed-off-by: Pavel Begunkov <[email protected]>
---
 man/io_uring_enter.2    | 12 ++++++++++++
 man/io_uring_register.2 | 20 ++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/man/io_uring_enter.2 b/man/io_uring_enter.2
index 5e4121b..8c79771 100644
--- a/man/io_uring_enter.2
+++ b/man/io_uring_enter.2
@@ -105,6 +105,18 @@ then setting this flag will tell the kernel that the
 .I ring_fd
 passed in is the registered ring offset rather than a normal file descriptor.
 
+.TP
+.B IORING_ENTER_ABS_TIMER
+
+When this flag is set, the timeout argument passed in
+.I struct io_uring_getevents_arg
+will be interpreted as an absolute
+time of the registered clock (see
+.B IORING_REGISTER_CLOCK
+) until which the waiting should end.
+
+Available since 6.12
+
 .PP
 .PP
 If the io_uring instance was configured for polling, by specifying
diff --git a/man/io_uring_register.2 b/man/io_uring_register.2
index 4590588..c8521b7 100644
--- a/man/io_uring_register.2
+++ b/man/io_uring_register.2
@@ -720,6 +720,26 @@ The application must have registered a file table first.
 
 Available since 6.0.
 
+.TP
+.B IORING_REGISTER_CLOCK
+Specifies which clock id io_uring will use for timers while waiting for
+completion events with
+.B IORING_ENTER_GETEVENTS.
+It's only effective if the timeout argument in
+.I struct io_uring_getevents_arg
+is passed, ignored otherwise.
+When used in conjunction with
+.B IORING_ENTER_ABS_TIMER,
+interprets the timeout argument as absolute time of the specified clock.
+
+The default clock is
+.B CLOCK_MONOTONIC.
+
+Available since 6.12 and supports
+.B CLOCK_MONOTONIC
+and
+.B CLOCK_BOOTTIME.
+
 .SH RETURN VALUE
 
 On success,
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH liburing 0/4] Tests for absolute timeouts and clockids
  2024-08-18 18:55 [PATCH liburing 0/4] Tests for absolute timeouts and clockids Pavel Begunkov
                   ` (3 preceding siblings ...)
  2024-08-18 18:55 ` [PATCH liburing 4/4] man: document clock id and IORING_ENTER_ABS_TIMER Pavel Begunkov
@ 2024-08-18 19:39 ` Jens Axboe
  2024-08-18 19:40 ` Jens Axboe
  5 siblings, 0 replies; 7+ messages in thread
From: Jens Axboe @ 2024-08-18 19:39 UTC (permalink / raw)
  To: io-uring, Pavel Begunkov


On Sun, 18 Aug 2024 19:55:40 +0100, Pavel Begunkov wrote:
> Add definitions, tests and documentation for IORING_ENTER_ABS_TIMER
> and IORING_REGISTER_CLOCK.
> 
> It also adds helpers for registering clocks but not for absolute
> timeouts. Currently, liburing does't provide a way to pass custom
> enter flags.
> 
> [...]

Applied, thanks!

[1/4] Sync kernel headers
      commit: 2fce7b7067a2443dcba8c94254efc3b1c6f84235
[2/4] src/register: add clock id registration helper
      commit: eed5cab0138531ff308c975825d01654644f0b42
[3/4] test: test clockids and abs timeouts
      commit: 050dd942acd02362299bde09ba794681052e1ebe
[4/4] man: document clock id and IORING_ENTER_ABS_TIMER
      commit: fa347092fac1b28bd9100e617974708af379ac44

Best regards,
-- 
Jens Axboe




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH liburing 0/4] Tests for absolute timeouts and clockids
  2024-08-18 18:55 [PATCH liburing 0/4] Tests for absolute timeouts and clockids Pavel Begunkov
                   ` (4 preceding siblings ...)
  2024-08-18 19:39 ` [PATCH liburing 0/4] Tests for absolute timeouts and clockids Jens Axboe
@ 2024-08-18 19:40 ` Jens Axboe
  5 siblings, 0 replies; 7+ messages in thread
From: Jens Axboe @ 2024-08-18 19:40 UTC (permalink / raw)
  To: Pavel Begunkov, io-uring

On 8/18/24 12:55 PM, Pavel Begunkov wrote:
> Add definitions, tests and documentation for IORING_ENTER_ABS_TIMER
> and IORING_REGISTER_CLOCK.
> 
> It also adds helpers for registering clocks but not for absolute
> timeouts. Currently, liburing does't provide a way to pass custom
> enter flags.

Applied, and then I wrote a quick io_uring_register_clock.3 man page
for it as well. Please double check it...

-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-08-18 19:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-18 18:55 [PATCH liburing 0/4] Tests for absolute timeouts and clockids Pavel Begunkov
2024-08-18 18:55 ` [PATCH liburing 1/4] Sync kernel headers Pavel Begunkov
2024-08-18 18:55 ` [PATCH liburing 2/4] src/register: add clock id registration helper Pavel Begunkov
2024-08-18 18:55 ` [PATCH liburing 3/4] test: test clockids and abs timeouts Pavel Begunkov
2024-08-18 18:55 ` [PATCH liburing 4/4] man: document clock id and IORING_ENTER_ABS_TIMER Pavel Begunkov
2024-08-18 19:39 ` [PATCH liburing 0/4] Tests for absolute timeouts and clockids Jens Axboe
2024-08-18 19:40 ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox