From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A15423016F5; Fri, 14 Aug 2026 01:23:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.145 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786670640; cv=none; b=mJY5lIoOdBpJSHOr9Cb+21X7rgjGgs9cIif+O1n7TP8gUSVzjF1fFzhbzLEIyGMoNkkUL8EHD7MVRtx7dLZj1F7zATE4e59ivX06k9R+EnVphBtImdAVOGeqBD909QNSAV/5IZdp67Z/q+2Ms65GCfifyI5PNIEuqmd9jFSRkoc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786670640; c=relaxed/simple; bh=ZWPFvoRyrvnJsflPTlk63Xy5ZT27x7jwQlCWWZ/pct0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KoVtihGeCt52gFja5V9xWReQP4Oe0c9/50k/2FCMU6nCDz9LpfHvsv423u1sufs9zVxMPdNRtzpSOJtmqDExaaZCADoMnvC3GFue/++GmtxqOOpOSnntsb7iSVPqLY3my7dtgdow0rxZyieltsEesi2D154naNTBRd6e8mJM3tg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fastmail.com; spf=pass smtp.mailfrom=fastmail.com; dkim=pass (2048-bit key) header.d=fastmail.com header.i=@fastmail.com header.b=Ah95oiG9; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=VYhk31xM; arc=none smtp.client-ip=202.12.124.145 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fastmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fastmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fastmail.com header.i=@fastmail.com header.b="Ah95oiG9"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="VYhk31xM" Received: from phl-compute-05.internal (phl-compute-05.internal [10.202.2.45]) by mailfout.stl.internal (Postfix) with ESMTP id B0AB01D00367; Thu, 13 Aug 2026 21:23:57 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-05.internal (MEProxy); Thu, 13 Aug 2026 21:23:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fastmail.com; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm3; t=1786670637; x= 1786757037; bh=Pkr0bWo5PyfxNbPe7FMXAwo56pMSREqoXVUV6Z5Ur04=; b=A h95oiG9Gn3BJthqnsl4nNyThJjhvjxjzErnr2N6MRXMo+HJ6so+YQN/gC58FtfZA 4BgVvSpdNm7LWXsf+SCV/JKAukZhzt746d3dadGiMr8cFQ3+kShU0jjNkWrcEXGD yzcOpg/eBmKMT+G0MQL275NDLREKsD4Y3CWM6uYBtd1FSAWyqPoeUaCDy+agfrdf 7nsZv9qfmCon1Rhbd5SvyeHHbAuW40MX8SMa6AbmkAFFxVl4cIBE/iRTxSXL0cAI 63ZI5MS5hbAJA1N/HnT7sV7c5lLiOOG/9xF3ZvnlbjNQ2sf+4x6T8yMOHXAgm6ws IukMMScFs+fJLIALKxk/A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786670637; x=1786757037; bh=P kr0bWo5PyfxNbPe7FMXAwo56pMSREqoXVUV6Z5Ur04=; b=VYhk31xMTTPvfLuWY VX9mU3Tq1FuYj1u+EU49TzyCG6yiHOUwfyFvwE9GzKY3m4vo4SzORRp1oAS/06Es VY8agWPd1qzeG1/pl2KvTAHXf1A0zMVUfvC07lV3rxQ2LJYBd+/pi8QWunP5I2/7 sYQnYn6sSn81B4TuRKqngf9A6OfnttbLvALmGos4m0P7htlz/8dCBRVLp/f2eOSe hjWTcStPLn54Hf2qWeXV3jqQTQd0xqCh7+ImBh7s/u0/liZ0JJm3CBgHhKsVsL3L lP1RiNSa41x0mWb9E/HWqlVgBAz6IGeFa7paC4R5VH44YdIbOJ3MCDPspqOOgDxY eilBA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTGlnKkc0TwPTb5JNCkAi+5Y8WSjcjjDWnkOIL2wNpUcV13CZto/qOXRm0nqGz7tPy KJEebetoFzGPCWAi43zBJPWh3lU6UkLAyBFZ6j4oxxM9R/f/XZ4XCVK2pzL/y7LQGFZvpR D/CrmLT9KZ1KsmxXyRJ2t1g6Nt6RO09HBhWhLe5eSw/EkIsnwI9+bk4+c3v7X8vnF67GAZ x5aPFmOtLpYkgdaSPCL5jXIqRgeyslKNbDZfP9OeqYyBjk5QInrgyNovvVM3MvStCRC0Vf KMYutq9dcLsVOl/YKHQj65USZyVlLayx+Z5CvgQ+ECO90Jd7U6/TgSqqZrFbLu3cB39nEC sxNJIkpMmke0wuhYG449bOnAHW1ebJYWYF8rkL8Vsjax/mVaMiep7yNNA2YgYebxAmkbaq mHK0pzOVAzUxT3Y4mzta+ePdg209vpfgZvGofUvfo8wEVizcj269cPNRE4eQSEd8bupFtP 7ESmDFervYeFFStHCpdUaMcfi/Q1q3osPefsTvS3Kh8uvHjQvwFxTB3GX7wXSB5n7CHYvQ kh/ElGM1FQjNsZ2nQCoNfKl6XOzk0hZTSsUyUwkn299M/jpJiR5piJTR9tiO0viBKg0gIy 87r2UcUpNjvU8Q65uwpMTiaeDkHrg4wxMhks8LlmczAFbdmn54RwaMUoIjOA X-ME-Proxy: Feedback-ID: i80b64ba7:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 13 Aug 2026 21:23:56 -0400 (EDT) From: Juanlu Herrero To: netdev@vger.kernel.org, dw@davidwei.uk Cc: io-uring@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, kuba@kernel.org, asml.silence@gmail.com, pabeni@redhat.com, shuah@kernel.org, Juanlu Herrero Subject: [PATCH net-next v5 3/6] selftests: net: refactor server state into struct thread_ctx Date: Thu, 13 Aug 2026 20:23:45 -0500 Message-ID: <20260814012348.46958-4-juanlu@fastmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260814012348.46958-1-juanlu@fastmail.com> References: <20260814012348.46958-1-juanlu@fastmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Move server-side state (io_uring ring, zcrx area, refill ring, receive tracking) from global variables into a local struct thread_ctx. This is a pure refactor with no behavior change: run_server still allocates a single context on the stack and runs single-threaded, using io_uring accept and recvzc as before. This prepares the ground for the multithread server support in the following commits, which spawns N worker threads each with their own struct thread_ctx. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Juanlu Herrero --- .../selftests/drivers/net/hw/iou-zcrx.c | 156 +++++++++--------- 1 file changed, 80 insertions(+), 76 deletions(-) diff --git a/tools/testing/selftests/drivers/net/hw/iou-zcrx.c b/tools/testing/selftests/drivers/net/hw/iou-zcrx.c index c6dbd0ad53681..9b62fd0703e61 100644 --- a/tools/testing/selftests/drivers/net/hw/iou-zcrx.c +++ b/tools/testing/selftests/drivers/net/hw/iou-zcrx.c @@ -87,14 +87,18 @@ static unsigned int cfg_rx_buf_len; static bool cfg_dry_run; static char *payload; -static void *area_ptr; -static void *ring_ptr; -static size_t ring_size; -static struct io_uring_zcrx_rq rq_ring; -static unsigned long area_token; -static int connfd; -static bool stop; -static size_t received; + +struct thread_ctx { + struct io_uring ring; + void *area_ptr; + void *ring_ptr; + size_t ring_size; + struct io_uring_zcrx_rq rq_ring; + unsigned long area_token; + int connfd; + bool stop; + size_t received; +}; static unsigned long gettimeofday_ms(void) { @@ -138,7 +142,7 @@ static inline size_t get_refill_ring_size(unsigned int rq_entries) return ALIGN_UP(size, page_size); } -static void setup_zcrx(struct io_uring *ring) +static void setup_zcrx(struct thread_ctx *ctx) { unsigned int ifindex; unsigned int rq_entries = 4096; @@ -149,44 +153,44 @@ static void setup_zcrx(struct io_uring *ring) error(1, 0, "bad interface name: %s", cfg_ifname); if (cfg_rx_buf_len && cfg_rx_buf_len != page_size) { - area_ptr = mmap(NULL, - AREA_SIZE, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE | - MAP_HUGETLB | MAP_HUGE_2MB, - -1, - 0); - if (area_ptr == MAP_FAILED) { + ctx->area_ptr = mmap(NULL, + AREA_SIZE, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | MAP_HUGE_2MB, + -1, + 0); + if (ctx->area_ptr == MAP_FAILED) { printf("Can't allocate huge pages\n"); exit(SKIP_CODE); } } else { - area_ptr = mmap(NULL, - AREA_SIZE, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, - 0, - 0); - if (area_ptr == MAP_FAILED) + ctx->area_ptr = mmap(NULL, + AREA_SIZE, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, + 0, + 0); + if (ctx->area_ptr == MAP_FAILED) 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); + ctx->ring_size = get_refill_ring_size(rq_entries); + ctx->ring_ptr = mmap(NULL, + ctx->ring_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, + 0, + 0); struct io_uring_region_desc region_reg = { - .size = ring_size, - .user_addr = (__u64)(unsigned long)ring_ptr, + .size = ctx->ring_size, + .user_addr = (__u64)(unsigned long)ctx->ring_ptr, .flags = IORING_MEM_REGION_TYPE_USER, }; struct io_uring_zcrx_area_reg area_reg = { - .addr = (__u64)(unsigned long)area_ptr, + .addr = (__u64)(unsigned long)ctx->area_ptr, .len = AREA_SIZE, .flags = 0, }; @@ -200,7 +204,7 @@ static void setup_zcrx(struct io_uring *ring) .rx_buf_len = cfg_rx_buf_len, }; - ret = io_uring_register_ifq(ring, (void *)®); + ret = io_uring_register_ifq(&ctx->ring, (void *)®); if (cfg_rx_buf_len && (ret == -EINVAL || ret == -EOPNOTSUPP || ret == -ERANGE)) { printf("Large chunks are not supported %i\n", ret); @@ -209,64 +213,64 @@ static void setup_zcrx(struct io_uring *ring) error(1, 0, "io_uring_register_ifq(): %d", ret); } - 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); - rq_ring.rq_tail = 0; - rq_ring.ring_entries = reg.rq_entries; + ctx->rq_ring.khead = (unsigned int *)((char *)ctx->ring_ptr + reg.offsets.head); + ctx->rq_ring.ktail = (unsigned int *)((char *)ctx->ring_ptr + reg.offsets.tail); + ctx->rq_ring.rqes = (struct io_uring_zcrx_rqe *)((char *)ctx->ring_ptr + reg.offsets.rqes); + ctx->rq_ring.rq_tail = 0; + ctx->rq_ring.ring_entries = reg.rq_entries; - area_token = area_reg.rq_area_token; + ctx->area_token = area_reg.rq_area_token; } -static void add_accept(struct io_uring *ring, int sockfd) +static void add_accept(struct thread_ctx *ctx, int sockfd) { struct io_uring_sqe *sqe; - sqe = io_uring_get_sqe(ring); + 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 io_uring *ring, int sockfd) +static void add_recvzc(struct thread_ctx *ctx, int sockfd) { struct io_uring_sqe *sqe; - sqe = io_uring_get_sqe(ring); + sqe = io_uring_get_sqe(&ctx->ring); io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, sockfd, NULL, 0, 0); sqe->ioprio |= IORING_RECV_MULTISHOT; sqe->user_data = 2; } -static void add_recvzc_oneshot(struct io_uring *ring, int sockfd, size_t len) +static void add_recvzc_oneshot(struct thread_ctx *ctx, int sockfd, size_t len) { struct io_uring_sqe *sqe; - sqe = io_uring_get_sqe(ring); + sqe = io_uring_get_sqe(&ctx->ring); io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, sockfd, NULL, len, 0); sqe->ioprio |= IORING_RECV_MULTISHOT; sqe->user_data = 2; } -static void process_accept(struct io_uring *ring, struct io_uring_cqe *cqe) +static void process_accept(struct thread_ctx *ctx, struct io_uring_cqe *cqe) { if (cqe->res < 0) error(1, 0, "accept()"); - if (connfd) + if (ctx->connfd) error(1, 0, "Unexpected second connection"); - connfd = cqe->res; + ctx->connfd = cqe->res; if (cfg_oneshot) - add_recvzc_oneshot(ring, connfd, page_size); + add_recvzc_oneshot(ctx, ctx->connfd, page_size); else - add_recvzc(ring, connfd); + add_recvzc(ctx, ctx->connfd); } -static void process_recvzc(struct io_uring *ring, struct io_uring_cqe *cqe) +static void process_recvzc(struct thread_ctx *ctx, struct io_uring_cqe *cqe) { - unsigned rq_mask = rq_ring.ring_entries - 1; + unsigned int rq_mask = ctx->rq_ring.ring_entries - 1; struct io_uring_zcrx_cqe *rcqe; struct io_uring_zcrx_rqe *rqe; uint64_t mask; @@ -275,7 +279,7 @@ static void process_recvzc(struct io_uring *ring, struct io_uring_cqe *cqe) int i; if (cqe->res == 0 && cqe->flags == 0 && cfg_oneshot_recvs == 0) { - stop = true; + ctx->stop = true; return; } @@ -284,56 +288,56 @@ static void process_recvzc(struct io_uring *ring, struct io_uring_cqe *cqe) if (cfg_oneshot) { if (cqe->res == 0 && cqe->flags == 0 && cfg_oneshot_recvs) { - add_recvzc_oneshot(ring, connfd, page_size); + add_recvzc_oneshot(ctx, ctx->connfd, page_size); cfg_oneshot_recvs--; } } else if (!(cqe->flags & IORING_CQE_F_MORE)) { - add_recvzc(ring, connfd); + add_recvzc(ctx, ctx->connfd); } rcqe = (struct io_uring_zcrx_cqe *)(cqe + 1); n = cqe->res; mask = (1ULL << IORING_ZCRX_AREA_SHIFT) - 1; - data = (char *)area_ptr + (rcqe->off & mask); + data = (char *)ctx->area_ptr + (rcqe->off & mask); for (i = 0; i < n; i++) { - if (*(data + i) != payload[(received + i)]) + if (*(data + i) != payload[(ctx->received + i)]) error(1, 0, "payload mismatch at %d", i); } - received += n; + ctx->received += n; - rqe = &rq_ring.rqes[(rq_ring.rq_tail & rq_mask)]; - rqe->off = (rcqe->off & ~IORING_ZCRX_AREA_MASK) | area_token; + rqe = &ctx->rq_ring.rqes[(ctx->rq_ring.rq_tail & rq_mask)]; + rqe->off = (rcqe->off & ~IORING_ZCRX_AREA_MASK) | ctx->area_token; rqe->len = cqe->res; - io_uring_smp_store_release(rq_ring.ktail, ++rq_ring.rq_tail); + io_uring_smp_store_release(ctx->rq_ring.ktail, ++ctx->rq_ring.rq_tail); } -static void server_loop(struct io_uring *ring) +static void server_loop(struct thread_ctx *ctx) { struct io_uring_cqe *cqe; unsigned int count = 0; unsigned int head; int i, ret; - io_uring_submit_and_wait(ring, 1); + io_uring_submit_and_wait(&ctx->ring, 1); - io_uring_for_each_cqe(ring, head, cqe) { + io_uring_for_each_cqe(&ctx->ring, head, cqe) { if (cqe->user_data == 1) - process_accept(ring, cqe); + process_accept(ctx, cqe); else if (cqe->user_data == 2) - process_recvzc(ring, cqe); + process_recvzc(ctx, cqe); else error(1, 0, "unknown cqe"); count++; } - io_uring_cq_advance(ring, count); + io_uring_cq_advance(&ctx->ring, count); } static void run_server(void) { + struct thread_ctx ctx = {}; unsigned int flags = 0; - struct io_uring ring; int fd, enable, ret; uint64_t tstop; @@ -356,22 +360,22 @@ static void run_server(void) flags |= IORING_SETUP_SUBMIT_ALL; flags |= IORING_SETUP_CQE32; - io_uring_queue_init(512, &ring, flags); + io_uring_queue_init(512, &ctx.ring, flags); - setup_zcrx(&ring); + setup_zcrx(&ctx); if (cfg_dry_run) return; if (listen(fd, 1024) < 0) error(1, 0, "listen()"); - add_accept(&ring, fd); + add_accept(&ctx, fd); tstop = gettimeofday_ms() + 5000; - while (!stop && gettimeofday_ms() < tstop) - server_loop(&ring); + while (!ctx.stop && gettimeofday_ms() < tstop) + server_loop(&ctx); - if (!stop) + if (!ctx.stop) error(1, 0, "test failed\n"); } -- 2.53.0-Meta