From: Dylan Yudaken <[email protected]>
To: <[email protected]>, <[email protected]>
Cc: <[email protected]>, <[email protected]>,
Dylan Yudaken <[email protected]>
Subject: [PATCH liburing v3 05/11] update existing tests for defer taskrun
Date: Mon, 5 Sep 2022 06:22:52 -0700 [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
Add defer_taskrun to a few choice tests that can expose some bad
behaviour.
This requires adding some io_uring_get_events calls to make sure deferred
tasks are run
Signed-off-by: Dylan Yudaken <[email protected]>
---
test/eventfd-disable.c | 33 ++++++++++++++++++++++---
test/iopoll.c | 17 +++++++++----
test/multicqes_drain.c | 50 +++++++++++++++++++++++++++++++++-----
test/poll-mshot-overflow.c | 40 +++++++++++++++++++++++++++---
test/recv-multishot.c | 33 ++++++++++++++++---------
test/rsrc_tags.c | 10 ++++++--
6 files changed, 152 insertions(+), 31 deletions(-)
diff --git a/test/eventfd-disable.c b/test/eventfd-disable.c
index 2c8cf6dad7c1..162f9f9bc783 100644
--- a/test/eventfd-disable.c
+++ b/test/eventfd-disable.c
@@ -15,7 +15,7 @@
#include "liburing.h"
#include "helpers.h"
-int main(int argc, char *argv[])
+static int test(bool defer)
{
struct io_uring_params p = {};
struct io_uring_sqe *sqe;
@@ -28,8 +28,9 @@ int main(int argc, char *argv[])
};
int ret, evfd, i;
- if (argc > 1)
- return T_EXIT_SKIP;
+ if (defer)
+ p.flags |= IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN;
ret = io_uring_queue_init_params(64, &ring, &p);
if (ret) {
@@ -148,5 +149,31 @@ int main(int argc, char *argv[])
io_uring_cqe_seen(&ring, cqe);
}
+ io_uring_queue_exit(&ring);
+ close(evfd);
return T_EXIT_PASS;
}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = test(false);
+ if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "%s: test(false) failed\n", argv[0]);
+ return ret;
+ }
+
+ if (t_probe_defer_taskrun()) {
+ ret = test(true);
+ if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "%s: test(true) failed\n", argv[0]);
+ return ret;
+ }
+ }
+
+ return ret;
+}
diff --git a/test/iopoll.c b/test/iopoll.c
index 91cb71bd2e9c..20f91c7947be 100644
--- a/test/iopoll.c
+++ b/test/iopoll.c
@@ -274,7 +274,7 @@ ok:
}
static int test_io(const char *file, int write, int sqthread, int fixed,
- int buf_select)
+ int buf_select, int defer)
{
struct io_uring ring;
int ret, ring_flags = IORING_SETUP_IOPOLL;
@@ -282,6 +282,10 @@ static int test_io(const char *file, int write, int sqthread, int fixed,
if (no_iopoll)
return 0;
+ if (defer)
+ ring_flags |= IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN;
+
ret = t_create_ring(64, &ring, ring_flags);
if (ret == T_SETUP_SKIP)
return 0;
@@ -337,19 +341,22 @@ int main(int argc, char *argv[])
vecs = t_create_buffers(BUFFERS, BS);
- nr = 16;
+ nr = 32;
if (no_buf_select)
nr = 8;
+ else if (!t_probe_defer_taskrun())
+ nr = 16;
for (i = 0; i < nr; i++) {
int write = (i & 1) != 0;
int sqthread = (i & 2) != 0;
int fixed = (i & 4) != 0;
int buf_select = (i & 8) != 0;
+ int defer = (i & 16) != 0;
- ret = test_io(fname, write, sqthread, fixed, buf_select);
+ ret = test_io(fname, write, sqthread, fixed, buf_select, defer);
if (ret) {
- fprintf(stderr, "test_io failed %d/%d/%d/%d\n",
- write, sqthread, fixed, buf_select);
+ fprintf(stderr, "test_io failed %d/%d/%d/%d/%d\n",
+ write, sqthread, fixed, buf_select, defer);
goto err;
}
if (no_iopoll)
diff --git a/test/multicqes_drain.c b/test/multicqes_drain.c
index 6cd03ba5f3f7..f95c4382b3f4 100644
--- a/test/multicqes_drain.c
+++ b/test/multicqes_drain.c
@@ -233,6 +233,8 @@ static int test_generic_drain(struct io_uring *ring)
if (trigger_event(pipes[i]))
goto err;
+
+ io_uring_get_events(ring);
}
sleep(1);
i = 0;
@@ -246,7 +248,7 @@ static int test_generic_drain(struct io_uring *ring)
* compl_bits is a bit map to record completions.
* eg. sqe[0], sqe[1], sqe[2] fully completed
* then compl_bits is 000...00111b
- *
+ *
*/
unsigned long long compl_bits = 0;
for (j = 0; j < i; j++) {
@@ -295,7 +297,12 @@ static int test_simple_drain(struct io_uring *ring)
io_uring_prep_poll_add(sqe[1], pipe2[0], POLLIN);
sqe[1]->user_data = 1;
- ret = io_uring_submit(ring);
+ /* This test relies on multishot poll to trigger events continually.
+ * however with IORING_SETUP_DEFER_TASKRUN this will only happen when
+ * triggered with a get_events. Hence we sprinkle get_events whenever
+ * there might be work to process in order to get the same result
+ */
+ ret = io_uring_submit_and_get_events(ring);
if (ret < 0) {
printf("sqe submit failed\n");
goto err;
@@ -307,9 +314,11 @@ static int test_simple_drain(struct io_uring *ring)
for (i = 0; i < 2; i++) {
if (trigger_event(pipe1))
goto err;
+ io_uring_get_events(ring);
}
if (trigger_event(pipe2))
goto err;
+ io_uring_get_events(ring);
for (i = 0; i < 2; i++) {
sqe[i] = io_uring_get_sqe(ring);
@@ -355,15 +364,17 @@ err:
return 1;
}
-int main(int argc, char *argv[])
+static int test(bool defer_taskrun)
{
struct io_uring ring;
int i, ret;
+ unsigned int flags = 0;
- if (argc > 1)
- return T_EXIT_SKIP;
+ if (defer_taskrun)
+ flags = IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN;
- ret = io_uring_queue_init(1024, &ring, 0);
+ ret = io_uring_queue_init(1024, &ring, flags);
if (ret) {
printf("ring setup failed\n");
return T_EXIT_FAIL;
@@ -384,5 +395,32 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}
}
+
+ io_uring_queue_exit(&ring);
+
return T_EXIT_PASS;
}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = test(false);
+ if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "%s: test(false) failed\n", argv[0]);
+ return ret;
+ }
+
+ if (t_probe_defer_taskrun()) {
+ ret = test(true);
+ if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "%s: test(true) failed\n", argv[0]);
+ return ret;
+ }
+ }
+
+ return ret;
+}
diff --git a/test/poll-mshot-overflow.c b/test/poll-mshot-overflow.c
index 360df65d2b15..431a337f19ae 100644
--- a/test/poll-mshot-overflow.c
+++ b/test/poll-mshot-overflow.c
@@ -42,7 +42,7 @@ int check_final_cqe(struct io_uring *ring)
return T_EXIT_PASS;
}
-int main(int argc, char *argv[])
+static int test(bool defer_taskrun)
{
struct io_uring_cqe *cqe;
struct io_uring_sqe *sqe;
@@ -50,9 +50,6 @@ int main(int argc, char *argv[])
int pipe1[2];
int ret, i;
- if (argc > 1)
- return 0;
-
if (pipe(pipe1) != 0) {
perror("pipe");
return T_EXIT_FAIL;
@@ -66,6 +63,10 @@ int main(int argc, char *argv[])
.cq_entries = 2
};
+ if (defer_taskrun)
+ params.flags |= IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN;
+
ret = io_uring_queue_init_params(2, &ring, ¶ms);
if (ret)
return T_EXIT_SKIP;
@@ -113,6 +114,9 @@ int main(int argc, char *argv[])
io_uring_cqe_seen(&ring, cqe);
}
+ /* make sure everything is processed */
+ io_uring_get_events(&ring);
+
/* now remove the poll */
sqe = io_uring_get_sqe(&ring);
io_uring_prep_poll_remove(sqe, 1);
@@ -126,5 +130,33 @@ int main(int argc, char *argv[])
ret = check_final_cqe(&ring);
+ close(pipe1[0]);
+ close(pipe1[1]);
+ io_uring_queue_exit(&ring);
+
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = test(false);
+ if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "%s: test(false) failed\n", argv[0]);
+ return ret;
+ }
+
+ if (t_probe_defer_taskrun()) {
+ ret = test(true);
+ if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "%s: test(true) failed\n", argv[0]);
+ return ret;
+ }
+ }
+
return ret;
}
diff --git a/test/recv-multishot.c b/test/recv-multishot.c
index a322e4317232..1a041f8e865a 100644
--- a/test/recv-multishot.c
+++ b/test/recv-multishot.c
@@ -29,6 +29,7 @@ struct args {
bool wait_each;
bool recvmsg;
enum early_error_t early_error;
+ bool defer;
};
static int check_sockaddr(struct sockaddr_in *in)
@@ -76,19 +77,22 @@ static int test(struct args *args)
.tv_sec = 1,
};
struct msghdr msg;
+ struct io_uring_params params = { };
+ int n_sqe = 32;
memset(recv_buffs, 0, sizeof(recv_buffs));
- if (args->early_error == ERROR_EARLY_OVERFLOW) {
- struct io_uring_params params = {
- .flags = IORING_SETUP_CQSIZE,
- .cq_entries = N_CQE_OVERFLOW
- };
+ if (args->defer)
+ params.flags |= IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN;
- ret = io_uring_queue_init_params(N_CQE_OVERFLOW, &ring, ¶ms);
- } else {
- ret = io_uring_queue_init(32, &ring, 0);
+ if (args->early_error == ERROR_EARLY_OVERFLOW) {
+ params.flags |= IORING_SETUP_CQSIZE;
+ params.cq_entries = N_CQE_OVERFLOW;
+ n_sqe = N_CQE_OVERFLOW;
}
+
+ ret = io_uring_queue_init_params(n_sqe, &ring, ¶ms);
if (ret) {
fprintf(stderr, "queue init failed: %d\n", ret);
return ret;
@@ -457,23 +461,30 @@ int main(int argc, char *argv[])
int ret;
int loop;
int early_error = 0;
+ bool has_defer;
if (argc > 1)
return T_EXIT_SKIP;
- for (loop = 0; loop < 8; loop++) {
+ has_defer = t_probe_defer_taskrun();
+
+ for (loop = 0; loop < 16; loop++) {
struct args a = {
.stream = loop & 0x01,
.wait_each = loop & 0x2,
.recvmsg = loop & 0x04,
+ .defer = loop & 0x08,
};
+ if (a.defer && !has_defer)
+ continue;
for (early_error = 0; early_error < ERROR_EARLY_LAST; early_error++) {
a.early_error = (enum early_error_t)early_error;
ret = test(&a);
if (ret) {
fprintf(stderr,
- "test stream=%d wait_each=%d recvmsg=%d early_error=%d failed\n",
- a.stream, a.wait_each, a.recvmsg, a.early_error);
+ "test stream=%d wait_each=%d recvmsg=%d early_error=%d "
+ " defer=%d failed\n",
+ a.stream, a.wait_each, a.recvmsg, a.early_error, a.defer);
return T_EXIT_FAIL;
}
if (no_recv_mshot)
diff --git a/test/rsrc_tags.c b/test/rsrc_tags.c
index 22370644b200..047e844acfbd 100644
--- a/test/rsrc_tags.c
+++ b/test/rsrc_tags.c
@@ -401,7 +401,8 @@ static int test_notag(void)
int main(int argc, char *argv[])
{
- int ring_flags[] = {0, IORING_SETUP_IOPOLL, IORING_SETUP_SQPOLL};
+ int ring_flags[] = {0, IORING_SETUP_IOPOLL, IORING_SETUP_SQPOLL,
+ IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN};
int i, ret;
if (argc > 1)
@@ -423,7 +424,12 @@ int main(int argc, char *argv[])
}
for (i = 0; i < sizeof(ring_flags) / sizeof(ring_flags[0]); i++) {
- ret = test_files(ring_flags[i]);
+ int flag = ring_flags[i];
+
+ if (flag & IORING_SETUP_DEFER_TASKRUN && !t_probe_defer_taskrun())
+ continue;
+
+ ret = test_files(flag);
if (ret) {
printf("test_tag failed, type %i\n", i);
return ret;
--
2.30.2
next prev parent reply other threads:[~2022-09-05 13:25 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-05 13:22 [PATCH liburing v3 00/11] Defer taskrun changes Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 01/11] Copy defer task run definition from kernel Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 02/11] Add documentation for IORING_SETUP_DEFER_TASKRUN flag Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 03/11] add io_uring_submit_and_get_events and io_uring_get_events Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 04/11] add a t_probe_defer_taskrun helper function for tests Dylan Yudaken
2022-09-05 13:22 ` Dylan Yudaken [this message]
2022-09-05 13:22 ` [PATCH liburing v3 06/11] add a defer-taskrun test Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 07/11] update io_uring_enter.2 docs for IORING_FEAT_NODROP Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 08/11] add docs for overflow lost errors Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 09/11] expose CQ ring overflow state Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 10/11] overflow: add tests Dylan Yudaken
2022-09-05 13:22 ` [PATCH liburing v3 11/11] file-verify test: log if short read Dylan Yudaken
2022-09-05 13:45 ` [PATCH liburing v3 00/11] Defer taskrun changes Ammar Faizi
2022-09-05 17:42 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox