On 2026-08-13 18:23, Juanlu Herrero wrote:
Add pthreads to the iou-zcrx client so that multiple connections can be
established simultaneously. Each client thread connects to the server
and sends its payload independently.

Introduce the -t option to control the number of threads (default 1),
preserving backwards compatibility with existing tests.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Juanlu Herrero <[email protected]>
---
  .../testing/selftests/drivers/net/hw/Makefile |  2 +-
  .../selftests/drivers/net/hw/iou-zcrx.c       | 35 +++++++++++++++++--
  2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/drivers/net/hw/Makefile 
b/tools/testing/selftests/drivers/net/hw/Makefile
index 78bb0169350b2..37023ba580de7 100644
--- a/tools/testing/selftests/drivers/net/hw/Makefile
+++ b/tools/testing/selftests/drivers/net/hw/Makefile
@@ -91,5 +91,5 @@ include ../../../net/ynl.mk
  include ../../../net/bpf.mk
ifeq ($(HAS_IOURING_ZCRX),y)
-$(OUTPUT)/iou-zcrx: LDLIBS += -luring
+$(OUTPUT)/iou-zcrx: LDLIBS += -luring -lpthread
  endif
diff --git a/tools/testing/selftests/drivers/net/hw/iou-zcrx.c 
b/tools/testing/selftests/drivers/net/hw/iou-zcrx.c
index 9b62fd0703e61..f793a6c04e412 100644
--- a/tools/testing/selftests/drivers/net/hw/iou-zcrx.c
+++ b/tools/testing/selftests/drivers/net/hw/iou-zcrx.c
@@ -4,6 +4,7 @@
  #include <error.h>
  #include <fcntl.h>
  #include <limits.h>
+#include <pthread.h>
  #include <stdbool.h>
  #include <stdint.h>
  #include <stdio.h>
@@ -85,6 +86,7 @@ static int cfg_send_size = SEND_SIZE;
  static struct sockaddr_in6 cfg_addr;
  static unsigned int cfg_rx_buf_len;
  static bool cfg_dry_run;
+static int cfg_num_threads = 1;
static char *payload; @@ -379,7 +381,7 @@ static void run_server(void)
                error(1, 0, "test failed\n");
  }
-static void run_client(void)
+static void *client_worker(void *arg)
  {
        ssize_t to_send = cfg_send_size;
        ssize_t sent = 0;
@@ -405,12 +407,36 @@ static void run_client(void)
        }
close(fd);
+       return NULL;
+}
+
+static void run_client(void)
+{
+       int total_conns = cfg_num_threads * cfg_num_threads;
+       pthread_t *threads;
+       int i, ret;
+
+       threads = calloc(total_conns, sizeof(*threads));
+       if (!threads)
+               error(1, 0, "calloc()");
+
+       for (i = 0; i < total_conns; i++) {
+               ret = pthread_create(&threads[i], NULL, client_worker, NULL);
+               if (ret)
+                       error(1, ret, "pthread_create()");
+       }
+
+       for (i = 0; i < total_conns; i++)
+               pthread_join(threads[i], NULL);
+
+       free(threads);
  }
static void usage(const char *filepath)
  {
        error(1, 0, "Usage: %s (-4|-6) (-s|-c) -h<server_ip> -p<port> "
-                   "-l<payload_size> -i<ifname> -q<rxq_id>", filepath);
+                   "-l<payload_size> -i<ifname> -q<rxq_id> -t<num_threads>",
+                   filepath);
  }
static void parse_opts(int argc, char **argv)
@@ -428,7 +454,7 @@ static void parse_opts(int argc, char **argv)
                usage(argv[0]);
        cfg_payload_len = max_payload_len;
- while ((c = getopt(argc, argv, "sch:p:l:i:q:o:z:x:d")) != -1) {
+       while ((c = getopt(argc, argv, "sch:p:l:i:q:o:z:x:dt:")) != -1) {
                switch (c) {
                case 's':
                        if (cfg_client)
@@ -469,6 +495,9 @@ static void parse_opts(int argc, char **argv)
                case 'd':
                        cfg_dry_run = true;
                        break;
+               case 't':
+                       cfg_num_threads = strtoul(optarg, NULL, 0);
+                       break;
                }
        }

Reviewed-by: David Wei <[email protected]>

Reply via email to