* [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 <[email protected]>
---
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 related [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 <[email protected]>
> ---
>
> 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