Re: [net-next,v6,5/6] selftests: net: add multithread server support to iou-zcrx
From: Juanlu Herrero <hidden>
Date: 2026-09-09 18:47:24
Also in:
io-uring, linux-kselftest, lkml
On Wed, Sep 09, 2026 at 09:16:58AM -0600, Bobby Eshleman wrote:
On Wed, Sep 02, 2026 at 11:38:17PM +0000, netdev-bot+sashiko@kernel.org wrote:quoted
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:[...]quoted
quoted
@@ -356,29 +444,68 @@ static void run_server(void) if (ret < 0) error(1, 0, "bind()"); - flags |= IORING_SETUP_COOP_TASKRUN; - flags |= IORING_SETUP_SINGLE_ISSUER; - flags |= IORING_SETUP_DEFER_TASKRUN; - flags |= IORING_SETUP_SUBMIT_ALL; - flags |= IORING_SETUP_CQE32; + pthread_barrier_init(&setup_done, NULL, cfg_num_threads + 1); + pthread_barrier_init(&dispatch_done, NULL, cfg_num_threads + 1); + + for (i = 0; i < cfg_num_threads; i++) { + ctxs[i].queue_id = cfg_queue_id + i; + ctxs[i].setup_done = &setup_done; + ctxs[i].dispatch_done = &dispatch_done; + } - io_uring_queue_init(512, &ctx.ring, flags); + for (i = 0; i < cfg_num_threads; i++) { + ret = pthread_create(&threads[i], NULL, + server_worker, &ctxs[i]); + if (ret) + error(1, ret, "pthread_create()"); + } - setup_zcrx(&ctx); if (cfg_dry_run) - return; + goto join; if (listen(fd, 1024) < 0) error(1, 0, "listen()"); - add_accept(&ctx, fd); + pthread_barrier_wait(&setup_done);[Severity: High] Is the listen() intentionally moved before the workers have registered their ifqs? The main thread creates the threads, calls listen(), and only then waits on setup_done, while the workers reach that barrier after io_uring_queue_init_params() plus setup_zcrx(), i.e. after io_uring_register_ifq() has restarted the device RX queue. Before the patch the sequence was serialized in one thread: io_uring_queue_init(512, &ctx.ring, flags); setup_zcrx(&ctx); ... listen(fd, 1024); so the port only became visible once the memory provider was installed. Two existing tests depend on that ordering. wait_port_listen() in net/lib/py/utils.py polls every 5 ms, so it can now return while registration is still in flight: iou-zcrx.py:test_zcrx_large_chunks() { wait_port_listen(cfg.port, proto="tcp") check_iou_rx_buf_len(cfg, rx_buf_len) } check_iou_rx_buf_len() raises "Expected 1 io-uring page pool, found 0", and nk_qlease.py:test_destroy() does queue_get() plus ksft_in("io-uring", queue_info) immediately after wait_port_listen() with no sleep. Beyond the harness races, data delivered into the queue before the provider exists is serviced by the copy fallback rather than zero copy, and the queue restart during registration can drop in-flight frames. Would moving listen() below pthread_barrier_wait(&setup_done) restore the previous guarantee?Just a heads up that I tested this on BRCM and did find this listen() ordering issue to cause genuine (but flaky) regression for nk_qlease.test_destroy. Moving the listen() to after wait(setup_done) indeed fixed it. Best, Bobby
thanks for testing on BRCM and I will do the same as a venue to validate any fix I do for the listen() ordering issue in v7!