[PATCH 1/2] test/link-timeout: add natural disarm chain with short pipe read

Yang Xiuwei <[email protected]>
Newsgroups org.kernel.vger.io-uring
Message-ID <[email protected]>
Add a test for read -> link timeout -> nop where the read completes
with a short pipe read, the link timeout is naturally disarmed with
-ECANCELED, and the linked nop still completes successfully.

Requires the kernel fix for short pipe read completion.

Signed-off-by: Yang Xiuwei <[email protected]>
---
 test/link-timeout.c | 102 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/test/link-timeout.c b/test/link-timeout.c
index 0e91604f..07856ff3 100644
--- a/test/link-timeout.c
+++ b/test/link-timeout.c
@@ -671,6 +671,103 @@ err:
 	return 1;
 }
 
+/*
+ * Test short pipe read that naturally disarms a link timeout
+ */
+static int test_link_timeout_natural_disarm_chain(struct io_uring *ring)
+{
+	struct __kernel_timespec ts;
+	struct io_uring_cqe *cqe;
+	struct io_uring_sqe *sqe;
+	int fds[2], ret, i;
+	struct iovec iov;
+	char buffer[128];
+	char byte = 'x';
+
+	if (pipe(fds)) {
+		perror("pipe");
+		return 1;
+	}
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		printf("get sqe failed\n");
+		goto err;
+	}
+
+	iov.iov_base = buffer;
+	iov.iov_len = sizeof(buffer);
+	io_uring_prep_readv(sqe, fds[0], &iov, 1, 0);
+	sqe->flags |= IOSQE_IO_LINK;
+	sqe->user_data = 1;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		printf("get sqe failed\n");
+		goto err;
+	}
+
+	ts.tv_sec = 3600;
+	ts.tv_nsec = 0;
+	io_uring_prep_link_timeout(sqe, &ts, 0);
+	sqe->flags |= IOSQE_IO_LINK;
+	sqe->user_data = 2;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		printf("get sqe failed\n");
+		goto err;
+	}
+	io_uring_prep_nop(sqe);
+	sqe->user_data = 3;
+
+	ret = io_uring_submit(ring);
+	if (ret != 3) {
+		printf("sqe submit failed: %d\n", ret);
+		goto err;
+	}
+
+	if (write(fds[1], &byte, 1) != 1) {
+		perror("write");
+		goto err;
+	}
+
+	for (i = 0; i < 3; i++) {
+		ret = io_uring_wait_cqe(ring, &cqe);
+		if (ret < 0) {
+			printf("wait completion %d\n", ret);
+			goto err;
+		}
+		switch (cqe->user_data) {
+		case 1:
+			if (cqe->res != 1) {
+				fprintf(stderr, "Read got %d, wanted 1\n", cqe->res);
+				goto err;
+			}
+			break;
+		case 2:
+			if (cqe->res != -ECANCELED) {
+				fprintf(stderr, "Link timeout got %d, wanted -ECANCELED\n",
+					cqe->res);
+				goto err;
+			}
+			break;
+		case 3:
+			if (cqe->res) {
+				fprintf(stderr, "Req %" PRIu64 " got %d\n",
+					(uint64_t) cqe->user_data, cqe->res);
+				goto err;
+			}
+			break;
+		}
+		io_uring_cqe_seen(ring, cqe);
+	}
+
+	return 0;
+err:
+	return 1;
+}
+
 static int test_timeout_link_chain1(struct io_uring *ring)
 {
 	struct __kernel_timespec ts;
@@ -1262,6 +1359,11 @@ int main(int argc, char *argv[])
 		return ret;
 	}
 
+	ret = test_link_timeout_natural_disarm_chain(&ring);
+	if (ret) {
+		printf("test_link_timeout_natural_disarm_chain failed\n");
+		return ret;
+	}
 
 	return T_EXIT_PASS;
 }
-- 
2.25.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.