Re: [PATCH net-next v4 5/6] selftests: net: add multithread server support to iou-zcrx
Juanlu Herrero <[email protected]> Tue, 4 Aug 2026 11:27:05 -0500
| Newsgroups | gmane.linux.network |
|---|---|
| Message-ID | <anISNwUQeVl1YNwn@jlhe0197-mac> |
On Tue, Aug 04, 2026 at 12:42:41PM -0600, Paolo Abeni wrote: > > > On 7/30/26 12:18 AM, Juanlu Herrero wrote: > > Run the iou-zcrx server as N worker threads, each owning one receive > > queue with its own io_uring and zero-copy receive (zcrx) ifq, so the > > test can exercise multi-queue zero-copy receive. > > > > The main thread owns the listening socket, accepts connections, and > > dispatches each to the worker owning the queue it landed on by matching > > SO_INCOMING_NAPI_ID against per-queue NAPI IDs. > > > > Assisted-by: Claude:claude-opus-4-8 > > Signed-off-by: Juanlu Herrero <[email protected]> > > --- > > .../testing/selftests/drivers/net/hw/Makefile | 5 +- > > .../selftests/drivers/net/hw/iou-zcrx.c | 290 ++++++++++++++---- > > 2 files changed, 226 insertions(+), 69 deletions(-) > > > > diff --git a/tools/testing/selftests/drivers/net/hw/Makefile b/tools/testing/selftests/drivers/net/hw/Makefile > > index 3cab3b4adbb2e..035581b58bc66 100644 > > --- a/tools/testing/selftests/drivers/net/hw/Makefile > > +++ b/tools/testing/selftests/drivers/net/hw/Makefile > > @@ -13,10 +13,6 @@ else > > $(warning excluding iouring tests, liburing not installed or too old) > > endif > > > > -TEST_GEN_FILES := \ > > - $(COND_GEN_FILES) \ > > -# end of TEST_GEN_FILES > > - > > TEST_PROGS = \ > > csum.py \ > > devlink_port_split.py \ > > @@ -71,6 +67,7 @@ TEST_INCLUDES := \ > > YNL_GEN_FILES := \ > > ncdevmem \ > > toeplitz \ > > + $(COND_GEN_FILES) \ > > # end of YNL_GEN_FILES > > TEST_GEN_FILES += $(YNL_GEN_FILES) > > TEST_GEN_FILES += $(patsubst %.c,%.o,$(wildcard *.bpf.c)) > > diff --git a/tools/testing/selftests/drivers/net/hw/iou-zcrx.c b/tools/testing/selftests/drivers/net/hw/iou-zcrx.c > > index 7bc61f3b70ca6..16259129df46d 100644 > > --- a/tools/testing/selftests/drivers/net/hw/iou-zcrx.c > > +++ b/tools/testing/selftests/drivers/net/hw/iou-zcrx.c > > @@ -27,6 +27,7 @@ > > #include <netinet/tcp.h> > > #include <netinet/udp.h> > > #include <sys/epoll.h> > > +#include <sys/eventfd.h> > > #include <sys/ioctl.h> > > #include <sys/mman.h> > > #include <sys/resource.h> > > @@ -38,6 +39,8 @@ > > #include <sys/wait.h> > > > > #include <liburing.h> > > +#include <ynl.h> > > +#include "netdev-user.h" > > > > #define SKIP_CODE 42 > > > > @@ -91,6 +94,7 @@ static int cfg_num_threads = 1; > > static char *payload; > > > > #define CONNS_PER_THREAD 4 > > +#define MAX_CONNS_PER_THREAD 64 > > > > struct thread_ctx { > > struct io_uring ring; > > @@ -99,9 +103,14 @@ struct thread_ctx { > > size_t ring_size; > > struct io_uring_zcrx_rq rq_ring; > > unsigned long area_token; > > - int connfd; > > - bool stop; > > - size_t received; > > + int queue_id; > > + int napi_id; > > + int ready_fd; > > + int start_fd; > > + > > + int connfds[MAX_CONNS_PER_THREAD]; > > + size_t received[MAX_CONNS_PER_THREAD]; > > + int nr_conns; > > }; > > > > static unsigned long gettimeofday_ms(void) > > @@ -201,7 +210,7 @@ static void setup_zcrx(struct thread_ctx *ctx) > > > > struct t_io_uring_zcrx_ifq_reg reg = { > > .if_idx = ifindex, > > - .if_rxq = cfg_queue_id, > > + .if_rxq = ctx->queue_id, > > .rq_entries = rq_entries, > > .area_ptr = (__u64)(unsigned long)&area_reg, > > .region_ptr = (__u64)(unsigned long)®ion_reg, > > @@ -226,53 +235,32 @@ static void setup_zcrx(struct thread_ctx *ctx) > > ctx->area_token = area_reg.rq_area_token; > > } > > > > -static void add_accept(struct thread_ctx *ctx, int sockfd) > > +static void add_recvzc(struct thread_ctx *ctx, int conn_idx) > > { > > struct io_uring_sqe *sqe; > > > > sqe = io_uring_get_sqe(&ctx->ring); > > > > - io_uring_prep_accept(sqe, sockfd, NULL, NULL, 0); > > - sqe->user_data = 1; > > -} > > - > > -static void add_recvzc(struct thread_ctx *ctx, int sockfd) > > -{ > > - struct io_uring_sqe *sqe; > > - > > - sqe = io_uring_get_sqe(&ctx->ring); > > - > > - io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, sockfd, NULL, 0, 0); > > + io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, ctx->connfds[conn_idx], > > + NULL, 0, 0); > > sqe->ioprio |= IORING_RECV_MULTISHOT; > > - sqe->user_data = 2; > > + sqe->user_data = conn_idx; > > } > > > > -static void add_recvzc_oneshot(struct thread_ctx *ctx, int sockfd, size_t len) > > +static void add_recvzc_oneshot(struct thread_ctx *ctx, int conn_idx, size_t len) > > { > > struct io_uring_sqe *sqe; > > > > sqe = io_uring_get_sqe(&ctx->ring); > > > > - io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, sockfd, NULL, len, 0); > > + io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, ctx->connfds[conn_idx], > > + NULL, len, 0); > > sqe->ioprio |= IORING_RECV_MULTISHOT; > > - sqe->user_data = 2; > > + sqe->user_data = conn_idx; > > } > > > > -static void process_accept(struct thread_ctx *ctx, struct io_uring_cqe *cqe) > > -{ > > - if (cqe->res < 0) > > - error(1, 0, "accept()"); > > - if (ctx->connfd) > > - error(1, 0, "Unexpected second connection"); > > - > > - ctx->connfd = cqe->res; > > - if (cfg_oneshot) > > - add_recvzc_oneshot(ctx, ctx->connfd, page_size); > > - else > > - add_recvzc(ctx, ctx->connfd); > > -} > > - > > -static void process_recvzc(struct thread_ctx *ctx, struct io_uring_cqe *cqe) > > +static void process_recvzc(struct thread_ctx *ctx, struct io_uring_cqe *cqe, > > + int conn_idx) > > { > > unsigned int rq_mask = ctx->rq_ring.ring_entries - 1; > > struct io_uring_zcrx_cqe *rcqe; > > @@ -283,7 +271,7 @@ static void process_recvzc(struct thread_ctx *ctx, struct io_uring_cqe *cqe) > > int i; > > > > if (cqe->res == 0 && cqe->flags == 0 && cfg_oneshot_recvs == 0) { > > - ctx->stop = true; > > + ctx->nr_conns--; > > return; > > } > > > > @@ -292,11 +280,11 @@ static void process_recvzc(struct thread_ctx *ctx, struct io_uring_cqe *cqe) > > > > if (cfg_oneshot) { > > if (cqe->res == 0 && cqe->flags == 0 && cfg_oneshot_recvs) { > > - add_recvzc_oneshot(ctx, ctx->connfd, page_size); > > + add_recvzc_oneshot(ctx, conn_idx, page_size); > > cfg_oneshot_recvs--; > > Sashiko noted that the above update is now racy in multithread tests: > > https://sashiko.dev/#/patchset/20260729221825.42773-1-juanlu%40fastmail.com > > Also please respect the reverse christmas tree order consistently. > > /P > I will look into the potential race and fix the reverse christmas tree ordering in v5. Thanks for the review Best, Juanlu