public inbox for io-uring@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH liburing 0/3] zcrx refill queue allocation modes
@ 2025-04-20 11:24 Pavel Begunkov
  2025-04-20 11:24 ` [PATCH liburing 1/3] examples: remove zcrx size limiting Pavel Begunkov
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Pavel Begunkov @ 2025-04-20 11:24 UTC (permalink / raw)
  To: io-uring; +Cc: asml.silence, David Wei

Random patches for zcrx. Path 1 removes oneshot mode as it doesn't
give a good example, and Patch 3 allows to kernel allocations for
the refill queue.

Pavel Begunkov (3):
  examples: remove zcrx size limiting
  examples/zcrx: constants for request types
  examples/zcrx: add refill queue allocation modes

 examples/zcrx.c | 100 +++++++++++++++++++++++++++---------------------
 1 file changed, 56 insertions(+), 44 deletions(-)

-- 
2.48.1


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

* [PATCH liburing 1/3] examples: remove zcrx size limiting
  2025-04-20 11:24 [PATCH liburing 0/3] zcrx refill queue allocation modes Pavel Begunkov
@ 2025-04-20 11:24 ` Pavel Begunkov
  2025-04-21  0:22   ` David Wei
  2025-04-20 11:24 ` [PATCH liburing 2/3] examples/zcrx: constants for request types Pavel Begunkov
  2025-04-20 11:24 ` [PATCH liburing 3/3] examples/zcrx: add refill queue allocation modes Pavel Begunkov
  2 siblings, 1 reply; 10+ messages in thread
From: Pavel Begunkov @ 2025-04-20 11:24 UTC (permalink / raw)
  To: io-uring; +Cc: asml.silence, David Wei

It's not handled too well and is not great at show casing the feature,
remove it for now, we may add it back later in a different form.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 examples/zcrx.c | 34 ++++------------------------------
 1 file changed, 4 insertions(+), 30 deletions(-)

diff --git a/examples/zcrx.c b/examples/zcrx.c
index 32d9e4ae..afc05642 100644
--- a/examples/zcrx.c
+++ b/examples/zcrx.c
@@ -46,8 +46,6 @@ static long page_size;
 static int cfg_port = 8000;
 static const char *cfg_ifname;
 static int cfg_queue_id = -1;
-static bool cfg_oneshot;
-static int cfg_oneshot_recvs;
 static bool cfg_verify_data = false;
 static struct sockaddr_in6 cfg_addr;
 
@@ -150,16 +148,6 @@ static void add_recvzc(struct io_uring *ring, int sockfd)
 	sqe->user_data = 2;
 }
 
-static void add_recvzc_oneshot(struct io_uring *ring, int sockfd, size_t len)
-{
-	struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
-
-	io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, sockfd, NULL, len, 0);
-	sqe->ioprio |= IORING_RECV_MULTISHOT;
-	sqe->zcrx_ifq_idx = zcrx_id;
-	sqe->user_data = 2;
-}
-
 static void process_accept(struct io_uring *ring, struct io_uring_cqe *cqe)
 {
 	if (cqe->res < 0)
@@ -168,10 +156,7 @@ static void process_accept(struct io_uring *ring, struct io_uring_cqe *cqe)
 		t_error(1, 0, "Unexpected second connection");
 
 	connfd = cqe->res;
-	if (cfg_oneshot)
-		add_recvzc_oneshot(ring, connfd, page_size);
-	else
-		add_recvzc(ring, connfd);
+	add_recvzc(ring, connfd);
 }
 
 static void verify_data(char *data, size_t size, unsigned long seq)
@@ -200,19 +185,13 @@ static void process_recvzc(struct io_uring *ring, struct io_uring_cqe *cqe)
 	if (cqe->res < 0)
 		t_error(1, 0, "recvzc(): %d", cqe->res);
 
-	if (cqe->res == 0 && cqe->flags == 0 && cfg_oneshot_recvs == 0) {
+	if (cqe->res == 0 && cqe->flags == 0) {
 		stop = true;
 		return;
 	}
 
-	if (cfg_oneshot) {
-		if (cqe->res == 0 && cqe->flags == 0 && cfg_oneshot_recvs) {
-			add_recvzc_oneshot(ring, connfd, page_size);
-			cfg_oneshot_recvs--;
-		}
-	} else if (!(cqe->flags & IORING_CQE_F_MORE)) {
+	if (!(cqe->flags & IORING_CQE_F_MORE))
 		add_recvzc(ring, connfd);
-	}
 
 	rcqe = (struct io_uring_zcrx_cqe *)(cqe + 1);
 	mask = (1ULL << IORING_ZCRX_AREA_SHIFT) - 1;
@@ -299,7 +278,7 @@ static void parse_opts(int argc, char **argv)
 	if (argc <= 1)
 		usage(argv[0]);
 
-	while ((c = getopt(argc, argv, "vp:i:q:o:")) != -1) {
+	while ((c = getopt(argc, argv, "vp:i:q:")) != -1) {
 		switch (c) {
 		case 'p':
 			cfg_port = strtoul(optarg, NULL, 0);
@@ -307,11 +286,6 @@ static void parse_opts(int argc, char **argv)
 		case 'i':
 			cfg_ifname = optarg;
 			break;
-		case 'o': {
-			cfg_oneshot = true;
-			cfg_oneshot_recvs = strtoul(optarg, NULL, 0);
-			break;
-		}
 		case 'q':
 			cfg_queue_id = strtoul(optarg, NULL, 0);
 			break;
-- 
2.48.1


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

* [PATCH liburing 2/3] examples/zcrx: constants for request types
  2025-04-20 11:24 [PATCH liburing 0/3] zcrx refill queue allocation modes Pavel Begunkov
  2025-04-20 11:24 ` [PATCH liburing 1/3] examples: remove zcrx size limiting Pavel Begunkov
@ 2025-04-20 11:24 ` Pavel Begunkov
  2025-04-21  0:25   ` David Wei
  2025-04-20 11:24 ` [PATCH liburing 3/3] examples/zcrx: add refill queue allocation modes Pavel Begunkov
  2 siblings, 1 reply; 10+ messages in thread
From: Pavel Begunkov @ 2025-04-20 11:24 UTC (permalink / raw)
  To: io-uring; +Cc: asml.silence, David Wei

Instead of hard coding user_data, name request types we need and use
them.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 examples/zcrx.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/examples/zcrx.c b/examples/zcrx.c
index afc05642..8989c9a4 100644
--- a/examples/zcrx.c
+++ b/examples/zcrx.c
@@ -43,6 +43,14 @@ static long page_size;
 #define AREA_SIZE (8192 * page_size)
 #define SEND_SIZE (512 * 4096)
 
+#define REQ_TYPE_SHIFT	3
+#define REQ_TYPE_MASK	((1UL << REQ_TYPE_SHIFT) - 1)
+
+enum request_type {
+	REQ_TYPE_ACCEPT		= 1,
+	REQ_TYPE_RX		= 2,
+};
+
 static int cfg_port = 8000;
 static const char *cfg_ifname;
 static int cfg_queue_id = -1;
@@ -135,7 +143,7 @@ static void add_accept(struct io_uring *ring, int sockfd)
 	struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
 
 	io_uring_prep_accept(sqe, sockfd, NULL, NULL, 0);
-	sqe->user_data = 1;
+	sqe->user_data = REQ_TYPE_ACCEPT;
 }
 
 static void add_recvzc(struct io_uring *ring, int sockfd)
@@ -145,7 +153,7 @@ static void add_recvzc(struct io_uring *ring, int sockfd)
 	io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, sockfd, NULL, 0, 0);
 	sqe->ioprio |= IORING_RECV_MULTISHOT;
 	sqe->zcrx_ifq_idx = zcrx_id;
-	sqe->user_data = 2;
+	sqe->user_data = REQ_TYPE_RX;
 }
 
 static void process_accept(struct io_uring *ring, struct io_uring_cqe *cqe)
@@ -215,12 +223,16 @@ static void server_loop(struct io_uring *ring)
 	io_uring_submit_and_wait(ring, 1);
 
 	io_uring_for_each_cqe(ring, head, cqe) {
-		if (cqe->user_data == 1)
+		switch (cqe->user_data & REQ_TYPE_MASK) {
+		case REQ_TYPE_ACCEPT:
 			process_accept(ring, cqe);
-		else if (cqe->user_data == 2)
+			break;
+		case REQ_TYPE_RX:
 			process_recvzc(ring, cqe);
-		else
+			break;
+		default:
 			t_error(1, 0, "unknown cqe");
+		}
 		count++;
 	}
 	io_uring_cq_advance(ring, count);
-- 
2.48.1


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

* [PATCH liburing 3/3] examples/zcrx: add refill queue allocation modes
  2025-04-20 11:24 [PATCH liburing 0/3] zcrx refill queue allocation modes Pavel Begunkov
  2025-04-20 11:24 ` [PATCH liburing 1/3] examples: remove zcrx size limiting Pavel Begunkov
  2025-04-20 11:24 ` [PATCH liburing 2/3] examples/zcrx: constants for request types Pavel Begunkov
@ 2025-04-20 11:24 ` Pavel Begunkov
  2025-04-21  0:28   ` David Wei
  2 siblings, 1 reply; 10+ messages in thread
From: Pavel Begunkov @ 2025-04-20 11:24 UTC (permalink / raw)
  To: io-uring; +Cc: asml.silence, David Wei

Refill queue creating is backed by the region api, which can either be
user or kernel allocated. Add an option to switch between the modes.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 examples/zcrx.c | 46 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 10 deletions(-)

diff --git a/examples/zcrx.c b/examples/zcrx.c
index 8989c9a4..eafe1969 100644
--- a/examples/zcrx.c
+++ b/examples/zcrx.c
@@ -39,6 +39,13 @@
 #include "liburing.h"
 #include "helpers.h"
 
+enum {
+	RQ_ALLOC_USER,
+	RQ_ALLOC_KERNEL,
+
+	__RQ_ALLOC_MAX,
+};
+
 static long page_size;
 #define AREA_SIZE (8192 * page_size)
 #define SEND_SIZE (512 * 4096)
@@ -55,6 +62,7 @@ static int cfg_port = 8000;
 static const char *cfg_ifname;
 static int cfg_queue_id = -1;
 static bool cfg_verify_data = false;
+static unsigned cfg_rq_alloc_mode = RQ_ALLOC_USER;
 static struct sockaddr_in6 cfg_addr;
 
 static void *area_ptr;
@@ -79,6 +87,7 @@ static void setup_zcrx(struct io_uring *ring)
 {
 	unsigned int ifindex;
 	unsigned int rq_entries = 4096;
+	unsigned rq_flags = 0;
 	int ret;
 
 	ifindex = if_nametoindex(cfg_ifname);
@@ -95,19 +104,22 @@ static void setup_zcrx(struct io_uring *ring)
 		t_error(1, 0, "mmap(): zero copy area");
 
 	ring_size = get_refill_ring_size(rq_entries);
-	ring_ptr = mmap(NULL,
-			ring_size,
-			PROT_READ | PROT_WRITE,
-			MAP_ANONYMOUS | MAP_PRIVATE,
-			0,
-			0);
-	if (ring_ptr == MAP_FAILED)
-		t_error(1, 0, "mmap(): refill ring");
+
+	ring_ptr = NULL;
+	if (cfg_rq_alloc_mode == RQ_ALLOC_USER) {
+		ring_ptr = mmap(NULL, ring_size,
+				PROT_READ | PROT_WRITE,
+				MAP_ANONYMOUS | MAP_PRIVATE,
+				0, 0);
+		if (ring_ptr == MAP_FAILED)
+			t_error(1, 0, "mmap(): refill ring");
+		rq_flags |= IORING_MEM_REGION_TYPE_USER;
+	}
 
 	struct io_uring_region_desc region_reg = {
 		.size = ring_size,
 		.user_addr = (__u64)(unsigned long)ring_ptr,
-		.flags = IORING_MEM_REGION_TYPE_USER,
+		.flags = rq_flags,
 	};
 
 	struct io_uring_zcrx_area_reg area_reg = {
@@ -128,6 +140,15 @@ static void setup_zcrx(struct io_uring *ring)
 	if (ret)
 		t_error(1, 0, "io_uring_register_ifq(): %d", ret);
 
+	if (cfg_rq_alloc_mode == RQ_ALLOC_USER) {
+		ring_ptr = mmap(NULL, ring_size,
+				PROT_READ | PROT_WRITE,
+				MAP_SHARED | MAP_POPULATE,
+				ring->ring_fd, region_reg.mmap_offset);
+		if (ring_ptr == MAP_FAILED)
+			t_error(1, 0, "mmap(): refill ring");
+	}
+
 	rq_ring.khead = (unsigned int *)((char *)ring_ptr + reg.offsets.head);
 	rq_ring.ktail = (unsigned int *)((char *)ring_ptr + reg.offsets.tail);
 	rq_ring.rqes = (struct io_uring_zcrx_rqe *)((char *)ring_ptr + reg.offsets.rqes);
@@ -290,7 +311,7 @@ static void parse_opts(int argc, char **argv)
 	if (argc <= 1)
 		usage(argv[0]);
 
-	while ((c = getopt(argc, argv, "vp:i:q:")) != -1) {
+	while ((c = getopt(argc, argv, "vp:i:q:a:")) != -1) {
 		switch (c) {
 		case 'p':
 			cfg_port = strtoul(optarg, NULL, 0);
@@ -304,6 +325,11 @@ static void parse_opts(int argc, char **argv)
 		case 'v':
 			cfg_verify_data = true;
 			break;
+		case 'a':
+			cfg_rq_alloc_mode = strtoul(optarg, NULL, 0);
+			if (cfg_rq_alloc_mode >= __RQ_ALLOC_MAX)
+				t_error(1, 0, "invalid RQ allocation mode");
+			break;
 		}
 	}
 
-- 
2.48.1


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

* Re: [PATCH liburing 1/3] examples: remove zcrx size limiting
  2025-04-20 11:24 ` [PATCH liburing 1/3] examples: remove zcrx size limiting Pavel Begunkov
@ 2025-04-21  0:22   ` David Wei
  2025-04-21  6:40     ` Pavel Begunkov
  0 siblings, 1 reply; 10+ messages in thread
From: David Wei @ 2025-04-21  0:22 UTC (permalink / raw)
  To: Pavel Begunkov, io-uring

On 2025-04-20 04:24, Pavel Begunkov wrote:
> It's not handled too well and is not great at show casing the feature,
> remove it for now, we may add it back later in a different form.
> 
> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
> ---
>  examples/zcrx.c | 34 ++++------------------------------
>  1 file changed, 4 insertions(+), 30 deletions(-)
> 

I'm relying on this selftest. Can the deletion wait until the
replacement is ready?

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

* Re: [PATCH liburing 2/3] examples/zcrx: constants for request types
  2025-04-20 11:24 ` [PATCH liburing 2/3] examples/zcrx: constants for request types Pavel Begunkov
@ 2025-04-21  0:25   ` David Wei
  0 siblings, 0 replies; 10+ messages in thread
From: David Wei @ 2025-04-21  0:25 UTC (permalink / raw)
  To: Pavel Begunkov, io-uring

On 2025-04-20 04:24, Pavel Begunkov wrote:
> Instead of hard coding user_data, name request types we need and use
> them.
> 
> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
> ---
>  examples/zcrx.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 

Reviewed-by: David Wei <dw@davidwei.uk>

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

* Re: [PATCH liburing 3/3] examples/zcrx: add refill queue allocation modes
  2025-04-20 11:24 ` [PATCH liburing 3/3] examples/zcrx: add refill queue allocation modes Pavel Begunkov
@ 2025-04-21  0:28   ` David Wei
  2025-04-21  6:38     ` Pavel Begunkov
  0 siblings, 1 reply; 10+ messages in thread
From: David Wei @ 2025-04-21  0:28 UTC (permalink / raw)
  To: Pavel Begunkov, io-uring

On 2025-04-20 04:24, Pavel Begunkov wrote:
> Refill queue creating is backed by the region api, which can either be
> user or kernel allocated. Add an option to switch between the modes.
> 
> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
> ---
>  examples/zcrx.c | 46 ++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 36 insertions(+), 10 deletions(-)
> 
> diff --git a/examples/zcrx.c b/examples/zcrx.c
> index 8989c9a4..eafe1969 100644
> --- a/examples/zcrx.c
> +++ b/examples/zcrx.c
> @@ -39,6 +39,13 @@
[...]
> @@ -128,6 +140,15 @@ static void setup_zcrx(struct io_uring *ring)
>  	if (ret)
>  		t_error(1, 0, "io_uring_register_ifq(): %d", ret);
>  
> +	if (cfg_rq_alloc_mode == RQ_ALLOC_USER) {

cfg_rq_alloc_mode == RQ_ALLOC_KERNEL?

> +		ring_ptr = mmap(NULL, ring_size,
> +				PROT_READ | PROT_WRITE,
> +				MAP_SHARED | MAP_POPULATE,
> +				ring->ring_fd, region_reg.mmap_offset);
> +		if (ring_ptr == MAP_FAILED)
> +			t_error(1, 0, "mmap(): refill ring");
> +	}
> +
>  	rq_ring.khead = (unsigned int *)((char *)ring_ptr + reg.offsets.head);
>  	rq_ring.ktail = (unsigned int *)((char *)ring_ptr + reg.offsets.tail);
>  	rq_ring.rqes = (struct io_uring_zcrx_rqe *)((char *)ring_ptr + reg.offsets.rqes);


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

* Re: [PATCH liburing 3/3] examples/zcrx: add refill queue allocation modes
  2025-04-21  0:28   ` David Wei
@ 2025-04-21  6:38     ` Pavel Begunkov
  0 siblings, 0 replies; 10+ messages in thread
From: Pavel Begunkov @ 2025-04-21  6:38 UTC (permalink / raw)
  To: David Wei, io-uring

On 4/21/25 01:28, David Wei wrote:
> On 2025-04-20 04:24, Pavel Begunkov wrote:
>> Refill queue creating is backed by the region api, which can either be
>> user or kernel allocated. Add an option to switch between the modes.
>>
>> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
>> ---
>>   examples/zcrx.c | 46 ++++++++++++++++++++++++++++++++++++----------
>>   1 file changed, 36 insertions(+), 10 deletions(-)
>>
>> diff --git a/examples/zcrx.c b/examples/zcrx.c
>> index 8989c9a4..eafe1969 100644
>> --- a/examples/zcrx.c
>> +++ b/examples/zcrx.c
>> @@ -39,6 +39,13 @@
> [...]
>> @@ -128,6 +140,15 @@ static void setup_zcrx(struct io_uring *ring)
>>   	if (ret)
>>   		t_error(1, 0, "io_uring_register_ifq(): %d", ret);
>>   
>> +	if (cfg_rq_alloc_mode == RQ_ALLOC_USER) {
> 
> cfg_rq_alloc_mode == RQ_ALLOC_KERNEL?

Good catch! I found it during testing but apparently forgot to
commit.

> 
>> +		ring_ptr = mmap(NULL, ring_size,
>> +				PROT_READ | PROT_WRITE,
>> +				MAP_SHARED | MAP_POPULATE,
>> +				ring->ring_fd, region_reg.mmap_offset);
>> +		if (ring_ptr == MAP_FAILED)
>> +			t_error(1, 0, "mmap(): refill ring");
>> +	}
>> +
>>   	rq_ring.khead = (unsigned int *)((char *)ring_ptr + reg.offsets.head);
>>   	rq_ring.ktail = (unsigned int *)((char *)ring_ptr + reg.offsets.tail);
>>   	rq_ring.rqes = (struct io_uring_zcrx_rqe *)((char *)ring_ptr + reg.offsets.rqes);
> 

-- 
Pavel Begunkov


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

* Re: [PATCH liburing 1/3] examples: remove zcrx size limiting
  2025-04-21  0:22   ` David Wei
@ 2025-04-21  6:40     ` Pavel Begunkov
  2025-04-21 17:38       ` David Wei
  0 siblings, 1 reply; 10+ messages in thread
From: Pavel Begunkov @ 2025-04-21  6:40 UTC (permalink / raw)
  To: David Wei, io-uring

On 4/21/25 01:22, David Wei wrote:
> On 2025-04-20 04:24, Pavel Begunkov wrote:
>> It's not handled too well and is not great at show casing the feature,
>> remove it for now, we may add it back later in a different form.
>>
>> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
>> ---
>>   examples/zcrx.c | 34 ++++------------------------------
>>   1 file changed, 4 insertions(+), 30 deletions(-)
>>
> 
> I'm relying on this selftest. Can the deletion wait until the
> replacement is ready?

I assumed you're using the selftest, and not this liburing/examples/*

Anyway, let's see what I can do with it

-- 
Pavel Begunkov


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

* Re: [PATCH liburing 1/3] examples: remove zcrx size limiting
  2025-04-21  6:40     ` Pavel Begunkov
@ 2025-04-21 17:38       ` David Wei
  0 siblings, 0 replies; 10+ messages in thread
From: David Wei @ 2025-04-21 17:38 UTC (permalink / raw)
  To: Pavel Begunkov, io-uring

On 2025-04-20 23:40, Pavel Begunkov wrote:
> On 4/21/25 01:22, David Wei wrote:
>> On 2025-04-20 04:24, Pavel Begunkov wrote:
>>> It's not handled too well and is not great at show casing the feature,
>>> remove it for now, we may add it back later in a different form.
>>>
>>> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
>>> ---
>>>   examples/zcrx.c | 34 ++++------------------------------
>>>   1 file changed, 4 insertions(+), 30 deletions(-)
>>>
>>
>> I'm relying on this selftest. Can the deletion wait until the
>> replacement is ready?
> 
> I assumed you're using the selftest, and not this liburing/examples/*
> 
> Anyway, let's see what I can do with it
> 

Oh my mistake :facepalm: I got this mixed up with the selfteset.

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

end of thread, other threads:[~2025-04-21 17:38 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-20 11:24 [PATCH liburing 0/3] zcrx refill queue allocation modes Pavel Begunkov
2025-04-20 11:24 ` [PATCH liburing 1/3] examples: remove zcrx size limiting Pavel Begunkov
2025-04-21  0:22   ` David Wei
2025-04-21  6:40     ` Pavel Begunkov
2025-04-21 17:38       ` David Wei
2025-04-20 11:24 ` [PATCH liburing 2/3] examples/zcrx: constants for request types Pavel Begunkov
2025-04-21  0:25   ` David Wei
2025-04-20 11:24 ` [PATCH liburing 3/3] examples/zcrx: add refill queue allocation modes Pavel Begunkov
2025-04-21  0:28   ` David Wei
2025-04-21  6:38     ` Pavel Begunkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox