Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/4] selftests/xsk: simplify UMEM setup
@ 2026-06-03  6:03 Tushar Vyavahare
  2026-06-03  6:03 ` [PATCH net-next v2 1/4] selftests/xsk: Introduce helpers for setting UMEM properties Tushar Vyavahare
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Tushar Vyavahare @ 2026-06-03  6:03 UTC (permalink / raw)
  To: netdev, magnus.karlsson, maciej.fijalkowski, stfomichev,
	kernelxing, davem, kuba, pabeni, ast, daniel, tirthendu.sarkar,
	tushar.vyavahare
  Cc: bpf

This series simplifies UMEM handling in selftests/xsk.

It centralizes UMEM property setup through helpers, moves UMEM ownership
from ifobject to socket-owned state, and normalizes umem_size/mmap_size
usage across the touched paths.

v1 -> v2:
- Applied helper usage consistently across the touched test paths.
- Moved UMEM ownership to socket-owned state and switched to one
  heap-backed umem_real object at xsk_arr[0] with explicit reset/cleanup.
- Kept shared-UMEM TX behavior unchanged via TX-local UMEM state
  copy/reset during TX configuration.
- Folded pkt_generate() umem parameter removal into the ownership
  refactor patch (no standalone cleanup patch). [Maciej]
- Updated mmap_size teardown handling to join the RX worker thread in
  single-thread mode before cleanup to synchronize UMEM mapping state.

Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>

Tushar Vyavahare (4):
  selftests/xsk: Introduce helpers for setting UMEM properties
  selftests/xsk: Move UMEM state from ifobject to xsk_socket_info
  selftests/xsk: Use umem_size() helper consistently
  selftests/xsk: Introduce mmap_size in umem struct

 .../selftests/bpf/prog_tests/test_xsk.c       | 203 ++++++++++--------
 .../selftests/bpf/prog_tests/test_xsk.h       |   3 +-
 2 files changed, 117 insertions(+), 89 deletions(-)

-- 
2.43.0


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

* [PATCH net-next v2 1/4] selftests/xsk: Introduce helpers for setting UMEM properties
  2026-06-03  6:03 [PATCH net-next v2 0/4] selftests/xsk: simplify UMEM setup Tushar Vyavahare
@ 2026-06-03  6:03 ` Tushar Vyavahare
  2026-06-03 14:52   ` Maciej Fijalkowski
  2026-06-03  6:03 ` [PATCH net-next v2 2/4] selftests/xsk: Move UMEM state from ifobject to xsk_socket_info Tushar Vyavahare
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Tushar Vyavahare @ 2026-06-03  6:03 UTC (permalink / raw)
  To: netdev, magnus.karlsson, maciej.fijalkowski, stfomichev,
	kernelxing, davem, kuba, pabeni, ast, daniel, tirthendu.sarkar,
	tushar.vyavahare
  Cc: bpf

UMEM properties are set via open-coded field assignments in multiple test
paths, which makes updates noisy and error-prone.

Introduce two helpers to set UMEM properties through a single interface.
This keeps setup logic consistent across tests and makes future refactoring
simpler.

No functional behavior change is intended.

Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
---
 .../selftests/bpf/prog_tests/test_xsk.c       | 36 ++++++++++---------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
index 7950c504ed28..3369450da974 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
@@ -303,6 +303,18 @@ static void test_spec_reset(struct test_spec *test)
 	__test_spec_init(test, test->ifobj_tx, test->ifobj_rx);
 }
 
+static void test_spec_set_unaligned(struct test_spec *test)
+{
+	test->ifobj_tx->umem->unaligned_mode = true;
+	test->ifobj_rx->umem->unaligned_mode = true;
+}
+
+static void test_spec_set_frame_size(struct test_spec *test, u32 size)
+{
+	test->ifobj_tx->umem->frame_size = size;
+	test->ifobj_rx->umem->frame_size = size;
+}
+
 static void test_spec_set_xdp_prog(struct test_spec *test, struct bpf_program *xdp_prog_rx,
 				   struct bpf_program *xdp_prog_tx, struct bpf_map *xskmap_rx,
 				   struct bpf_map *xskmap_tx)
@@ -2025,8 +2037,7 @@ int testapp_stats_fill_empty(struct test_spec *test)
 
 int testapp_send_receive_unaligned(struct test_spec *test)
 {
-	test->ifobj_tx->umem->unaligned_mode = true;
-	test->ifobj_rx->umem->unaligned_mode = true;
+	test_spec_set_unaligned(test);
 	/* Let half of the packets straddle a 4K buffer boundary */
 	if (pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2))
 		return TEST_FAILURE;
@@ -2037,8 +2048,7 @@ int testapp_send_receive_unaligned(struct test_spec *test)
 int testapp_send_receive_unaligned_mb(struct test_spec *test)
 {
 	test->mtu = MAX_ETH_JUMBO_SIZE;
-	test->ifobj_tx->umem->unaligned_mode = true;
-	test->ifobj_rx->umem->unaligned_mode = true;
+	test_spec_set_unaligned(test);
 	if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MAX_ETH_JUMBO_SIZE))
 		return TEST_FAILURE;
 	return testapp_validate_traffic(test);
@@ -2337,8 +2347,7 @@ int testapp_send_receive(struct test_spec *test)
 
 int testapp_send_receive_2k_frame(struct test_spec *test)
 {
-	test->ifobj_tx->umem->frame_size = 2048;
-	test->ifobj_rx->umem->frame_size = 2048;
+	test_spec_set_frame_size(test, 2048);
 	if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE))
 		return TEST_FAILURE;
 	return testapp_validate_traffic(test);
@@ -2363,15 +2372,13 @@ int testapp_aligned_inv_desc(struct test_spec *test)
 
 int testapp_aligned_inv_desc_2k_frame(struct test_spec *test)
 {
-	test->ifobj_tx->umem->frame_size = 2048;
-	test->ifobj_rx->umem->frame_size = 2048;
+	test_spec_set_frame_size(test, 2048);
 	return testapp_invalid_desc(test);
 }
 
 int testapp_unaligned_inv_desc(struct test_spec *test)
 {
-	test->ifobj_tx->umem->unaligned_mode = true;
-	test->ifobj_rx->umem->unaligned_mode = true;
+	test_spec_set_unaligned(test);
 	return testapp_invalid_desc(test);
 }
 
@@ -2380,10 +2387,8 @@ int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test)
 	u64 page_size, umem_size;
 
 	/* Odd frame size so the UMEM doesn't end near a page boundary. */
-	test->ifobj_tx->umem->frame_size = 4001;
-	test->ifobj_rx->umem->frame_size = 4001;
-	test->ifobj_tx->umem->unaligned_mode = true;
-	test->ifobj_rx->umem->unaligned_mode = true;
+	test_spec_set_frame_size(test, 4001);
+	test_spec_set_unaligned(test);
 	/* This test exists to test descriptors that staddle the end of
 	 * the UMEM but not a page.
 	 */
@@ -2402,8 +2407,7 @@ int testapp_aligned_inv_desc_mb(struct test_spec *test)
 
 int testapp_unaligned_inv_desc_mb(struct test_spec *test)
 {
-	test->ifobj_tx->umem->unaligned_mode = true;
-	test->ifobj_rx->umem->unaligned_mode = true;
+	test_spec_set_unaligned(test);
 	return testapp_invalid_desc_mb(test);
 }
 
-- 
2.43.0


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

* [PATCH net-next v2 2/4] selftests/xsk: Move UMEM state from ifobject to xsk_socket_info
  2026-06-03  6:03 [PATCH net-next v2 0/4] selftests/xsk: simplify UMEM setup Tushar Vyavahare
  2026-06-03  6:03 ` [PATCH net-next v2 1/4] selftests/xsk: Introduce helpers for setting UMEM properties Tushar Vyavahare
@ 2026-06-03  6:03 ` Tushar Vyavahare
  2026-06-03 14:51   ` Maciej Fijalkowski
  2026-06-03  6:03 ` [PATCH net-next v2 3/4] selftests/xsk: Use umem_size() helper consistently Tushar Vyavahare
  2026-06-03  6:03 ` [PATCH net-next v2 4/4] selftests/xsk: Introduce mmap_size in umem struct Tushar Vyavahare
  3 siblings, 1 reply; 9+ messages in thread
From: Tushar Vyavahare @ 2026-06-03  6:03 UTC (permalink / raw)
  To: netdev, magnus.karlsson, maciej.fijalkowski, stfomichev,
	kernelxing, davem, kuba, pabeni, ast, daniel, tirthendu.sarkar,
	tushar.vyavahare
  Cc: bpf

Move UMEM ownership from ifobject to xsk_socket_info and access it
through xsk->umem.

Allocate one shared umem_real in ifobject_create() and let all
sockets reference it through xsk->umem, while keeping ownership in
xsk_arr[0]. Keep the existing goto-based error path in
ifobject_create() and free the allocation once in ifobject_delete().

Reset the existing umem_real in __test_spec_init() with memset()
instead of reallocating it.

Preserve shared-UMEM behavior by copying RX UMEM state into a TX-local
UMEM state in thread_common_ops_tx() and reset base_addr/next_buffer
before TX socket configuration.

Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
---
 .../selftests/bpf/prog_tests/test_xsk.c       | 133 +++++++++++-------
 .../selftests/bpf/prog_tests/test_xsk.h       |   2 +-
 2 files changed, 80 insertions(+), 55 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
index 3369450da974..7e0d34111b2f 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
@@ -65,9 +65,9 @@ static void gen_eth_hdr(struct xsk_socket_info *xsk, struct ethhdr *eth_hdr)
 	eth_hdr->h_proto = htons(ETH_P_LOOPBACK);
 }
 
-static bool is_umem_valid(struct ifobject *ifobj)
+static bool is_umem_valid(struct xsk_socket_info *xsk)
 {
-	return !!ifobj->umem->umem;
+	return !!xsk->umem->umem;
 }
 
 static u32 mode_to_xdp_flags(enum test_mode mode)
@@ -213,6 +213,7 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
 
 	for (i = 0; i < MAX_INTERFACES; i++) {
 		struct ifobject *ifobj = i ? ifobj_rx : ifobj_tx;
+		struct xsk_umem_info *umem_real;
 
 		ifobj->xsk = &ifobj->xsk_arr[0];
 		ifobj->use_poll = false;
@@ -229,24 +230,30 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
 			ifobj->tx_on = false;
 		}
 
-		memset(ifobj->umem, 0, sizeof(*ifobj->umem));
-		ifobj->umem->num_frames = DEFAULT_UMEM_BUFFERS;
-		ifobj->umem->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
-
+		umem_real = ifobj->xsk_arr[0].umem_real;
+		memset(umem_real, 0, sizeof(*umem_real));
 		for (j = 0; j < MAX_SOCKETS; j++) {
-			memset(&ifobj->xsk_arr[j], 0, sizeof(ifobj->xsk_arr[j]));
-			ifobj->xsk_arr[j].rxqsize = XSK_RING_CONS__DEFAULT_NUM_DESCS;
-			ifobj->xsk_arr[j].batch_size = DEFAULT_BATCH_SIZE;
+			struct xsk_socket_info *xsk = &ifobj->xsk_arr[j];
+
+			memset(xsk, 0, sizeof(*xsk));
+			xsk->rxqsize = XSK_RING_CONS__DEFAULT_NUM_DESCS;
+			if (j == 0)
+				xsk->umem_real = umem_real;
+			xsk->umem = umem_real;
+			xsk->batch_size = DEFAULT_BATCH_SIZE;
 			if (i == 0)
-				ifobj->xsk_arr[j].pkt_stream = test->tx_pkt_stream_default;
+				xsk->pkt_stream = test->tx_pkt_stream_default;
 			else
-				ifobj->xsk_arr[j].pkt_stream = test->rx_pkt_stream_default;
+				xsk->pkt_stream = test->rx_pkt_stream_default;
 
-			memcpy(ifobj->xsk_arr[j].src_mac, g_mac, ETH_ALEN);
-			memcpy(ifobj->xsk_arr[j].dst_mac, g_mac, ETH_ALEN);
-			ifobj->xsk_arr[j].src_mac[5] += ((j * 2) + 0);
-			ifobj->xsk_arr[j].dst_mac[5] += ((j * 2) + 1);
+			memcpy(xsk->src_mac, g_mac, ETH_ALEN);
+			memcpy(xsk->dst_mac, g_mac, ETH_ALEN);
+			xsk->src_mac[5] += ((j * 2) + 0);
+			xsk->dst_mac[5] += ((j * 2) + 1);
 		}
+
+		ifobj->xsk->umem->num_frames = DEFAULT_UMEM_BUFFERS;
+		ifobj->xsk->umem->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
 	}
 
 	if (ifobj_tx->hw_ring_size_supp)
@@ -305,14 +312,14 @@ static void test_spec_reset(struct test_spec *test)
 
 static void test_spec_set_unaligned(struct test_spec *test)
 {
-	test->ifobj_tx->umem->unaligned_mode = true;
-	test->ifobj_rx->umem->unaligned_mode = true;
+	test->ifobj_tx->xsk->umem->unaligned_mode = true;
+	test->ifobj_rx->xsk->umem->unaligned_mode = true;
 }
 
 static void test_spec_set_frame_size(struct test_spec *test, u32 size)
 {
-	test->ifobj_tx->umem->frame_size = size;
-	test->ifobj_rx->umem->frame_size = size;
+	test->ifobj_tx->xsk->umem->frame_size = size;
+	test->ifobj_rx->xsk->umem->frame_size = size;
 }
 
 static void test_spec_set_xdp_prog(struct test_spec *test, struct bpf_program *xdp_prog_rx,
@@ -623,10 +630,10 @@ static void pkt_stream_cancel(struct pkt_stream *pkt_stream)
 	pkt_stream->current_pkt_nb--;
 }
 
-static void pkt_generate(struct xsk_socket_info *xsk, struct xsk_umem_info *umem, u64 addr, u32 len,
-			 u32 pkt_nb, u32 bytes_written)
+static void pkt_generate(struct xsk_socket_info *xsk, u64 addr, u32 len, u32 pkt_nb,
+			 u32 bytes_written)
 {
-	void *data = xsk_umem__get_data(umem->buffer, addr);
+	void *data = xsk_umem__get_data(xsk->umem->buffer, addr);
 
 	if (len < MIN_PKT_SIZE)
 		return;
@@ -1003,7 +1010,7 @@ static int __receive_pkts(struct test_spec *test, struct xsk_socket_info *xsk)
 			return TEST_FAILURE;
 
 		if (!ret) {
-			if (!is_umem_valid(test->ifobj_tx))
+			if (!is_umem_valid(test->ifobj_tx->xsk))
 				return TEST_PASS;
 
 			ksft_print_msg("ERROR: [%s] Poll timed out\n", __func__);
@@ -1163,7 +1170,7 @@ static int __send_pkts(struct ifobject *ifobject, struct xsk_socket_info *xsk, b
 {
 	u32 i, idx = 0, valid_pkts = 0, valid_frags = 0, buffer_len;
 	struct pkt_stream *pkt_stream = xsk->pkt_stream;
-	struct xsk_umem_info *umem = ifobject->umem;
+	struct xsk_umem_info *umem = xsk->umem;
 	bool use_poll = ifobject->use_poll;
 	struct pollfd fds = { };
 	int ret;
@@ -1222,7 +1229,7 @@ static int __send_pkts(struct ifobject *ifobject, struct xsk_socket_info *xsk, b
 		while (nb_frags_left--) {
 			struct xdp_desc *tx_desc = xsk_ring_prod__tx_desc(&xsk->tx, idx + i);
 
-			tx_desc->addr = pkt_get_addr(pkt, ifobject->umem);
+			tx_desc->addr = pkt_get_addr(pkt, umem);
 			if (pkt_stream->verbatim) {
 				tx_desc->len = pkt->len;
 				tx_desc->options = pkt->options;
@@ -1234,7 +1241,7 @@ static int __send_pkts(struct ifobject *ifobject, struct xsk_socket_info *xsk, b
 				tx_desc->options = 0;
 			}
 			if (pkt->valid)
-				pkt_generate(xsk, umem, tx_desc->addr, tx_desc->len, pkt->pkt_nb,
+				pkt_generate(xsk, tx_desc->addr, tx_desc->len, pkt->pkt_nb,
 					     bytes_written);
 			bytes_written += tx_desc->len;
 
@@ -1315,7 +1322,7 @@ bool all_packets_sent(struct test_spec *test, unsigned long *bitmap)
 
 static int send_pkts(struct test_spec *test, struct ifobject *ifobject)
 {
-	bool timeout = !is_umem_valid(test->ifobj_rx);
+	bool timeout = !is_umem_valid(test->ifobj_rx->xsk);
 	DECLARE_BITMAP(bitmap, test->nb_sockets);
 	u32 i, ret;
 
@@ -1500,14 +1507,25 @@ static int xsk_configure(struct test_spec *test, struct ifobject *ifobject,
 
 static int thread_common_ops_tx(struct test_spec *test, struct ifobject *ifobject)
 {
-	int ret = xsk_configure(test, ifobject, test->ifobj_rx->umem, true);
+	struct xsk_umem_info *umem_rx, *umem_tx;
+	int ret;
 
+	if (!test->ifobj_rx || !test->ifobj_rx->xsk_arr[0].umem->umem) {
+		ksft_print_msg("Error: RX UMEM is not initialized before shared-UMEM TX setup\n");
+		return -EINVAL;
+	}
+
+	umem_rx = test->ifobj_rx->xsk_arr[0].umem;
+	umem_tx = ifobject->xsk_arr[0].umem_real;
+	memcpy(umem_tx, umem_rx, sizeof(*umem_tx));
+	umem_tx->base_addr = 0;
+	umem_tx->next_buffer = 0;
+
+	ret = xsk_configure(test, ifobject, umem_tx, true);
 	if (ret)
 		return ret;
 	ifobject->xsk = &ifobject->xsk_arr[0];
 	ifobject->xskmap = test->ifobj_rx->xskmap;
-	memcpy(ifobject->umem, test->ifobj_rx->umem, sizeof(struct xsk_umem_info));
-	ifobject->umem->base_addr = 0;
 
 	return 0;
 }
@@ -1560,6 +1578,7 @@ static int xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream
 
 static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 {
+	struct xsk_umem_info *umem = ifobject->xsk->umem;
 	LIBBPF_OPTS(bpf_xdp_query_opts, opts);
 	int mmap_flags;
 	u64 umem_sz;
@@ -1567,10 +1586,10 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 	int ret;
 	u32 i;
 
-	umem_sz = ifobject->umem->num_frames * ifobject->umem->frame_size;
+	umem_sz = umem->num_frames * umem->frame_size;
 	mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
 
-	if (ifobject->umem->unaligned_mode)
+	if (umem->unaligned_mode)
 		mmap_flags |= MAP_HUGETLB | MAP_HUGE_2MB;
 
 	if (ifobject->shared_umem)
@@ -1580,11 +1599,11 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 	if (bufs == MAP_FAILED)
 		return -errno;
 
-	ret = xsk_configure_umem(ifobject, ifobject->umem, bufs, umem_sz);
+	ret = xsk_configure_umem(ifobject, umem, bufs, umem_sz);
 	if (ret)
 		return ret;
 
-	ret = xsk_configure(test, ifobject, ifobject->umem, false);
+	ret = xsk_configure(test, ifobject, umem, false);
 	if (ret)
 		return ret;
 
@@ -1593,14 +1612,13 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 	if (!ifobject->rx_on)
 		return 0;
 
-	ret = xsk_populate_fill_ring(ifobject->umem, ifobject->xsk->pkt_stream,
+	ret = xsk_populate_fill_ring(umem, ifobject->xsk->pkt_stream,
 				     ifobject->use_fill_ring);
 	if (ret)
 		return ret;
 
 	for (i = 0; i < test->nb_sockets; i++) {
-		ifobject->xsk = &ifobject->xsk_arr[i];
-		ret = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk, i);
+		ret = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk_arr[i].xsk, i);
 		if (ret)
 			return ret;
 	}
@@ -1687,14 +1705,15 @@ void *worker_testapp_validate_rx(void *arg)
 
 static void testapp_clean_xsk_umem(struct ifobject *ifobj)
 {
-	u64 umem_sz = ifobj->umem->num_frames * ifobj->umem->frame_size;
+	struct xsk_umem_info *umem = ifobj->xsk->umem;
+	u64 umem_sz = umem->num_frames * umem->frame_size;
 
 	if (ifobj->shared_umem)
 		umem_sz *= 2;
 
 	umem_sz = ceil_u64(umem_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
-	xsk_umem__delete(ifobj->umem->umem);
-	munmap(ifobj->umem->buffer, umem_sz);
+	xsk_umem__delete(umem->umem);
+	munmap(umem->buffer, umem_sz);
 }
 
 static void handler(int signum)
@@ -1856,9 +1875,11 @@ static int testapp_validate_traffic(struct test_spec *test)
 {
 	struct ifobject *ifobj_rx = test->ifobj_rx;
 	struct ifobject *ifobj_tx = test->ifobj_tx;
+	struct xsk_umem_info *umem_rx = ifobj_rx->xsk->umem;
+	struct xsk_umem_info *umem_tx = ifobj_tx->xsk->umem;
 
-	if ((ifobj_rx->umem->unaligned_mode && !ifobj_rx->unaligned_supp) ||
-	    (ifobj_tx->umem->unaligned_mode && !ifobj_tx->unaligned_supp)) {
+	if ((umem_rx->unaligned_mode && !ifobj_rx->unaligned_supp) ||
+	    (umem_tx->unaligned_mode && !ifobj_tx->unaligned_supp)) {
 		ksft_print_msg("No huge pages present.\n");
 		return TEST_SKIP;
 	}
@@ -1965,12 +1986,13 @@ int testapp_xdp_prog_cleanup(struct test_spec *test)
 
 int testapp_headroom(struct test_spec *test)
 {
-	test->ifobj_rx->umem->frame_headroom = UMEM_HEADROOM_TEST_SIZE;
+	test->ifobj_rx->xsk->umem->frame_headroom = UMEM_HEADROOM_TEST_SIZE;
 	return testapp_validate_traffic(test);
 }
 
 int testapp_stats_rx_dropped(struct test_spec *test)
 {
+	struct xsk_umem_info *umem = test->ifobj_rx->xsk->umem;
 	u32 umem_tr = test->ifobj_tx->umem_tailroom;
 
 	if (test->mode == TEST_MODE_ZC) {
@@ -1980,7 +2002,7 @@ int testapp_stats_rx_dropped(struct test_spec *test)
 
 	if (pkt_stream_replace_half(test, (MIN_PKT_SIZE * 3) + umem_tr, 0))
 		return TEST_FAILURE;
-	test->ifobj_rx->umem->frame_headroom = test->ifobj_rx->umem->frame_size -
+	umem->frame_headroom = umem->frame_size -
 		XDP_PACKET_HEADROOM - (MIN_PKT_SIZE * 2) - umem_tr;
 	if (pkt_stream_receive_half(test))
 		return TEST_FAILURE;
@@ -2074,7 +2096,7 @@ int testapp_send_receive_mb(struct test_spec *test)
 
 int testapp_invalid_desc_mb(struct test_spec *test)
 {
-	struct xsk_umem_info *umem = test->ifobj_tx->umem;
+	struct xsk_umem_info *umem = test->ifobj_tx->xsk->umem;
 	u64 umem_size = umem->num_frames * umem->frame_size;
 	struct pkt pkts[] = {
 		/* Valid packet for synch to start with */
@@ -2115,7 +2137,7 @@ int testapp_invalid_desc_mb(struct test_spec *test)
 
 int testapp_invalid_desc(struct test_spec *test)
 {
-	struct xsk_umem_info *umem = test->ifobj_tx->umem;
+	struct xsk_umem_info *umem = test->ifobj_tx->xsk->umem;
 	u64 umem_size = umem->num_frames * umem->frame_size;
 	struct pkt pkts[] = {
 		/* Zero packet address allowed */
@@ -2214,7 +2236,7 @@ int testapp_poll_txq_tmout(struct test_spec *test)
 {
 	test->ifobj_tx->use_poll = true;
 	/* create invalid frame by set umem frame_size and pkt length equal to 2048 */
-	test->ifobj_tx->umem->frame_size = 2048;
+	test->ifobj_tx->xsk->umem->frame_size = 2048;
 	if (pkt_stream_replace(test, 2 * DEFAULT_PKT_CNT, 2048))
 		return TEST_FAILURE;
 	return testapp_validate_traffic_single_thread(test, test->ifobj_tx);
@@ -2393,7 +2415,8 @@ int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test)
 	 * the UMEM but not a page.
 	 */
 	page_size = sysconf(_SC_PAGESIZE);
-	umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
+	umem_size = test->ifobj_tx->xsk->umem->num_frames *
+		test->ifobj_tx->xsk->umem->frame_size;
 	assert(umem_size % page_size > MIN_PKT_SIZE);
 	assert(umem_size % page_size < page_size - MIN_PKT_SIZE);
 
@@ -2451,9 +2474,9 @@ int testapp_hw_sw_max_ring_size(struct test_spec *test)
 	test->total_steps = 2;
 	test->ifobj_tx->ring.tx_pending = test->ifobj_tx->ring.tx_max_pending;
 	test->ifobj_tx->ring.rx_pending  = test->ifobj_tx->ring.rx_max_pending;
-	test->ifobj_rx->umem->num_frames = max_descs;
-	test->ifobj_rx->umem->fill_size = max_descs;
-	test->ifobj_rx->umem->comp_size = max_descs;
+	test->ifobj_rx->xsk->umem->num_frames = max_descs;
+	test->ifobj_rx->xsk->umem->fill_size = max_descs;
+	test->ifobj_rx->xsk->umem->comp_size = max_descs;
 	test->ifobj_tx->xsk->batch_size = XSK_RING_PROD__DEFAULT_NUM_DESCS;
 	test->ifobj_rx->xsk->batch_size = XSK_RING_PROD__DEFAULT_NUM_DESCS;
 
@@ -2594,8 +2617,8 @@ struct ifobject *ifobject_create(void)
 	if (!ifobj->xsk_arr)
 		goto out_xsk_arr;
 
-	ifobj->umem = calloc(1, sizeof(*ifobj->umem));
-	if (!ifobj->umem)
+	ifobj->xsk_arr[0].umem_real = calloc(1, sizeof(struct xsk_umem_info));
+	if (!ifobj->xsk_arr[0].umem_real)
 		goto out_umem;
 
 	return ifobj;
@@ -2609,7 +2632,9 @@ struct ifobject *ifobject_create(void)
 
 void ifobject_delete(struct ifobject *ifobj)
 {
-	free(ifobj->umem);
+	if (ifobj->xsk_arr)
+		free(ifobj->xsk_arr[0].umem_real);
+
 	free(ifobj->xsk_arr);
 	free(ifobj);
 }
diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.h b/tools/testing/selftests/bpf/prog_tests/test_xsk.h
index 1ab8aee4ce56..99003995d7c3 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_xsk.h
+++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.h
@@ -83,6 +83,7 @@ typedef int (*test_func_t)(struct test_spec *test);
 struct xsk_socket_info {
 	struct xsk_ring_cons rx;
 	struct xsk_ring_prod tx;
+	struct xsk_umem_info *umem_real;
 	struct xsk_umem_info *umem;
 	struct xsk_socket *xsk;
 	struct pkt_stream *pkt_stream;
@@ -123,7 +124,6 @@ struct ifobject {
 	char ifname[MAX_INTERFACE_NAME_CHARS];
 	struct xsk_socket_info *xsk;
 	struct xsk_socket_info *xsk_arr;
-	struct xsk_umem_info *umem;
 	thread_func_t func_ptr;
 	validation_func_t validation_func;
 	struct xsk_xdp_progs *xdp_progs;
-- 
2.43.0


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

* [PATCH net-next v2 3/4] selftests/xsk: Use umem_size() helper consistently
  2026-06-03  6:03 [PATCH net-next v2 0/4] selftests/xsk: simplify UMEM setup Tushar Vyavahare
  2026-06-03  6:03 ` [PATCH net-next v2 1/4] selftests/xsk: Introduce helpers for setting UMEM properties Tushar Vyavahare
  2026-06-03  6:03 ` [PATCH net-next v2 2/4] selftests/xsk: Move UMEM state from ifobject to xsk_socket_info Tushar Vyavahare
@ 2026-06-03  6:03 ` Tushar Vyavahare
  2026-06-03 15:34   ` Maciej Fijalkowski
  2026-06-03  6:03 ` [PATCH net-next v2 4/4] selftests/xsk: Introduce mmap_size in umem struct Tushar Vyavahare
  3 siblings, 1 reply; 9+ messages in thread
From: Tushar Vyavahare @ 2026-06-03  6:03 UTC (permalink / raw)
  To: netdev, magnus.karlsson, maciej.fijalkowski, stfomichev,
	kernelxing, davem, kuba, pabeni, ast, daniel, tirthendu.sarkar,
	tushar.vyavahare
  Cc: bpf

Replace remaining open-coded umem->num_frames * umem->frame_size
calculations in test_xsk.c with the existing umem_size() helper.

This keeps UMEM size computation centralized, avoids duplicated arithmetic,
and improves readability with no intended behavior change.

Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
---
 .../selftests/bpf/prog_tests/test_xsk.c       | 36 +++++++++----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
index 7e0d34111b2f..f1730466ffd9 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
@@ -829,11 +829,11 @@ static bool is_frag_valid(struct xsk_umem_info *umem, u64 addr, u32 len, u32 exp
 {
 	u32 seqnum, pkt_nb, *pkt_data, words_to_end, expected_seqnum;
 	void *data = xsk_umem__get_data(umem->buffer, addr);
+	u64 umem_sz = umem_size(umem);
 
 	addr -= umem->base_addr;
 
-	if (addr >= umem->num_frames * umem->frame_size ||
-	    addr + len > umem->num_frames * umem->frame_size) {
+	if (addr >= umem_sz || addr + len > umem_sz) {
 		ksft_print_msg("Frag invalid addr: %llx len: %u\n",
 			       (unsigned long long)addr, len);
 		return false;
@@ -1586,7 +1586,7 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 	int ret;
 	u32 i;
 
-	umem_sz = umem->num_frames * umem->frame_size;
+	umem_sz = umem_size(umem);
 	mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
 
 	if (umem->unaligned_mode)
@@ -1706,12 +1706,13 @@ void *worker_testapp_validate_rx(void *arg)
 static void testapp_clean_xsk_umem(struct ifobject *ifobj)
 {
 	struct xsk_umem_info *umem = ifobj->xsk->umem;
-	u64 umem_sz = umem->num_frames * umem->frame_size;
+	u64 umem_sz = umem_size(umem);
 
 	if (ifobj->shared_umem)
 		umem_sz *= 2;
 
 	umem_sz = ceil_u64(umem_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
+
 	xsk_umem__delete(umem->umem);
 	munmap(umem->buffer, umem_sz);
 }
@@ -2097,7 +2098,7 @@ int testapp_send_receive_mb(struct test_spec *test)
 int testapp_invalid_desc_mb(struct test_spec *test)
 {
 	struct xsk_umem_info *umem = test->ifobj_tx->xsk->umem;
-	u64 umem_size = umem->num_frames * umem->frame_size;
+	u64 umem_sz = umem_size(umem);
 	struct pkt pkts[] = {
 		/* Valid packet for synch to start with */
 		{0, MIN_PKT_SIZE, 0, true, 0},
@@ -2107,7 +2108,7 @@ int testapp_invalid_desc_mb(struct test_spec *test)
 		{0, 0, 0, false, 0},
 		/* Invalid address in the second frame */
 		{0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
-		{umem_size, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
+		{umem_sz, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
 		/* Invalid len in the middle */
 		{0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
 		{0, XSK_UMEM__INVALID_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
@@ -2138,7 +2139,7 @@ int testapp_invalid_desc_mb(struct test_spec *test)
 int testapp_invalid_desc(struct test_spec *test)
 {
 	struct xsk_umem_info *umem = test->ifobj_tx->xsk->umem;
-	u64 umem_size = umem->num_frames * umem->frame_size;
+	u64 umem_sz = umem_size(umem);
 	struct pkt pkts[] = {
 		/* Zero packet address allowed */
 		{0, MIN_PKT_SIZE, 0, true},
@@ -2149,11 +2150,11 @@ int testapp_invalid_desc(struct test_spec *test)
 		/* Packet too large */
 		{0, XSK_UMEM__INVALID_FRAME_SIZE, 0, false},
 		/* Up to end of umem allowed */
-		{umem_size - MIN_PKT_SIZE - 2 * umem->frame_size, MIN_PKT_SIZE, 0, true},
+		{umem_sz - MIN_PKT_SIZE - 2 * umem->frame_size, MIN_PKT_SIZE, 0, true},
 		/* After umem ends */
-		{umem_size, MIN_PKT_SIZE, 0, false},
+		{umem_sz, MIN_PKT_SIZE, 0, false},
 		/* Straddle the end of umem */
-		{umem_size - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false},
+		{umem_sz - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false},
 		/* Straddle a 4K boundary */
 		{0x1000 - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false},
 		/* Straddle a 2K boundary */
@@ -2171,9 +2172,9 @@ int testapp_invalid_desc(struct test_spec *test)
 	}
 
 	if (test->ifobj_tx->shared_umem) {
-		pkts[4].offset += umem_size;
-		pkts[5].offset += umem_size;
-		pkts[6].offset += umem_size;
+		pkts[4].offset += umem_sz;
+		pkts[5].offset += umem_sz;
+		pkts[6].offset += umem_sz;
 	}
 
 	if (pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts)))
@@ -2406,7 +2407,7 @@ int testapp_unaligned_inv_desc(struct test_spec *test)
 
 int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test)
 {
-	u64 page_size, umem_size;
+	u64 page_size, umem_sz;
 
 	/* Odd frame size so the UMEM doesn't end near a page boundary. */
 	test_spec_set_frame_size(test, 4001);
@@ -2415,10 +2416,9 @@ int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test)
 	 * the UMEM but not a page.
 	 */
 	page_size = sysconf(_SC_PAGESIZE);
-	umem_size = test->ifobj_tx->xsk->umem->num_frames *
-		test->ifobj_tx->xsk->umem->frame_size;
-	assert(umem_size % page_size > MIN_PKT_SIZE);
-	assert(umem_size % page_size < page_size - MIN_PKT_SIZE);
+	umem_sz = umem_size(test->ifobj_tx->xsk->umem);
+	assert(umem_sz % page_size > MIN_PKT_SIZE);
+	assert(umem_sz % page_size < page_size - MIN_PKT_SIZE);
 
 	return testapp_invalid_desc(test);
 }
-- 
2.43.0


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

* [PATCH net-next v2 4/4] selftests/xsk: Introduce mmap_size in umem struct
  2026-06-03  6:03 [PATCH net-next v2 0/4] selftests/xsk: simplify UMEM setup Tushar Vyavahare
                   ` (2 preceding siblings ...)
  2026-06-03  6:03 ` [PATCH net-next v2 3/4] selftests/xsk: Use umem_size() helper consistently Tushar Vyavahare
@ 2026-06-03  6:03 ` Tushar Vyavahare
  2026-06-03 15:35   ` Maciej Fijalkowski
  3 siblings, 1 reply; 9+ messages in thread
From: Tushar Vyavahare @ 2026-06-03  6:03 UTC (permalink / raw)
  To: netdev, magnus.karlsson, maciej.fijalkowski, stfomichev,
	kernelxing, davem, kuba, pabeni, ast, daniel, tirthendu.sarkar,
	tushar.vyavahare
  Cc: bpf

UMEM teardown currently recomputes the munmap() length from frame
geometry, shared-UMEM adjustment, and hugepage rounding. This duplicates
setup-time logic in cleanup and relies on re-deriving the mapping size
instead of using the size originally established for the mapping.

Store the final mapping length in xsk_umem_info as mmap_size when the
UMEM mapping is created, and use that value during teardown.

Also join the RX worker thread before cleanup in the single-thread
path. This establishes synchronization before reading umem->mmap_size
in teardown and avoids a potential visibility race.

This removes duplicated size arithmetic in cleanup and makes munmap()
use the canonical mapping size recorded at setup time.

Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
---
 .../selftests/bpf/prog_tests/test_xsk.c       | 20 +++++++++----------
 .../selftests/bpf/prog_tests/test_xsk.h       |  1 +
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
index f1730466ffd9..e94c38a1faf4 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
@@ -1581,7 +1581,7 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 	struct xsk_umem_info *umem = ifobject->xsk->umem;
 	LIBBPF_OPTS(bpf_xdp_query_opts, opts);
 	int mmap_flags;
-	u64 umem_sz;
+	u64 umem_sz, mmap_sz;
 	void *bufs;
 	int ret;
 	u32 i;
@@ -1595,10 +1595,15 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 	if (ifobject->shared_umem)
 		umem_sz *= 2;
 
-	bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
+	mmap_sz = umem->unaligned_mode ?
+		ceil_u64(umem_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE : umem_sz;
+
+	bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
 	if (bufs == MAP_FAILED)
 		return -errno;
 
+	umem->mmap_size = mmap_sz;
+
 	ret = xsk_configure_umem(ifobject, umem, bufs, umem_sz);
 	if (ret)
 		return ret;
@@ -1706,15 +1711,9 @@ void *worker_testapp_validate_rx(void *arg)
 static void testapp_clean_xsk_umem(struct ifobject *ifobj)
 {
 	struct xsk_umem_info *umem = ifobj->xsk->umem;
-	u64 umem_sz = umem_size(umem);
-
-	if (ifobj->shared_umem)
-		umem_sz *= 2;
-
-	umem_sz = ceil_u64(umem_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
 
 	xsk_umem__delete(umem->umem);
-	munmap(umem->buffer, umem_sz);
+	munmap(umem->buffer, umem->mmap_size);
 }
 
 static void handler(int signum)
@@ -1857,8 +1856,7 @@ static int __testapp_validate_traffic(struct test_spec *test, struct ifobject *i
 
 	if (!ifobj2)
 		pthread_kill(t0, SIGUSR1);
-	else
-		pthread_join(t0, NULL);
+	pthread_join(t0, NULL);
 
 	if (test->total_steps == test->current_step || test->fail) {
 		clean_sockets(test, ifobj1);
diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.h b/tools/testing/selftests/bpf/prog_tests/test_xsk.h
index 99003995d7c3..4313d0d87235 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_xsk.h
+++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.h
@@ -103,6 +103,7 @@ struct xsk_umem_info {
 	struct xsk_ring_cons cq;
 	struct xsk_umem *umem;
 	u64 next_buffer;
+	u64 mmap_size;
 	u32 num_frames;
 	u32 frame_headroom;
 	void *buffer;
-- 
2.43.0


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

* Re: [PATCH net-next v2 2/4] selftests/xsk: Move UMEM state from ifobject to xsk_socket_info
  2026-06-03  6:03 ` [PATCH net-next v2 2/4] selftests/xsk: Move UMEM state from ifobject to xsk_socket_info Tushar Vyavahare
@ 2026-06-03 14:51   ` Maciej Fijalkowski
  0 siblings, 0 replies; 9+ messages in thread
From: Maciej Fijalkowski @ 2026-06-03 14:51 UTC (permalink / raw)
  To: Tushar Vyavahare
  Cc: netdev, magnus.karlsson, stfomichev, kernelxing, davem, kuba,
	pabeni, ast, daniel, tirthendu.sarkar, bpf

On Wed, Jun 03, 2026 at 11:33:25AM +0530, Tushar Vyavahare wrote:
> Move UMEM ownership from ifobject to xsk_socket_info and access it
> through xsk->umem.
> 
> Allocate one shared umem_real in ifobject_create() and let all
> sockets reference it through xsk->umem, while keeping ownership in
> xsk_arr[0]. Keep the existing goto-based error path in
> ifobject_create() and free the allocation once in ifobject_delete().
> 
> Reset the existing umem_real in __test_spec_init() with memset()
> instead of reallocating it.
> 
> Preserve shared-UMEM behavior by copying RX UMEM state into a TX-local
> UMEM state in thread_common_ops_tx() and reset base_addr/next_buffer
> before TX socket configuration.
> 
> Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
> ---
>  .../selftests/bpf/prog_tests/test_xsk.c       | 133 +++++++++++-------
>  .../selftests/bpf/prog_tests/test_xsk.h       |   2 +-
>  2 files changed, 80 insertions(+), 55 deletions(-)

...

> -static void pkt_generate(struct xsk_socket_info *xsk, struct xsk_umem_info *umem, u64 addr, u32 len,
> -			 u32 pkt_nb, u32 bytes_written)
> +static void pkt_generate(struct xsk_socket_info *xsk, u64 addr, u32 len, u32 pkt_nb,
> +			 u32 bytes_written)
>  {
> -	void *data = xsk_umem__get_data(umem->buffer, addr);
> +	void *data = xsk_umem__get_data(xsk->umem->buffer, addr);
>  
>  	if (len < MIN_PKT_SIZE)
>  		return;
> @@ -1003,7 +1010,7 @@ static int __receive_pkts(struct test_spec *test, struct xsk_socket_info *xsk)
>  			return TEST_FAILURE;
>  
>  		if (!ret) {
> -			if (!is_umem_valid(test->ifobj_tx))
> +			if (!is_umem_valid(test->ifobj_tx->xsk))
>  				return TEST_PASS;
>  
>  			ksft_print_msg("ERROR: [%s] Poll timed out\n", __func__);
> @@ -1163,7 +1170,7 @@ static int __send_pkts(struct ifobject *ifobject, struct xsk_socket_info *xsk, b
>  {
>  	u32 i, idx = 0, valid_pkts = 0, valid_frags = 0, buffer_len;
>  	struct pkt_stream *pkt_stream = xsk->pkt_stream;
> -	struct xsk_umem_info *umem = ifobject->umem;
> +	struct xsk_umem_info *umem = xsk->umem;
>  	bool use_poll = ifobject->use_poll;
>  	struct pollfd fds = { };
>  	int ret;
> @@ -1222,7 +1229,7 @@ static int __send_pkts(struct ifobject *ifobject, struct xsk_socket_info *xsk, b
>  		while (nb_frags_left--) {
>  			struct xdp_desc *tx_desc = xsk_ring_prod__tx_desc(&xsk->tx, idx + i);
>  
> -			tx_desc->addr = pkt_get_addr(pkt, ifobject->umem);
> +			tx_desc->addr = pkt_get_addr(pkt, umem);
>  			if (pkt_stream->verbatim) {
>  				tx_desc->len = pkt->len;
>  				tx_desc->options = pkt->options;
> @@ -1234,7 +1241,7 @@ static int __send_pkts(struct ifobject *ifobject, struct xsk_socket_info *xsk, b
>  				tx_desc->options = 0;
>  			}
>  			if (pkt->valid)
> -				pkt_generate(xsk, umem, tx_desc->addr, tx_desc->len, pkt->pkt_nb,
> +				pkt_generate(xsk, tx_desc->addr, tx_desc->len, pkt->pkt_nb,

Nit: you have the umem pointer handy, what's the point to change
pkt_generate() interface?

>  					     bytes_written);
>  			bytes_written += tx_desc->len;
>  

...

> @@ -1856,9 +1875,11 @@ static int testapp_validate_traffic(struct test_spec *test)
>  {
>  	struct ifobject *ifobj_rx = test->ifobj_rx;
>  	struct ifobject *ifobj_tx = test->ifobj_tx;
> +	struct xsk_umem_info *umem_rx = ifobj_rx->xsk->umem;
> +	struct xsk_umem_info *umem_tx = ifobj_tx->xsk->umem;
>  
> -	if ((ifobj_rx->umem->unaligned_mode && !ifobj_rx->unaligned_supp) ||
> -	    (ifobj_tx->umem->unaligned_mode && !ifobj_tx->unaligned_supp)) {
> +	if ((umem_rx->unaligned_mode && !ifobj_rx->unaligned_supp) ||
> +	    (umem_tx->unaligned_mode && !ifobj_tx->unaligned_supp)) {
>  		ksft_print_msg("No huge pages present.\n");
>  		return TEST_SKIP;
>  	}

this hunk does not add any value IMHO.

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

* Re: [PATCH net-next v2 1/4] selftests/xsk: Introduce helpers for setting UMEM properties
  2026-06-03  6:03 ` [PATCH net-next v2 1/4] selftests/xsk: Introduce helpers for setting UMEM properties Tushar Vyavahare
@ 2026-06-03 14:52   ` Maciej Fijalkowski
  0 siblings, 0 replies; 9+ messages in thread
From: Maciej Fijalkowski @ 2026-06-03 14:52 UTC (permalink / raw)
  To: Tushar Vyavahare
  Cc: netdev, magnus.karlsson, stfomichev, kernelxing, davem, kuba,
	pabeni, ast, daniel, tirthendu.sarkar, bpf

On Wed, Jun 03, 2026 at 11:33:24AM +0530, Tushar Vyavahare wrote:
> UMEM properties are set via open-coded field assignments in multiple test
> paths, which makes updates noisy and error-prone.
> 
> Introduce two helpers to set UMEM properties through a single interface.
> This keeps setup logic consistent across tests and makes future refactoring
> simpler.
> 
> No functional behavior change is intended.
> 
> Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>

Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>

> ---
>  .../selftests/bpf/prog_tests/test_xsk.c       | 36 ++++++++++---------
>  1 file changed, 20 insertions(+), 16 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> index 7950c504ed28..3369450da974 100644
> --- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> +++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> @@ -303,6 +303,18 @@ static void test_spec_reset(struct test_spec *test)
>  	__test_spec_init(test, test->ifobj_tx, test->ifobj_rx);
>  }
>  
> +static void test_spec_set_unaligned(struct test_spec *test)
> +{
> +	test->ifobj_tx->umem->unaligned_mode = true;
> +	test->ifobj_rx->umem->unaligned_mode = true;
> +}
> +
> +static void test_spec_set_frame_size(struct test_spec *test, u32 size)
> +{
> +	test->ifobj_tx->umem->frame_size = size;
> +	test->ifobj_rx->umem->frame_size = size;
> +}
> +
>  static void test_spec_set_xdp_prog(struct test_spec *test, struct bpf_program *xdp_prog_rx,
>  				   struct bpf_program *xdp_prog_tx, struct bpf_map *xskmap_rx,
>  				   struct bpf_map *xskmap_tx)
> @@ -2025,8 +2037,7 @@ int testapp_stats_fill_empty(struct test_spec *test)
>  
>  int testapp_send_receive_unaligned(struct test_spec *test)
>  {
> -	test->ifobj_tx->umem->unaligned_mode = true;
> -	test->ifobj_rx->umem->unaligned_mode = true;
> +	test_spec_set_unaligned(test);
>  	/* Let half of the packets straddle a 4K buffer boundary */
>  	if (pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2))
>  		return TEST_FAILURE;
> @@ -2037,8 +2048,7 @@ int testapp_send_receive_unaligned(struct test_spec *test)
>  int testapp_send_receive_unaligned_mb(struct test_spec *test)
>  {
>  	test->mtu = MAX_ETH_JUMBO_SIZE;
> -	test->ifobj_tx->umem->unaligned_mode = true;
> -	test->ifobj_rx->umem->unaligned_mode = true;
> +	test_spec_set_unaligned(test);
>  	if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MAX_ETH_JUMBO_SIZE))
>  		return TEST_FAILURE;
>  	return testapp_validate_traffic(test);
> @@ -2337,8 +2347,7 @@ int testapp_send_receive(struct test_spec *test)
>  
>  int testapp_send_receive_2k_frame(struct test_spec *test)
>  {
> -	test->ifobj_tx->umem->frame_size = 2048;
> -	test->ifobj_rx->umem->frame_size = 2048;
> +	test_spec_set_frame_size(test, 2048);
>  	if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE))
>  		return TEST_FAILURE;
>  	return testapp_validate_traffic(test);
> @@ -2363,15 +2372,13 @@ int testapp_aligned_inv_desc(struct test_spec *test)
>  
>  int testapp_aligned_inv_desc_2k_frame(struct test_spec *test)
>  {
> -	test->ifobj_tx->umem->frame_size = 2048;
> -	test->ifobj_rx->umem->frame_size = 2048;
> +	test_spec_set_frame_size(test, 2048);
>  	return testapp_invalid_desc(test);
>  }
>  
>  int testapp_unaligned_inv_desc(struct test_spec *test)
>  {
> -	test->ifobj_tx->umem->unaligned_mode = true;
> -	test->ifobj_rx->umem->unaligned_mode = true;
> +	test_spec_set_unaligned(test);
>  	return testapp_invalid_desc(test);
>  }
>  
> @@ -2380,10 +2387,8 @@ int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test)
>  	u64 page_size, umem_size;
>  
>  	/* Odd frame size so the UMEM doesn't end near a page boundary. */
> -	test->ifobj_tx->umem->frame_size = 4001;
> -	test->ifobj_rx->umem->frame_size = 4001;
> -	test->ifobj_tx->umem->unaligned_mode = true;
> -	test->ifobj_rx->umem->unaligned_mode = true;
> +	test_spec_set_frame_size(test, 4001);
> +	test_spec_set_unaligned(test);
>  	/* This test exists to test descriptors that staddle the end of
>  	 * the UMEM but not a page.
>  	 */
> @@ -2402,8 +2407,7 @@ int testapp_aligned_inv_desc_mb(struct test_spec *test)
>  
>  int testapp_unaligned_inv_desc_mb(struct test_spec *test)
>  {
> -	test->ifobj_tx->umem->unaligned_mode = true;
> -	test->ifobj_rx->umem->unaligned_mode = true;
> +	test_spec_set_unaligned(test);
>  	return testapp_invalid_desc_mb(test);
>  }
>  
> -- 
> 2.43.0
> 

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

* Re: [PATCH net-next v2 3/4] selftests/xsk: Use umem_size() helper consistently
  2026-06-03  6:03 ` [PATCH net-next v2 3/4] selftests/xsk: Use umem_size() helper consistently Tushar Vyavahare
@ 2026-06-03 15:34   ` Maciej Fijalkowski
  0 siblings, 0 replies; 9+ messages in thread
From: Maciej Fijalkowski @ 2026-06-03 15:34 UTC (permalink / raw)
  To: Tushar Vyavahare
  Cc: netdev, magnus.karlsson, stfomichev, kernelxing, davem, kuba,
	pabeni, ast, daniel, tirthendu.sarkar, bpf

On Wed, Jun 03, 2026 at 11:33:26AM +0530, Tushar Vyavahare wrote:
> Replace remaining open-coded umem->num_frames * umem->frame_size
> calculations in test_xsk.c with the existing umem_size() helper.
> 
> This keeps UMEM size computation centralized, avoids duplicated arithmetic,
> and improves readability with no intended behavior change.
> 
> Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>

Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>

> ---
>  .../selftests/bpf/prog_tests/test_xsk.c       | 36 +++++++++----------
>  1 file changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> index 7e0d34111b2f..f1730466ffd9 100644
> --- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> +++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> @@ -829,11 +829,11 @@ static bool is_frag_valid(struct xsk_umem_info *umem, u64 addr, u32 len, u32 exp
>  {
>  	u32 seqnum, pkt_nb, *pkt_data, words_to_end, expected_seqnum;
>  	void *data = xsk_umem__get_data(umem->buffer, addr);
> +	u64 umem_sz = umem_size(umem);
>  
>  	addr -= umem->base_addr;
>  
> -	if (addr >= umem->num_frames * umem->frame_size ||
> -	    addr + len > umem->num_frames * umem->frame_size) {
> +	if (addr >= umem_sz || addr + len > umem_sz) {
>  		ksft_print_msg("Frag invalid addr: %llx len: %u\n",
>  			       (unsigned long long)addr, len);
>  		return false;
> @@ -1586,7 +1586,7 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
>  	int ret;
>  	u32 i;
>  
> -	umem_sz = umem->num_frames * umem->frame_size;
> +	umem_sz = umem_size(umem);
>  	mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
>  
>  	if (umem->unaligned_mode)
> @@ -1706,12 +1706,13 @@ void *worker_testapp_validate_rx(void *arg)
>  static void testapp_clean_xsk_umem(struct ifobject *ifobj)
>  {
>  	struct xsk_umem_info *umem = ifobj->xsk->umem;
> -	u64 umem_sz = umem->num_frames * umem->frame_size;
> +	u64 umem_sz = umem_size(umem);
>  
>  	if (ifobj->shared_umem)
>  		umem_sz *= 2;
>  
>  	umem_sz = ceil_u64(umem_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
> +
>  	xsk_umem__delete(umem->umem);
>  	munmap(umem->buffer, umem_sz);
>  }
> @@ -2097,7 +2098,7 @@ int testapp_send_receive_mb(struct test_spec *test)
>  int testapp_invalid_desc_mb(struct test_spec *test)
>  {
>  	struct xsk_umem_info *umem = test->ifobj_tx->xsk->umem;
> -	u64 umem_size = umem->num_frames * umem->frame_size;
> +	u64 umem_sz = umem_size(umem);
>  	struct pkt pkts[] = {
>  		/* Valid packet for synch to start with */
>  		{0, MIN_PKT_SIZE, 0, true, 0},
> @@ -2107,7 +2108,7 @@ int testapp_invalid_desc_mb(struct test_spec *test)
>  		{0, 0, 0, false, 0},
>  		/* Invalid address in the second frame */
>  		{0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
> -		{umem_size, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
> +		{umem_sz, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
>  		/* Invalid len in the middle */
>  		{0, XSK_UMEM__LARGE_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
>  		{0, XSK_UMEM__INVALID_FRAME_SIZE, 0, false, XDP_PKT_CONTD},
> @@ -2138,7 +2139,7 @@ int testapp_invalid_desc_mb(struct test_spec *test)
>  int testapp_invalid_desc(struct test_spec *test)
>  {
>  	struct xsk_umem_info *umem = test->ifobj_tx->xsk->umem;
> -	u64 umem_size = umem->num_frames * umem->frame_size;
> +	u64 umem_sz = umem_size(umem);
>  	struct pkt pkts[] = {
>  		/* Zero packet address allowed */
>  		{0, MIN_PKT_SIZE, 0, true},
> @@ -2149,11 +2150,11 @@ int testapp_invalid_desc(struct test_spec *test)
>  		/* Packet too large */
>  		{0, XSK_UMEM__INVALID_FRAME_SIZE, 0, false},
>  		/* Up to end of umem allowed */
> -		{umem_size - MIN_PKT_SIZE - 2 * umem->frame_size, MIN_PKT_SIZE, 0, true},
> +		{umem_sz - MIN_PKT_SIZE - 2 * umem->frame_size, MIN_PKT_SIZE, 0, true},
>  		/* After umem ends */
> -		{umem_size, MIN_PKT_SIZE, 0, false},
> +		{umem_sz, MIN_PKT_SIZE, 0, false},
>  		/* Straddle the end of umem */
> -		{umem_size - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false},
> +		{umem_sz - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false},
>  		/* Straddle a 4K boundary */
>  		{0x1000 - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false},
>  		/* Straddle a 2K boundary */
> @@ -2171,9 +2172,9 @@ int testapp_invalid_desc(struct test_spec *test)
>  	}
>  
>  	if (test->ifobj_tx->shared_umem) {
> -		pkts[4].offset += umem_size;
> -		pkts[5].offset += umem_size;
> -		pkts[6].offset += umem_size;
> +		pkts[4].offset += umem_sz;
> +		pkts[5].offset += umem_sz;
> +		pkts[6].offset += umem_sz;
>  	}
>  
>  	if (pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts)))
> @@ -2406,7 +2407,7 @@ int testapp_unaligned_inv_desc(struct test_spec *test)
>  
>  int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test)
>  {
> -	u64 page_size, umem_size;
> +	u64 page_size, umem_sz;
>  
>  	/* Odd frame size so the UMEM doesn't end near a page boundary. */
>  	test_spec_set_frame_size(test, 4001);
> @@ -2415,10 +2416,9 @@ int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test)
>  	 * the UMEM but not a page.
>  	 */
>  	page_size = sysconf(_SC_PAGESIZE);
> -	umem_size = test->ifobj_tx->xsk->umem->num_frames *
> -		test->ifobj_tx->xsk->umem->frame_size;
> -	assert(umem_size % page_size > MIN_PKT_SIZE);
> -	assert(umem_size % page_size < page_size - MIN_PKT_SIZE);
> +	umem_sz = umem_size(test->ifobj_tx->xsk->umem);
> +	assert(umem_sz % page_size > MIN_PKT_SIZE);
> +	assert(umem_sz % page_size < page_size - MIN_PKT_SIZE);
>  
>  	return testapp_invalid_desc(test);
>  }
> -- 
> 2.43.0
> 

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

* Re: [PATCH net-next v2 4/4] selftests/xsk: Introduce mmap_size in umem struct
  2026-06-03  6:03 ` [PATCH net-next v2 4/4] selftests/xsk: Introduce mmap_size in umem struct Tushar Vyavahare
@ 2026-06-03 15:35   ` Maciej Fijalkowski
  0 siblings, 0 replies; 9+ messages in thread
From: Maciej Fijalkowski @ 2026-06-03 15:35 UTC (permalink / raw)
  To: Tushar Vyavahare
  Cc: netdev, magnus.karlsson, stfomichev, kernelxing, davem, kuba,
	pabeni, ast, daniel, tirthendu.sarkar, bpf

On Wed, Jun 03, 2026 at 11:33:27AM +0530, Tushar Vyavahare wrote:
> UMEM teardown currently recomputes the munmap() length from frame
> geometry, shared-UMEM adjustment, and hugepage rounding. This duplicates
> setup-time logic in cleanup and relies on re-deriving the mapping size
> instead of using the size originally established for the mapping.
> 
> Store the final mapping length in xsk_umem_info as mmap_size when the
> UMEM mapping is created, and use that value during teardown.
> 
> Also join the RX worker thread before cleanup in the single-thread
> path. This establishes synchronization before reading umem->mmap_size
> in teardown and avoids a potential visibility race.
> 
> This removes duplicated size arithmetic in cleanup and makes munmap()
> use the canonical mapping size recorded at setup time.
> 
> Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>

Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>

> ---
>  .../selftests/bpf/prog_tests/test_xsk.c       | 20 +++++++++----------
>  .../selftests/bpf/prog_tests/test_xsk.h       |  1 +
>  2 files changed, 10 insertions(+), 11 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> index f1730466ffd9..e94c38a1faf4 100644
> --- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> +++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
> @@ -1581,7 +1581,7 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
>  	struct xsk_umem_info *umem = ifobject->xsk->umem;
>  	LIBBPF_OPTS(bpf_xdp_query_opts, opts);
>  	int mmap_flags;
> -	u64 umem_sz;
> +	u64 umem_sz, mmap_sz;
>  	void *bufs;
>  	int ret;
>  	u32 i;
> @@ -1595,10 +1595,15 @@ static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
>  	if (ifobject->shared_umem)
>  		umem_sz *= 2;
>  
> -	bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
> +	mmap_sz = umem->unaligned_mode ?
> +		ceil_u64(umem_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE : umem_sz;
> +
> +	bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
>  	if (bufs == MAP_FAILED)
>  		return -errno;
>  
> +	umem->mmap_size = mmap_sz;
> +
>  	ret = xsk_configure_umem(ifobject, umem, bufs, umem_sz);
>  	if (ret)
>  		return ret;
> @@ -1706,15 +1711,9 @@ void *worker_testapp_validate_rx(void *arg)
>  static void testapp_clean_xsk_umem(struct ifobject *ifobj)
>  {
>  	struct xsk_umem_info *umem = ifobj->xsk->umem;
> -	u64 umem_sz = umem_size(umem);
> -
> -	if (ifobj->shared_umem)
> -		umem_sz *= 2;
> -
> -	umem_sz = ceil_u64(umem_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
>  
>  	xsk_umem__delete(umem->umem);
> -	munmap(umem->buffer, umem_sz);
> +	munmap(umem->buffer, umem->mmap_size);
>  }
>  
>  static void handler(int signum)
> @@ -1857,8 +1856,7 @@ static int __testapp_validate_traffic(struct test_spec *test, struct ifobject *i
>  
>  	if (!ifobj2)
>  		pthread_kill(t0, SIGUSR1);
> -	else
> -		pthread_join(t0, NULL);
> +	pthread_join(t0, NULL);
>  
>  	if (test->total_steps == test->current_step || test->fail) {
>  		clean_sockets(test, ifobj1);
> diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.h b/tools/testing/selftests/bpf/prog_tests/test_xsk.h
> index 99003995d7c3..4313d0d87235 100644
> --- a/tools/testing/selftests/bpf/prog_tests/test_xsk.h
> +++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.h
> @@ -103,6 +103,7 @@ struct xsk_umem_info {
>  	struct xsk_ring_cons cq;
>  	struct xsk_umem *umem;
>  	u64 next_buffer;
> +	u64 mmap_size;
>  	u32 num_frames;
>  	u32 frame_headroom;
>  	void *buffer;
> -- 
> 2.43.0
> 

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

end of thread, other threads:[~2026-06-03 15:35 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-03  6:03 [PATCH net-next v2 0/4] selftests/xsk: simplify UMEM setup Tushar Vyavahare
2026-06-03  6:03 ` [PATCH net-next v2 1/4] selftests/xsk: Introduce helpers for setting UMEM properties Tushar Vyavahare
2026-06-03 14:52   ` Maciej Fijalkowski
2026-06-03  6:03 ` [PATCH net-next v2 2/4] selftests/xsk: Move UMEM state from ifobject to xsk_socket_info Tushar Vyavahare
2026-06-03 14:51   ` Maciej Fijalkowski
2026-06-03  6:03 ` [PATCH net-next v2 3/4] selftests/xsk: Use umem_size() helper consistently Tushar Vyavahare
2026-06-03 15:34   ` Maciej Fijalkowski
2026-06-03  6:03 ` [PATCH net-next v2 4/4] selftests/xsk: Introduce mmap_size in umem struct Tushar Vyavahare
2026-06-03 15:35   ` Maciej Fijalkowski

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