io-uring.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH liburing v2] tests: test early-submit link fails
@ 2021-08-31 15:49 Pavel Begunkov
  2021-08-31 17:03 ` Jens Axboe
  2021-09-01 18:04 ` Hao Xu
  0 siblings, 2 replies; 4+ messages in thread
From: Pavel Begunkov @ 2021-08-31 15:49 UTC (permalink / raw)
  To: Jens Axboe, io-uring; +Cc: Hao Xu

Add a whole bunch of tests for when linked requests fail early during
submission.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---

v2: correct io_uring_submit() ret checks with !drain

 .gitignore              |   1 +
 test/Makefile           |   2 +
 test/submit-link-fail.c | 150 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 153 insertions(+)
 create mode 100644 test/submit-link-fail.c

diff --git a/.gitignore b/.gitignore
index 3d67ef9..df0f740 100644
--- a/.gitignore
+++ b/.gitignore
@@ -128,6 +128,7 @@
 /test/rw_merge_test
 /test/sqpoll-cancel-hang
 /test/testfile
+/test/submit-link-fail
 /test/*.dmesg
 
 config-host.h
diff --git a/test/Makefile b/test/Makefile
index d392b95..775e3bb 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -123,6 +123,7 @@ test_targets += \
 	sq-space_left \
 	stdout \
 	submit-reuse \
+	submit-link-fail \
 	symlink \
 	teardowns \
 	thread-exit \
@@ -264,6 +265,7 @@ test_srcs := \
 	statx.c \
 	stdout.c \
 	submit-reuse.c \
+	submit-link-fail.c \
 	symlink.c \
 	teardowns.c \
 	thread-exit.c \
diff --git a/test/submit-link-fail.c b/test/submit-link-fail.c
new file mode 100644
index 0000000..b79aa7c
--- /dev/null
+++ b/test/submit-link-fail.c
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: tests linked requests failing during submission
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <assert.h>
+
+#include "liburing.h"
+
+#define DRAIN_USER_DATA 42
+
+static int test_underprep_fail(bool hardlink, bool drain, bool link_last,
+			       int link_size, int fail_idx)
+{
+	const int invalid_fd = 42;
+	int link_flags = IOSQE_IO_LINK;
+	int total_submit = link_size;
+	struct io_uring ring;
+	struct io_uring_sqe *sqe;
+	struct io_uring_cqe *cqe;
+	char buffer[1];
+	int i, ret, fds[2];
+
+	if (drain)
+		link_flags |= IOSQE_IO_DRAIN;
+	if (hardlink)
+		link_flags |= IOSQE_IO_HARDLINK;
+
+	assert(fail_idx < link_size);
+	assert(link_size < 40);
+
+	/* create a new ring as it leaves it dirty */
+	ret = io_uring_queue_init(8, &ring, 0);
+	if (ret) {
+		printf("ring setup failed\n");
+		return -1;
+	}
+	if (pipe(fds)) {
+		perror("pipe");
+		return -1;
+	}
+
+	if (drain) {
+		/* clog drain, so following reqs sent to draining */
+		sqe = io_uring_get_sqe(&ring);
+		io_uring_prep_read(sqe, fds[0], buffer, sizeof(buffer), 0);
+		sqe->user_data = DRAIN_USER_DATA;
+		sqe->flags |= IOSQE_IO_DRAIN;
+		total_submit++;
+	}
+
+	for (i = 0; i < link_size; i++) {
+		sqe = io_uring_get_sqe(&ring);
+		if (i == fail_idx)
+			io_uring_prep_read(sqe, invalid_fd, buffer, 1, 0);
+		else
+			io_uring_prep_nop(sqe);
+
+		if (i != link_size - 1 || !link_last)
+			sqe->flags |= link_flags;
+		sqe->user_data = i;
+	}
+
+	ret = io_uring_submit(&ring);
+	if (ret != total_submit) {
+		/* Old behaviour, failed early and under-submitted */
+		if (ret == fail_idx + 1 + drain)
+			goto out;
+		fprintf(stderr, "submit failed: %d\n", ret);
+		return -1;
+	}
+
+	if (drain) {
+		/* unclog drain */
+		write(fds[1], buffer, sizeof(buffer));
+	}
+
+	for (i = 0; i < total_submit; i++) {
+		ret = io_uring_wait_cqe(&ring, &cqe);
+		if (ret) {
+			fprintf(stderr, "wait_cqe=%d\n", ret);
+			return 1;
+		}
+
+		ret = cqe->res;
+		if (cqe->user_data == DRAIN_USER_DATA) {
+			if (ret != 1) {
+				fprintf(stderr, "drain failed %d\n", ret);
+				return 1;
+			}
+		} else if (cqe->user_data == fail_idx) {
+			if (ret == 0 || ret == -ECANCELED) {
+				fprintf(stderr, "half-prep req unexpected return %d\n", ret);
+				return 1;
+			}
+		} else {
+			if (ret != -ECANCELED) {
+				fprintf(stderr, "cancel failed %d, ud %d\n", ret, (int)cqe->user_data);
+				return 1;
+			}
+		}
+		io_uring_cqe_seen(&ring, cqe);
+	}
+out:
+	close(fds[0]);
+	close(fds[1]);
+	io_uring_queue_exit(&ring);
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	int ret, link_size, fail_idx, i;
+
+	if (argc > 1)
+		return 0;
+
+	/*
+	 * hardlink, size=3, fail_idx=1, drain=false -- kernel fault
+	 * link, size=3, fail_idx=0, drain=true -- kernel fault
+	 * link, size=3, fail_idx=1, drain=true -- invalid cqe->res
+	 */
+	for (link_size = 0; link_size < 3; link_size++) {
+		for (fail_idx = 0; fail_idx < link_size; fail_idx++) {
+			for (i = 0; i < 8; i++) {
+				bool hardlink = (i & 1) != 0;
+				bool drain = (i & 2) != 0;
+				bool link_last = (i & 4) != 0;
+
+				ret = test_underprep_fail(hardlink, drain, link_last,
+							  link_size, fail_idx);
+				if (!ret)
+					continue;
+
+				fprintf(stderr, "failed %d, hard %d, drain %d,"
+						"link_last %d, size %d, idx %d\n",
+						ret, hardlink, drain, link_last,
+						link_size, fail_idx);
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
-- 
2.33.0


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

* Re: [PATCH liburing v2] tests: test early-submit link fails
  2021-08-31 15:49 [PATCH liburing v2] tests: test early-submit link fails Pavel Begunkov
@ 2021-08-31 17:03 ` Jens Axboe
  2021-08-31 18:15   ` Pavel Begunkov
  2021-09-01 18:04 ` Hao Xu
  1 sibling, 1 reply; 4+ messages in thread
From: Jens Axboe @ 2021-08-31 17:03 UTC (permalink / raw)
  To: Pavel Begunkov, io-uring; +Cc: Hao Xu

On 8/31/21 9:49 AM, Pavel Begunkov wrote:
> Add a whole bunch of tests for when linked requests fail early during
> submission.

Applied, but remember to check write(2) returns:

submit-link-fail.c: In function ‘test_underprep_fail’:
submit-link-fail.c:80:17: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   80 |                 write(fds[1], buffer, sizeof(buffer));
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


-- 
Jens Axboe


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

* Re: [PATCH liburing v2] tests: test early-submit link fails
  2021-08-31 17:03 ` Jens Axboe
@ 2021-08-31 18:15   ` Pavel Begunkov
  0 siblings, 0 replies; 4+ messages in thread
From: Pavel Begunkov @ 2021-08-31 18:15 UTC (permalink / raw)
  To: Jens Axboe, io-uring; +Cc: Hao Xu

On 8/31/21 6:03 PM, Jens Axboe wrote:
> On 8/31/21 9:49 AM, Pavel Begunkov wrote:
>> Add a whole bunch of tests for when linked requests fail early during
>> submission.
> 
> Applied, but remember to check write(2) returns:
> 
> submit-link-fail.c: In function ‘test_underprep_fail’:
> submit-link-fail.c:80:17: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
>    80 |                 write(fds[1], buffer, sizeof(buffer));
>       |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

My bad. Interesting why my gcc 11 doesn't complain.

-- 
Pavel Begunkov

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

* Re: [PATCH liburing v2] tests: test early-submit link fails
  2021-08-31 15:49 [PATCH liburing v2] tests: test early-submit link fails Pavel Begunkov
  2021-08-31 17:03 ` Jens Axboe
@ 2021-09-01 18:04 ` Hao Xu
  1 sibling, 0 replies; 4+ messages in thread
From: Hao Xu @ 2021-09-01 18:04 UTC (permalink / raw)
  To: Pavel Begunkov, Jens Axboe, io-uring

在 2021/8/31 下午11:49, Pavel Begunkov 写道:
> Add a whole bunch of tests for when linked requests fail early during
> submission.
> 
> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
> ---
> 
> v2: correct io_uring_submit() ret checks with !drain
> 
Thanks for this test.

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

end of thread, other threads:[~2021-09-01 18:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-31 15:49 [PATCH liburing v2] tests: test early-submit link fails Pavel Begunkov
2021-08-31 17:03 ` Jens Axboe
2021-08-31 18:15   ` Pavel Begunkov
2021-09-01 18:04 ` Hao Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).