BPF List
 help / color / mirror / Atom feed
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
To: netdev@vger.kernel.org
Cc: bpf@vger.kernel.org, magnus.karlsson@intel.com,
	stfomichev@gmail.com, kuba@kernel.org, pabeni@redhat.com,
	tushar.vyavahare@intel.com, kerneljasonxing@gmail.com,
	bjorn@kernel.org,
	Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Subject: [PATCH net-next 08/13] selftests: xsk: run one test case per xskxceiver invocation
Date: Thu,  1 Oct 2026 22:21:19 +0200	[thread overview]
Message-ID: <20261001202124.692591-9-maciej.fijalkowski@intel.com> (raw)
In-Reply-To: <20261001202124.692591-1-maciej.fijalkowski@intel.com>

Make test_xsk.sh own the mode x case matrix and run xskxceiver once per
case, so that every case starts from a fresh process and a case that
crashes fails only itself. A single case is also the unit that the next
patch splits into separate RX and TX endpoint processes.

xskxceiver now requires -m and -t and runs exactly that case. It
reports one KTAP result and exits with its verdict. An unsupported mode
skips the case instead of exiting with XFAIL.

test_xsk.sh runs every case in the skb and drv modes, or in the one
given with -m, in both the softirq and the busy-poll pass, and prints a
summary of the passed, skipped and failed cases. -t also accepts a test
name, which is resolved through xskxceiver -l. Only skb and drv modes
are accepted, as veth has no zero-copy support, and the script skips
when xskxceiver was not built. As ARGS is now rebuilt for every case,
exec_xskxceiver() adds -b to a local copy of it.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
 .../selftests/net/lib/xsk/xskxceiver.c        |  52 ++++-----
 tools/testing/selftests/net/test_xsk.sh       | 102 ++++++++++++++----
 tools/testing/selftests/net/xsk_prereqs.sh    |   6 +-
 3 files changed, 103 insertions(+), 57 deletions(-)

diff --git a/tools/testing/selftests/net/lib/xsk/xskxceiver.c b/tools/testing/selftests/net/lib/xsk/xskxceiver.c
index afd6b242aa0d..b8a52846eaf8 100644
--- a/tools/testing/selftests/net/lib/xsk/xskxceiver.c
+++ b/tools/testing/selftests/net/lib/xsk/xskxceiver.c
@@ -169,7 +169,7 @@ static struct option long_options[] = {
 static void print_usage(char **argv)
 {
 	const char *str =
-		"  Usage: xskxceiver [OPTIONS]\n"
+		"  Usage: xskxceiver -i TX_IFACE -i RX_IFACE -m MODE -t TEST [OPTIONS]\n"
 		"  Options:\n"
 		"  -i, --interface      Use interface\n"
 		"  -v, --verbose        Verbose output\n"
@@ -267,6 +267,9 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj
 		}
 	}
 
+	if (opt_run_test == RUN_ALL_TESTS || opt_mode == TEST_MODE_ALL)
+		print_usage(argv);
+
 	bind_iface(ifobj_tx, ifname[0], worker_testapp_validate_tx, argv);
 	bind_iface(ifobj_rx, ifname[1], worker_testapp_validate_rx, argv);
 }
@@ -368,10 +371,9 @@ int main(int argc, char **argv)
 	u32 cache_line_size, max_frags, umem_tailroom;
 	const size_t total_tests = ARRAY_SIZE(tests);
 	struct ifobject *ifobj_tx, *ifobj_rx;
-	u32 i, j, failed_tests = 0, nb_tests;
 	struct test_spec test = {};
 	int ret = TEST_FAILURE;
-	u32 caps, modes = 0;
+	u32 caps;
 
 	/* Use libbpf 1.0 API mode */
 	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
@@ -420,42 +422,20 @@ int main(int argc, char **argv)
 
 	caps = detect_mode_caps(ifobj_tx);
 
-	if (opt_mode != TEST_MODE_ALL && !mode_supported(opt_mode, caps)) {
+	if (!mode_supported(opt_mode, caps)) {
 		if (opt_mode == TEST_MODE_DRV)
-			ksft_print_msg("Error: XDP_DRV mode not supported.\n");
+			ksft_print_msg("XDP_DRV mode not supported.\n");
 		else
-			ksft_print_msg("Error: zero-copy mode not supported.\n");
-		ksft_exit_xfail();
+			ksft_print_msg("zero-copy mode not supported.\n");
+		ret = TEST_SKIP;
+		goto out;
 	}
 
-	for (i = TEST_MODE_SKB; i <= TEST_MODE_ZC; i++)
-		if ((opt_mode == TEST_MODE_ALL || i == opt_mode) && mode_supported(i, caps))
-			modes++;
-	if (opt_run_test == RUN_ALL_TESTS)
-		nb_tests = total_tests;
-	else
-		nb_tests = 1;
 	/* Line-buffer stdout so verdicts reach a capturing launcher live. */
 	ksft_print_header();
-	ksft_set_plan(modes * nb_tests);
-
-	for (i = TEST_MODE_SKB; i <= TEST_MODE_ZC; i++) {
-		if (opt_mode != TEST_MODE_ALL && i != opt_mode)
-			continue;
-		if (!mode_supported(i, caps))
-			continue;
-
-		for (j = 0; j < total_tests; j++) {
-			if (opt_run_test != RUN_ALL_TESTS && j != opt_run_test)
-				continue;
-
-			test_init(&test, ifobj_tx, ifobj_rx, i, &tests[j]);
-			if (run_pkt_test(&test) == TEST_FAILURE)
-				failed_tests++;
-			usleep(USLEEP_MAX);
-		}
-	}
-	ret = failed_tests ? TEST_FAILURE : TEST_PASS;
+	ksft_set_plan(1);
+	test_init(&test, ifobj_tx, ifobj_rx, opt_mode, &tests[opt_run_test]);
+	ret = run_pkt_test(&test);
 
 out:
 	cleanup_iface(ifobj_tx);
@@ -465,6 +445,12 @@ int main(int argc, char **argv)
 	ifobject_delete(ifobj_tx);
 	ifobject_delete(ifobj_rx);
 
+	if (ret == TEST_SKIP && ksft_test_num()) {
+		ksft_print_cnts();
+		return KSFT_SKIP;
+	}
+	if (ret == TEST_SKIP)
+		ksft_exit_skip("mode not supported\n");
 	if (ret)
 		ksft_exit_fail();
 	else
diff --git a/tools/testing/selftests/net/test_xsk.sh b/tools/testing/selftests/net/test_xsk.sh
index 69fac65f073c..e476556eb05b 100755
--- a/tools/testing/selftests/net/test_xsk.sh
+++ b/tools/testing/selftests/net/test_xsk.sh
@@ -71,7 +71,7 @@
 # Set up veth interfaces and leave them up so xskxceiver can be launched in a debugger:
 #   sudo ./test_xsk.sh -d
 #
-# Run test suite in a specific mode only [skb,drv,zc]
+# Run test suite in a specific mode only [skb,drv]
 #   sudo ./test_xsk.sh -m MODE
 #
 # List available tests
@@ -85,6 +85,11 @@
 
 . xsk_prereqs.sh
 
+if [ ! -x "./${XSKOBJ}" ]; then
+	echo "xskxceiver was not built; skipping"
+	exit $ksft_skip
+fi
+
 while getopts "vdm:lt:h" flag
 do
 	case "${flag}" in
@@ -151,6 +156,31 @@ if [[ $help -eq 1 ]]; then
         exit
 fi
 
+if [ -n "$MODE" ]; then
+	case "$MODE" in
+		skb|drv) MODES=("$MODE");;
+		*) echo "Unsupported veth mode: $MODE (expected skb or drv)" >&2
+		   exit 1;;
+	esac
+else
+	MODES=(skb drv)
+fi
+
+if [ -n "$TEST" ]; then
+	if [[ "$TEST" =~ ^[0-9]+$ ]]; then
+		CASES=("$TEST")
+	else
+		mapfile -t CASES < <(./${XSKOBJ} -l |
+			awk -F ': ' -v name="$TEST" '$2 == name {print $1}')
+	fi
+else
+	mapfile -t CASES < <(./${XSKOBJ} -l | awk -F ': ' '/^[0-9]+: / {print $1}')
+fi
+if [ ${#CASES[@]} -eq 0 ]; then
+	echo "Unknown AF_XDP test: $TEST" >&2
+	exit 1
+fi
+
 validate_root_exec
 validate_veth_support ${VETH0}
 validate_ip_utility
@@ -168,29 +198,38 @@ if [[ $verbose -eq 1 ]]; then
 	ARGS+="-v "
 fi
 
-if [ -n "$MODE" ]; then
-	ARGS+="-m ${MODE} "
-fi
-
-if [ -n "$TEST" ]; then
-	ARGS+="-t ${TEST} "
-fi
-
 retval=$?
 test_status $retval "${TEST_NAME}"
 
 ## START TESTS
 
 statusList=()
+nameList=()
+
+run_matrix()
+{
+	local mode case_id
+
+	for mode in "${MODES[@]}"; do
+		for case_id in "${CASES[@]}"; do
+			ARGS="${BASE_ARGS} -m ${mode} -t ${case_id}"
+			TEST_NAME="XSK_${mode}_${case_id}_${RUN_VARIANT}_${VETH0}"
+			exec_xskxceiver
+		done
+	done
+}
+
+BASE_ARGS="${ARGS}"
 
-TEST_NAME="XSK_SELFTESTS_${VETH0}_SOFTIRQ"
+RUN_VARIANT=SOFTIRQ
 
 if [[ $debug -eq 1 ]]; then
-    echo "-i" ${VETH0} "-i" ${VETH1}
+    ARGS="${BASE_ARGS} -m ${MODES[0]} -t ${CASES[0]}"
+    echo "./${XSKOBJ} -i ${VETH0} -i ${VETH1} ${ARGS}"
     exit
 fi
 
-exec_xskxceiver
+run_matrix
 
 cleanup_exit ${VETH0} ${VETH1}
 
@@ -198,28 +237,47 @@ if [[ $list -eq 1 ]]; then
     exit
 fi
 
-TEST_NAME="XSK_SELFTESTS_${VETH0}_BUSY_POLL"
+RUN_VARIANT=BUSY_POLL
 busy_poll=1
 
 setup_vethPairs
-exec_xskxceiver
+run_matrix
 
 ## END TESTS
 
 cleanup_exit ${VETH0} ${VETH1}
 
+passes=0
+skips=0
 failures=0
-echo -e "\nSummary:"
+failed_tests=()
 for i in "${!statusList[@]}"
 do
-	if [ ${statusList[$i]} -ne 0 ]; then
-	        test_status ${statusList[$i]} ${nameList[$i]}
-		failures=1
-	fi
+	case ${statusList[$i]} in
+		$ksft_pass)
+			passes=$((passes + 1))
+			;;
+		$ksft_skip)
+			skips=$((skips + 1))
+			;;
+		*)
+			failures=$((failures + 1))
+			failed_tests+=("${nameList[$i]}")
+			;;
+	esac
 done
 
-if [ $failures -eq 0 ]; then
-        echo "All tests successful!"
-else
+echo
+echo "Summary:"
+printf "  Tests:   %d\n" "${#statusList[@]}"
+printf "  Passed:  %d\n" "$passes"
+printf "  Skipped: %d\n" "$skips"
+printf "  Failed:  %d\n" "$failures"
+
+if [ $failures -ne 0 ]; then
+	echo "Failed tests:"
+	for TEST_NAME in "${failed_tests[@]}"; do
+		echo "  $TEST_NAME"
+	done
 	exit 1
 fi
diff --git a/tools/testing/selftests/net/xsk_prereqs.sh b/tools/testing/selftests/net/xsk_prereqs.sh
index 5e5c8ef3fff2..30173db12c56 100755
--- a/tools/testing/selftests/net/xsk_prereqs.sh
+++ b/tools/testing/selftests/net/xsk_prereqs.sh
@@ -71,11 +71,13 @@ validate_ip_utility()
 
 exec_xskxceiver()
 {
+	local run_args="${ARGS}"
+
         if [[ $busy_poll -eq 1 ]]; then
-	        ARGS+="-b "
+		run_args+=" -b"
 	fi
 
-	./${XSKOBJ} -i ${VETH0} -i ${VETH1} ${ARGS}
+	./${XSKOBJ} -i ${VETH0} -i ${VETH1} ${run_args}
 	retval=$?
 
 	if [[ $list -ne 1 ]]; then
-- 
2.43.0


  parent reply	other threads:[~2026-10-01 20:22 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01 20:21 [PATCH net-next 00/13] selftests: net: migrate AF_XDP test suite over to net Maciej Fijalkowski
2026-10-01 20:21 ` [PATCH net-next 01/13] selftests: xsk: factor endpoint work out of pthread wrappers Maciej Fijalkowski
2026-10-01 20:21 ` [PATCH net-next 02/13] selftests: xsk: drop the single-interface loopback mode Maciej Fijalkowski
2026-10-01 20:21 ` [PATCH net-next 03/13] selftests/bpf: drop the test_progs AF_XDP wrapper Maciej Fijalkowski
2026-10-01 20:21 ` [PATCH net-next 04/13] selftests: net: add a generic rule for BPF skeletons Maciej Fijalkowski
2026-10-03  1:33   ` sashiko-bot
2026-10-01 20:21 ` [PATCH net-next 05/13] selftests: xsk: move the AF_XDP test suite to selftests/net Maciej Fijalkowski
2026-10-01 20:21 ` [PATCH net-next 06/13] selftests: xsk: collect interface capabilities in struct xsk_caps Maciej Fijalkowski
2026-10-01 20:21 ` [PATCH net-next 07/13] selftests: xsk: split xskxceiver main() into setup, run and cleanup Maciej Fijalkowski
2026-10-01 20:21 ` Maciej Fijalkowski [this message]
2026-10-01 20:21 ` [PATCH net-next 09/13] selftests: xsk: run the RX and TX endpoints in separate processes Maciej Fijalkowski
2026-10-02 18:07   ` Vyavahare, Tushar
2026-10-03  1:33   ` sashiko-bot
2026-10-01 20:21 ` [PATCH net-next 10/13] selftests: xsk: add a hardware mode to xskxceiver Maciej Fijalkowski
2026-10-03  1:33   ` sashiko-bot
2026-10-01 20:21 ` [PATCH net-next 11/13] selftests: xsk: share test case definitions with hardware runner Maciej Fijalkowski
2026-10-01 20:21 ` [PATCH net-next 12/13] selftests: drv-net: test AF_XDP zero-copy with an SKB peer Maciej Fijalkowski
2026-10-01 20:21 ` [PATCH net-next 13/13] selftests: xsk: document generic and hardware endpoint runs Maciej Fijalkowski
2026-10-05 18:06 ` [PATCH net-next 00/13] selftests: net: migrate AF_XDP test suite over to net Stanislav Fomichev
2026-10-06 17:42   ` Maciej Fijalkowski
2026-10-06 22:04     ` Stanislav Fomichev
2026-10-07 12:22       ` Maciej Fijalkowski
2026-10-07 17:26         ` Stanislav Fomichev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261001202124.692591-9-maciej.fijalkowski@intel.com \
    --to=maciej.fijalkowski@intel.com \
    --cc=bjorn@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=kerneljasonxing@gmail.com \
    --cc=kuba@kernel.org \
    --cc=magnus.karlsson@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=stfomichev@gmail.com \
    --cc=tushar.vyavahare@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox