* [PATCH liburing 1/3] test: handle test_send_faults()'s cases one by one
2024-04-08 14:24 [PATCH liburing 0/3] improve sendzc tests Pavel Begunkov
@ 2024-04-08 14:24 ` Pavel Begunkov
2024-04-08 14:24 ` [PATCH liburing 2/3] test/sendzc: improve zc support probing Pavel Begunkov
2024-04-08 14:24 ` [PATCH liburing 3/3] io_uring/sendzc: add DEFER_TASKRUN testing Pavel Begunkov
2 siblings, 0 replies; 5+ messages in thread
From: Pavel Begunkov @ 2024-04-08 14:24 UTC (permalink / raw)
To: io-uring; +Cc: Jens Axboe, asml.silence
There are 3 different cases tested by test_send_faults(), requests for
which are sent together. That's not too convenient, complicates CQEs
checking and opens some space for error. Do them one at a time.
Signed-off-by: Pavel Begunkov <[email protected]>
---
test/send-zerocopy.c | 105 +++++++++++++++++++++++++++++--------------
1 file changed, 71 insertions(+), 34 deletions(-)
diff --git a/test/send-zerocopy.c b/test/send-zerocopy.c
index 1b6dd77..78ec3d7 100644
--- a/test/send-zerocopy.c
+++ b/test/send-zerocopy.c
@@ -122,17 +122,60 @@ static int test_basic_send(struct io_uring *ring, int sock_tx, int sock_rx)
return T_EXIT_PASS;
}
+static int test_send_faults_check(struct io_uring *ring, int expected)
+{
+ struct io_uring_cqe *cqe;
+ int ret, nr_cqes = 0;
+ bool more = true;
+
+ while (more) {
+ nr_cqes++;
+ ret = io_uring_wait_cqe(ring, &cqe);
+ assert(!ret);
+ assert(cqe->user_data == 1);
+
+ if (nr_cqes == 1 && (cqe->flags & IORING_CQE_F_NOTIF)) {
+ fprintf(stderr, "test_send_faults_check notif came first\n");
+ return -1;
+ }
+
+ if (!(cqe->flags & IORING_CQE_F_NOTIF)) {
+ if (cqe->res != expected) {
+ fprintf(stderr, "invalid cqe res %i vs expected %i, "
+ "user_data %i\n",
+ cqe->res, expected, (int)cqe->user_data);
+ return -1;
+ }
+ } else {
+ if (cqe->res != 0 || cqe->flags != IORING_CQE_F_NOTIF) {
+ fprintf(stderr, "invalid notif cqe %i %i\n",
+ cqe->res, cqe->flags);
+ return -1;
+ }
+ }
+
+ more = cqe->flags & IORING_CQE_F_MORE;
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ if (nr_cqes > 2) {
+ fprintf(stderr, "test_send_faults_check() too many CQEs %i\n",
+ nr_cqes);
+ return -1;
+ }
+ assert(check_cq_empty(ring));
+ return 0;
+}
+
static int test_send_faults(int sock_tx, int sock_rx)
{
struct io_uring_sqe *sqe;
- struct io_uring_cqe *cqe;
int msg_flags = 0;
unsigned zc_flags = 0;
- int payload_size = 100;
- int ret, i, nr_cqes, nr_reqs = 3;
+ int ret, payload_size = 100;
struct io_uring ring;
- ret = io_uring_queue_init(32, &ring, IORING_SETUP_SUBMIT_ALL);
+ ret = io_uring_queue_init(32, &ring, 0);
if (ret) {
fprintf(stderr, "queue init failed: %d\n", ret);
return -1;
@@ -143,6 +186,14 @@ static int test_send_faults(int sock_tx, int sock_rx)
io_uring_prep_send_zc(sqe, sock_tx, (void *)1UL, payload_size,
msg_flags, zc_flags);
sqe->user_data = 1;
+ ret = io_uring_submit(&ring);
+ assert(ret == 1);
+
+ ret = test_send_faults_check(&ring, -EFAULT);
+ if (ret) {
+ fprintf(stderr, "test_send_faults with invalid buf failed\n");
+ return -1;
+ }
/* invalid address */
sqe = io_uring_get_sqe(&ring);
@@ -150,44 +201,30 @@ static int test_send_faults(int sock_tx, int sock_rx)
msg_flags, zc_flags);
io_uring_prep_send_set_addr(sqe, (const struct sockaddr *)1UL,
sizeof(struct sockaddr_in6));
- sqe->user_data = 2;
+ sqe->user_data = 1;
+ ret = io_uring_submit(&ring);
+ assert(ret == 1);
+
+ ret = test_send_faults_check(&ring, -EFAULT);
+ if (ret) {
+ fprintf(stderr, "test_send_faults with invalid addr failed\n");
+ return -1;
+ }
/* invalid send/recv flags */
sqe = io_uring_get_sqe(&ring);
io_uring_prep_send_zc(sqe, sock_tx, tx_buffer, payload_size,
msg_flags, ~0U);
- sqe->user_data = 3;
-
+ sqe->user_data = 1;
ret = io_uring_submit(&ring);
- assert(ret == nr_reqs);
-
- nr_cqes = nr_reqs;
- for (i = 0; i < nr_cqes; i++) {
- ret = io_uring_wait_cqe(&ring, &cqe);
- assert(!ret);
- assert(cqe->user_data <= nr_reqs);
-
- if (!(cqe->flags & IORING_CQE_F_NOTIF)) {
- int expected = (cqe->user_data == 3) ? -EINVAL : -EFAULT;
+ assert(ret == 1);
- if (cqe->res != expected) {
- fprintf(stderr, "invalid cqe res %i vs expected %i, "
- "user_data %i\n",
- cqe->res, expected, (int)cqe->user_data);
- return -1;
- }
- if (cqe->flags & IORING_CQE_F_MORE)
- nr_cqes++;
- } else {
- if (cqe->res != 0 || cqe->flags != IORING_CQE_F_NOTIF) {
- fprintf(stderr, "invalid notif cqe %i %i\n",
- cqe->res, cqe->flags);
- return -1;
- }
- }
- io_uring_cqe_seen(&ring, cqe);
+ ret = test_send_faults_check(&ring, -EINVAL);
+ if (ret) {
+ fprintf(stderr, "test_send_faults with invalid flags failed\n");
+ return -1;
}
- assert(check_cq_empty(&ring));
+
return T_EXIT_PASS;
}
--
2.44.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH liburing 2/3] test/sendzc: improve zc support probing
2024-04-08 14:24 [PATCH liburing 0/3] improve sendzc tests Pavel Begunkov
2024-04-08 14:24 ` [PATCH liburing 1/3] test: handle test_send_faults()'s cases one by one Pavel Begunkov
@ 2024-04-08 14:24 ` Pavel Begunkov
2024-04-08 14:24 ` [PATCH liburing 3/3] io_uring/sendzc: add DEFER_TASKRUN testing Pavel Begunkov
2 siblings, 0 replies; 5+ messages in thread
From: Pavel Begunkov @ 2024-04-08 14:24 UTC (permalink / raw)
To: io-uring; +Cc: Jens Axboe, asml.silence
Move probing whether we support zerocopy send or not to the beginning
instead of relying on test_basic_send().
Signed-off-by: Pavel Begunkov <[email protected]>
---
test/send-zerocopy.c | 64 +++++++++++++++++++++++++++-----------------
1 file changed, 40 insertions(+), 24 deletions(-)
diff --git a/test/send-zerocopy.c b/test/send-zerocopy.c
index 78ec3d7..bfb15d2 100644
--- a/test/send-zerocopy.c
+++ b/test/send-zerocopy.c
@@ -68,8 +68,37 @@ enum {
static size_t page_sz;
static char *tx_buffer, *rx_buffer;
static struct iovec buffers_iov[__BUF_NR];
+
+static bool has_sendzc;
static bool has_sendmsg;
+static int probe_zc_support(void)
+{
+ struct io_uring ring;
+ struct io_uring_probe *p;
+ int ret;
+
+ has_sendzc = has_sendmsg = false;
+
+ ret = io_uring_queue_init(1, &ring, 0);
+ if (ret)
+ return -1;
+
+ p = t_calloc(1, sizeof(*p) + 256 * sizeof(struct io_uring_probe_op));
+ if (!p)
+ return -1;
+
+ ret = io_uring_register_probe(&ring, p, 256);
+ if (ret)
+ return -1;
+
+ has_sendzc = p->ops_len > IORING_OP_SEND_ZC;
+ has_sendmsg = p->ops_len > IORING_OP_SENDMSG_ZC;
+ io_uring_queue_exit(&ring);
+ free(p);
+ return 0;
+}
+
static bool check_cq_empty(struct io_uring *ring)
{
struct io_uring_cqe *cqe = NULL;
@@ -98,10 +127,7 @@ static int test_basic_send(struct io_uring *ring, int sock_tx, int sock_rx)
ret = io_uring_wait_cqe(ring, &cqe);
assert(!ret && cqe->user_data == 1);
- if (cqe->res == -EINVAL) {
- assert(!(cqe->flags & IORING_CQE_F_MORE));
- return T_EXIT_SKIP;
- } else if (cqe->res != payload_size) {
+ if (cqe->res != payload_size) {
fprintf(stderr, "send failed %i\n", cqe->res);
return T_EXIT_FAIL;
}
@@ -700,22 +726,6 @@ static int test_async_addr(struct io_uring *ring)
return 0;
}
-static bool io_check_zc_sendmsg(struct io_uring *ring)
-{
- struct io_uring_probe *p;
- int ret;
-
- p = t_calloc(1, sizeof(*p) + 256 * sizeof(struct io_uring_probe_op));
- if (!p) {
- fprintf(stderr, "probe allocation failed\n");
- return false;
- }
- ret = io_uring_register_probe(ring, p, 256);
- if (ret)
- return false;
- return p->ops_len > IORING_OP_SENDMSG_ZC;
-}
-
/* see also send_recv.c:test_invalid */
static int test_invalid_zc(int fds[2])
{
@@ -769,6 +779,16 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
+ ret = probe_zc_support();
+ if (ret) {
+ printf("probe failed\n");
+ return T_EXIT_FAIL;
+ }
+ if (!has_sendzc) {
+ printf("no IORING_OP_SEND_ZC support, skip\n");
+ return T_EXIT_SKIP;
+ }
+
page_sz = sysconf(_SC_PAGESIZE);
/* create TCP IPv6 pair */
@@ -834,15 +854,11 @@ int main(int argc, char *argv[])
}
ret = test_basic_send(&ring, sp[0], sp[1]);
- if (ret == T_EXIT_SKIP)
- return ret;
if (ret) {
fprintf(stderr, "test_basic_send() failed\n");
return T_EXIT_FAIL;
}
- has_sendmsg = io_check_zc_sendmsg(&ring);
-
ret = test_send_faults(sp[0], sp[1]);
if (ret) {
fprintf(stderr, "test_send_faults() failed\n");
--
2.44.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH liburing 3/3] io_uring/sendzc: add DEFER_TASKRUN testing
2024-04-08 14:24 [PATCH liburing 0/3] improve sendzc tests Pavel Begunkov
2024-04-08 14:24 ` [PATCH liburing 1/3] test: handle test_send_faults()'s cases one by one Pavel Begunkov
2024-04-08 14:24 ` [PATCH liburing 2/3] test/sendzc: improve zc support probing Pavel Begunkov
@ 2024-04-08 14:24 ` Pavel Begunkov
2024-04-08 15:23 ` Pavel Begunkov
2 siblings, 1 reply; 5+ messages in thread
From: Pavel Begunkov @ 2024-04-08 14:24 UTC (permalink / raw)
To: io-uring; +Cc: Jens Axboe, asml.silence
Signed-off-by: Pavel Begunkov <[email protected]>
---
test/send-zerocopy.c | 166 +++++++++++++++++++++++++++----------------
1 file changed, 106 insertions(+), 60 deletions(-)
diff --git a/test/send-zerocopy.c b/test/send-zerocopy.c
index bfb15d2..4699cf6 100644
--- a/test/send-zerocopy.c
+++ b/test/send-zerocopy.c
@@ -769,12 +769,69 @@ static int test_invalid_zc(int fds[2])
return 0;
}
-int main(int argc, char *argv[])
+static int run_basic_tests(void)
{
struct sockaddr_storage addr;
- struct io_uring ring;
- int i, ret, sp[2];
+ int ret, i, sp[2];
+
+ /* create TCP IPv6 pair */
+ ret = create_socketpair_ip(&addr, &sp[0], &sp[1], true, true, false, true);
+ if (ret) {
+ fprintf(stderr, "sock prep failed %d\n", ret);
+ return -1;
+ }
+
+ for (i = 0; i < 2; i++) {
+ struct io_uring ring;
+ unsigned ring_flags = 0;
+
+ if (i & 1)
+ ring_flags |= IORING_SETUP_DEFER_TASKRUN;
+
+ ret = io_uring_queue_init(32, &ring, ring_flags);
+ if (ret) {
+ if (ret == -EINVAL)
+ continue;
+ fprintf(stderr, "queue init failed: %d\n", ret);
+ return -1;
+ }
+
+ ret = test_basic_send(&ring, sp[0], sp[1]);
+ if (ret) {
+ fprintf(stderr, "test_basic_send() failed\n");
+ return -1;
+ }
+
+ ret = test_send_faults(sp[0], sp[1]);
+ if (ret) {
+ fprintf(stderr, "test_send_faults() failed\n");
+ return -1;
+ }
+
+ ret = test_invalid_zc(sp);
+ if (ret) {
+ fprintf(stderr, "test_invalid_zc() failed\n");
+ return -1;
+ }
+
+ ret = test_async_addr(&ring);
+ if (ret) {
+ fprintf(stderr, "test_async_addr() failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_queue_exit(&ring);
+ }
+
+ close(sp[0]);
+ close(sp[1]);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
size_t len;
+ int ret, i;
if (argc > 1)
return T_EXIT_SKIP;
@@ -791,13 +848,6 @@ int main(int argc, char *argv[])
page_sz = sysconf(_SC_PAGESIZE);
- /* create TCP IPv6 pair */
- ret = create_socketpair_ip(&addr, &sp[0], &sp[1], true, true, false, true);
- if (ret) {
- fprintf(stderr, "sock prep failed %d\n", ret);
- return T_EXIT_FAIL;
- }
-
len = LARGE_BUF_SIZE;
tx_buffer = aligned_alloc(page_sz, len);
rx_buffer = aligned_alloc(page_sz, len);
@@ -847,65 +897,61 @@ int main(int argc, char *argv[])
}
}
- ret = io_uring_queue_init(32, &ring, 0);
- if (ret) {
- fprintf(stderr, "queue init failed: %d\n", ret);
+ ret = run_basic_tests();
+ if (ret)
return T_EXIT_FAIL;
- }
- ret = test_basic_send(&ring, sp[0], sp[1]);
- if (ret) {
- fprintf(stderr, "test_basic_send() failed\n");
- return T_EXIT_FAIL;
- }
+ for (i = 0; i < 2; i++) {
+ struct io_uring ring;
+ unsigned ring_flags = 0;
- ret = test_send_faults(sp[0], sp[1]);
- if (ret) {
- fprintf(stderr, "test_send_faults() failed\n");
- return T_EXIT_FAIL;
- }
+ if (i & 1)
+ ring_flags |= IORING_SETUP_DEFER_TASKRUN;
- ret = test_invalid_zc(sp);
- if (ret) {
- fprintf(stderr, "test_invalid_zc() failed\n");
- return T_EXIT_FAIL;
- }
+ ret = io_uring_queue_init(32, &ring, ring_flags);
+ if (ret) {
+ if (ret == -EINVAL)
+ continue;
+ fprintf(stderr, "queue init failed: %d\n", ret);
+ return -1;
+ }
- close(sp[0]);
- close(sp[1]);
+ ret = t_register_buffers(&ring, buffers_iov, ARRAY_SIZE(buffers_iov));
+ if (ret == T_SETUP_SKIP) {
+ fprintf(stderr, "can't register bufs, skip\n");
+ goto out;
+ } else if (ret != T_SETUP_OK) {
+ fprintf(stderr, "buffer registration failed %i\n", ret);
+ return T_EXIT_FAIL;
+ }
- ret = test_async_addr(&ring);
- if (ret) {
- fprintf(stderr, "test_async_addr() failed\n");
- return T_EXIT_FAIL;
- }
+ if (buffers_iov[BUF_T_HUGETLB].iov_base) {
+ buffers_iov[BUF_T_HUGETLB].iov_base += 13;
+ buffers_iov[BUF_T_HUGETLB].iov_len -= 26;
+ }
+ if (buffers_iov[BUF_T_LARGE].iov_base) {
+ buffers_iov[BUF_T_LARGE].iov_base += 13;
+ buffers_iov[BUF_T_LARGE].iov_len -= 26;
+ }
- ret = t_register_buffers(&ring, buffers_iov, ARRAY_SIZE(buffers_iov));
- if (ret == T_SETUP_SKIP) {
- fprintf(stderr, "can't register bufs, skip\n");
- goto out;
- } else if (ret != T_SETUP_OK) {
- fprintf(stderr, "buffer registration failed %i\n", ret);
- return T_EXIT_FAIL;
- }
+ ret = test_inet_send(&ring);
+ if (ret) {
+ fprintf(stderr, "test_inet_send() failed (defer_taskrun %i)\n",
+ ring_flags & IORING_SETUP_DEFER_TASKRUN);
+ return T_EXIT_FAIL;
+ }
- if (buffers_iov[BUF_T_HUGETLB].iov_base) {
- buffers_iov[BUF_T_HUGETLB].iov_base += 13;
- buffers_iov[BUF_T_HUGETLB].iov_len -= 26;
- }
- if (buffers_iov[BUF_T_LARGE].iov_base) {
- buffers_iov[BUF_T_LARGE].iov_base += 13;
- buffers_iov[BUF_T_LARGE].iov_len -= 26;
+ if (buffers_iov[BUF_T_HUGETLB].iov_base) {
+ buffers_iov[BUF_T_HUGETLB].iov_base -= 13;
+ buffers_iov[BUF_T_HUGETLB].iov_len += 26;
+ }
+ if (buffers_iov[BUF_T_LARGE].iov_base) {
+ buffers_iov[BUF_T_LARGE].iov_base -= 13;
+ buffers_iov[BUF_T_LARGE].iov_len += 26;
+ }
+out:
+ io_uring_queue_exit(&ring);
}
- ret = test_inet_send(&ring);
- if (ret) {
- fprintf(stderr, "test_inet_send() failed\n");
- return T_EXIT_FAIL;
- }
-out:
- io_uring_queue_exit(&ring);
- close(sp[0]);
- close(sp[1]);
return T_EXIT_PASS;
}
--
2.44.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH liburing 3/3] io_uring/sendzc: add DEFER_TASKRUN testing
2024-04-08 14:24 ` [PATCH liburing 3/3] io_uring/sendzc: add DEFER_TASKRUN testing Pavel Begunkov
@ 2024-04-08 15:23 ` Pavel Begunkov
0 siblings, 0 replies; 5+ messages in thread
From: Pavel Begunkov @ 2024-04-08 15:23 UTC (permalink / raw)
To: io-uring; +Cc: Jens Axboe
On 4/8/24 15:24, Pavel Begunkov wrote:
> Signed-off-by: Pavel Begunkov <[email protected]>
> ---
> test/send-zerocopy.c | 166 +++++++++++++++++++++++++++----------------
> 1 file changed, 106 insertions(+), 60 deletions(-)
>
> diff --git a/test/send-zerocopy.c b/test/send-zerocopy.c
> index bfb15d2..4699cf6 100644
> --- a/test/send-zerocopy.c
> +++ b/test/send-zerocopy.c
> @@ -769,12 +769,69 @@ static int test_invalid_zc(int fds[2])
> return 0;
> }
>
> -int main(int argc, char *argv[])
> +static int run_basic_tests(void)
> {
> struct sockaddr_storage addr;
> - struct io_uring ring;
> - int i, ret, sp[2];
> + int ret, i, sp[2];
> +
> + /* create TCP IPv6 pair */
> + ret = create_socketpair_ip(&addr, &sp[0], &sp[1], true, true, false, true);
> + if (ret) {
> + fprintf(stderr, "sock prep failed %d\n", ret);
> + return -1;
> + }
> +
> + for (i = 0; i < 2; i++) {
> + struct io_uring ring;
> + unsigned ring_flags = 0;
> +
> + if (i & 1)
> + ring_flags |= IORING_SETUP_DEFER_TASKRUN;
That's not right, it's missing SINGLE_ISSUER and then skips the
test. I'll resend
--
Pavel Begunkov
^ permalink raw reply [flat|nested] 5+ messages in thread