io-uring.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH liburing 0/3] improve sendzc tests
@ 2024-04-08 14:24 Pavel Begunkov
  2024-04-08 14:24 ` [PATCH liburing 1/3] test: handle test_send_faults()'s cases one by one Pavel Begunkov
                   ` (2 more replies)
  0 siblings, 3 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 is enough of special handling for DEFER_TASKRUN, so we want
to test sendzc with DEFER_TASKRUN as well. Apart from that, probe
zc support at the beginning and do some more cleanups.

Pavel Begunkov (3):
  test: handle test_send_faults()'s cases one by one
  test/sendzc: improve zc support probing
  io_uring/sendzc: add DEFER_TASKRUN testing

 test/send-zerocopy.c | 331 ++++++++++++++++++++++++++++---------------
 1 file changed, 215 insertions(+), 116 deletions(-)

-- 
2.44.0


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

* [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 <asml.silence@gmail.com>
---
 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 <asml.silence@gmail.com>
---
 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 <asml.silence@gmail.com>
---
 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 <asml.silence@gmail.com>
> ---
>   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

end of thread, other threads:[~2024-04-08 15:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH liburing 3/3] io_uring/sendzc: add DEFER_TASKRUN testing Pavel Begunkov
2024-04-08 15:23   ` Pavel Begunkov

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).