diff mbox series

[bpf-next,v2,07/10] selftests/xsx: test for huge pages only once

Message ID 20230516103109.3066-8-magnus.karlsson@gmail.com (mailing list archive)
State Accepted
Commit 041b68f688a38865434d7b8fbfe64beb03e54ff2
Delegated to: BPF
Headers show
Series seltests/xsk: prepare for AF_XDP multi-buffer testing | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/cc_maintainers warning 7 maintainers not CCed: kuba@kernel.org hawk@kernel.org shuah@kernel.org mykolal@fb.com davem@davemloft.net linux-kselftest@vger.kernel.org jonathan.lemon@gmail.com
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch warning WARNING: line length of 81 exceeds 80 columns WARNING: line length of 83 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_no_alu32_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_progs_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-29 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-30 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-31 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-32 success Logs for test_verifier on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-34 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-35 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-36 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32 on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-15 fail Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-33 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-20 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on s390x with gcc
bpf/vmtest-bpf-next-PR fail PR summary
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ${{ matrix.test }} on ${{ matrix.arch }} with ${{ matrix.toolchain_full }}
bpf/vmtest-bpf-next-VM_Test-2 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 fail Logs for build for aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-8 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-9 success Logs for veristat

Commit Message

Magnus Karlsson May 16, 2023, 10:31 a.m. UTC
From: Magnus Karlsson <magnus.karlsson@intel.com>

Test for hugepages only once at the beginning of the execution of the
whole test suite, instead of before each test that needs huge
pages. These are the tests that use unaligned mode. As more unaligned
tests will be added, so the current system just does not scale.

With this change, there are now three possible outcomes of a test run:
fail, pass, or skip. To simplify the handling of this, the function
testapp_validate_traffic() now returns this value to the main loop. As
this function is used by nearly all tests, it meant a small change to
most of them.

Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
---
 tools/testing/selftests/bpf/xskxceiver.c | 186 +++++++++++------------
 tools/testing/selftests/bpf/xskxceiver.h |   2 +
 2 files changed, 94 insertions(+), 94 deletions(-)

Comments

Fijalkowski, Maciej May 16, 2023, 12:58 p.m. UTC | #1
On Tue, May 16, 2023 at 12:31:06PM +0200, Magnus Karlsson wrote:
> From: Magnus Karlsson <magnus.karlsson@intel.com>
> 
> Test for hugepages only once at the beginning of the execution of the
> whole test suite, instead of before each test that needs huge
> pages. These are the tests that use unaligned mode. As more unaligned
> tests will be added, so the current system just does not scale.
> 
> With this change, there are now three possible outcomes of a test run:
> fail, pass, or skip. To simplify the handling of this, the function
> testapp_validate_traffic() now returns this value to the main loop. As
> this function is used by nearly all tests, it meant a small change to
> most of them.

I don't get the need for that change. Why couldn't we just store the
retval to test_spec and then check it in run_pkt_test() just like we check
test->fail currently? Am i missing something?

> 
> Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> ---
>  tools/testing/selftests/bpf/xskxceiver.c | 186 +++++++++++------------
>  tools/testing/selftests/bpf/xskxceiver.h |   2 +
>  2 files changed, 94 insertions(+), 94 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
> index d488d859d3a2..f0d929cb730a 100644
> --- a/tools/testing/selftests/bpf/xskxceiver.c
> +++ b/tools/testing/selftests/bpf/xskxceiver.c
> @@ -1413,6 +1413,12 @@ static int testapp_validate_traffic(struct test_spec *test)
>  	struct ifobject *ifobj_rx = test->ifobj_rx;
>  	struct ifobject *ifobj_tx = test->ifobj_tx;
>  
> +	if ((ifobj_rx->umem->unaligned_mode && !ifobj_rx->unaligned_supp) ||
> +	    (ifobj_tx->umem->unaligned_mode && !ifobj_tx->unaligned_supp)) {
> +		ksft_test_result_skip("No huge pages present.\n");
> +		return TEST_SKIP;
> +	}
> +
>  	xsk_attach_xdp_progs(test, ifobj_rx, ifobj_tx);
>  	return __testapp_validate_traffic(test, ifobj_rx, ifobj_tx);
>  }
> @@ -1422,16 +1428,18 @@ static int testapp_validate_traffic_single_thread(struct test_spec *test, struct
>  	return __testapp_validate_traffic(test, ifobj, NULL);
>  }
>  
> -static void testapp_teardown(struct test_spec *test)
> +static int testapp_teardown(struct test_spec *test)
>  {
>  	int i;
>  
>  	test_spec_set_name(test, "TEARDOWN");
>  	for (i = 0; i < MAX_TEARDOWN_ITER; i++) {
>  		if (testapp_validate_traffic(test))
> -			return;
> +			return TEST_FAILURE;
>  		test_spec_reset(test);
>  	}
> +
> +	return TEST_PASS;
>  }
>  
>  static void swap_directions(struct ifobject **ifobj1, struct ifobject **ifobj2)
> @@ -1446,20 +1454,23 @@ static void swap_directions(struct ifobject **ifobj1, struct ifobject **ifobj2)
>  	*ifobj2 = tmp_ifobj;
>  }
>  
> -static void testapp_bidi(struct test_spec *test)
> +static int testapp_bidi(struct test_spec *test)
>  {
> +	int res;
> +
>  	test_spec_set_name(test, "BIDIRECTIONAL");
>  	test->ifobj_tx->rx_on = true;
>  	test->ifobj_rx->tx_on = true;
>  	test->total_steps = 2;
>  	if (testapp_validate_traffic(test))
> -		return;
> +		return TEST_FAILURE;
>  
>  	print_verbose("Switching Tx/Rx vectors\n");
>  	swap_directions(&test->ifobj_rx, &test->ifobj_tx);
> -	__testapp_validate_traffic(test, test->ifobj_rx, test->ifobj_tx);
> +	res = __testapp_validate_traffic(test, test->ifobj_rx, test->ifobj_tx);
>  
>  	swap_directions(&test->ifobj_rx, &test->ifobj_tx);
> +	return res;
>  }
>  
>  static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj_rx)
> @@ -1476,115 +1487,94 @@ static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj
>  		exit_with_error(errno);
>  }
>  
> -static void testapp_bpf_res(struct test_spec *test)
> +static int testapp_bpf_res(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "BPF_RES");
>  	test->total_steps = 2;
>  	test->nb_sockets = 2;
>  	if (testapp_validate_traffic(test))
> -		return;
> +		return TEST_FAILURE;
>  
>  	swap_xsk_resources(test->ifobj_tx, test->ifobj_rx);
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_headroom(struct test_spec *test)
> +static int testapp_headroom(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "UMEM_HEADROOM");
>  	test->ifobj_rx->umem->frame_headroom = UMEM_HEADROOM_TEST_SIZE;
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_stats_rx_dropped(struct test_spec *test)
> +static int testapp_stats_rx_dropped(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "STAT_RX_DROPPED");
> +	if (test->mode == TEST_MODE_ZC) {
> +		ksft_test_result_skip("Can not run RX_DROPPED test for ZC mode\n");
> +		return TEST_SKIP;
> +	}
> +
>  	pkt_stream_replace_half(test, MIN_PKT_SIZE * 4, 0);
>  	test->ifobj_rx->umem->frame_headroom = test->ifobj_rx->umem->frame_size -
>  		XDP_PACKET_HEADROOM - MIN_PKT_SIZE * 3;
>  	pkt_stream_receive_half(test);
>  	test->ifobj_rx->validation_func = validate_rx_dropped;
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_stats_tx_invalid_descs(struct test_spec *test)
> +static int testapp_stats_tx_invalid_descs(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "STAT_TX_INVALID");
>  	pkt_stream_replace_half(test, XSK_UMEM__INVALID_FRAME_SIZE, 0);
>  	test->ifobj_tx->validation_func = validate_tx_invalid_descs;
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_stats_rx_full(struct test_spec *test)
> +static int testapp_stats_rx_full(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "STAT_RX_FULL");
>  	pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
>  	test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
>  							 DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
> -	if (!test->ifobj_rx->pkt_stream)
> -		exit_with_error(ENOMEM);
>  
>  	test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS;
>  	test->ifobj_rx->release_rx = false;
>  	test->ifobj_rx->validation_func = validate_rx_full;
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_stats_fill_empty(struct test_spec *test)
> +static int testapp_stats_fill_empty(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "STAT_RX_FILL_EMPTY");
>  	pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
>  	test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
>  							 DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
> -	if (!test->ifobj_rx->pkt_stream)
> -		exit_with_error(ENOMEM);
>  
>  	test->ifobj_rx->use_fill_ring = false;
>  	test->ifobj_rx->validation_func = validate_fill_empty;
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -/* Simple test */
> -static bool hugepages_present(struct ifobject *ifobject)
> +static int testapp_unaligned(struct test_spec *test)
>  {
> -	size_t mmap_sz = 2 * ifobject->umem->num_frames * ifobject->umem->frame_size;
> -	void *bufs;
> -
> -	bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
> -		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_HUGE_2MB, -1, 0);
> -	if (bufs == MAP_FAILED)
> -		return false;
> -
> -	mmap_sz = ceil_u64(mmap_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
> -	munmap(bufs, mmap_sz);
> -	return true;
> -}
> -
> -static bool testapp_unaligned(struct test_spec *test)
> -{
> -	if (!hugepages_present(test->ifobj_tx)) {
> -		ksft_test_result_skip("No 2M huge pages present.\n");
> -		return false;
> -	}
> -
>  	test_spec_set_name(test, "UNALIGNED_MODE");
>  	test->ifobj_tx->umem->unaligned_mode = true;
>  	test->ifobj_rx->umem->unaligned_mode = true;
>  	/* Let half of the packets straddle a 4K buffer boundary */
>  	pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2);
> -	testapp_validate_traffic(test);
>  
> -	return true;
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_single_pkt(struct test_spec *test)
> +static int testapp_single_pkt(struct test_spec *test)
>  {
>  	struct pkt pkts[] = {{0, MIN_PKT_SIZE, 0, true}};
>  
>  	pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_invalid_desc(struct test_spec *test)
> +static int testapp_invalid_desc(struct test_spec *test)
>  {
>  	struct xsk_umem_info *umem = test->ifobj_tx->umem;
>  	u64 umem_size = umem->num_frames * umem->frame_size;
> @@ -1626,10 +1616,10 @@ static void testapp_invalid_desc(struct test_spec *test)
>  	}
>  
>  	pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_xdp_drop(struct test_spec *test)
> +static int testapp_xdp_drop(struct test_spec *test)
>  {
>  	struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
>  	struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
> @@ -1639,10 +1629,10 @@ static void testapp_xdp_drop(struct test_spec *test)
>  			       skel_rx->maps.xsk, skel_tx->maps.xsk);
>  
>  	pkt_stream_receive_half(test);
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_xdp_metadata_count(struct test_spec *test)
> +static int testapp_xdp_metadata_count(struct test_spec *test)
>  {
>  	struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
>  	struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
> @@ -1663,10 +1653,10 @@ static void testapp_xdp_metadata_count(struct test_spec *test)
>  	if (bpf_map_update_elem(bpf_map__fd(data_map), &key, &count, BPF_ANY))
>  		exit_with_error(errno);
>  
> -	testapp_validate_traffic(test);
> +	return testapp_validate_traffic(test);
>  }
>  
> -static void testapp_poll_txq_tmout(struct test_spec *test)
> +static int testapp_poll_txq_tmout(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "POLL_TXQ_FULL");
>  
> @@ -1674,14 +1664,14 @@ static void testapp_poll_txq_tmout(struct test_spec *test)
>  	/* create invalid frame by set umem frame_size and pkt length equal to 2048 */
>  	test->ifobj_tx->umem->frame_size = 2048;
>  	pkt_stream_replace(test, 2 * DEFAULT_PKT_CNT, 2048);
> -	testapp_validate_traffic_single_thread(test, test->ifobj_tx);
> +	return testapp_validate_traffic_single_thread(test, test->ifobj_tx);
>  }
>  
> -static void testapp_poll_rxq_tmout(struct test_spec *test)
> +static int testapp_poll_rxq_tmout(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "POLL_RXQ_EMPTY");
>  	test->ifobj_rx->use_poll = true;
> -	testapp_validate_traffic_single_thread(test, test->ifobj_rx);
> +	return testapp_validate_traffic_single_thread(test, test->ifobj_rx);
>  }
>  
>  static int xsk_load_xdp_programs(struct ifobject *ifobj)
> @@ -1698,6 +1688,22 @@ static void xsk_unload_xdp_programs(struct ifobject *ifobj)
>  	xsk_xdp_progs__destroy(ifobj->xdp_progs);
>  }
>  
> +/* Simple test */
> +static bool hugepages_present(void)
> +{
> +	size_t mmap_sz = 2 * DEFAULT_UMEM_BUFFERS * XSK_UMEM__DEFAULT_FRAME_SIZE;
> +	void *bufs;
> +
> +	bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
> +		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, MAP_HUGE_2MB);
> +	if (bufs == MAP_FAILED)
> +		return false;
> +
> +	mmap_sz = ceil_u64(mmap_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
> +	munmap(bufs, mmap_sz);
> +	return true;
> +}
> +
>  static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *src_mac,
>  		       thread_func_t func_ptr)
>  {
> @@ -1713,94 +1719,87 @@ static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *
>  		printf("Error loading XDP program\n");
>  		exit_with_error(err);
>  	}
> +
> +	if (hugepages_present())
> +		ifobj->unaligned_supp = true;
>  }
>  
>  static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_type type)
>  {
> +	int ret = TEST_SKIP;
> +
>  	switch (type) {
>  	case TEST_TYPE_STATS_RX_DROPPED:
> -		if (mode == TEST_MODE_ZC) {
> -			ksft_test_result_skip("Can not run RX_DROPPED test for ZC mode\n");
> -			return;
> -		}
> -		testapp_stats_rx_dropped(test);
> +		ret = testapp_stats_rx_dropped(test);
>  		break;
>  	case TEST_TYPE_STATS_TX_INVALID_DESCS:
> -		testapp_stats_tx_invalid_descs(test);
> +		ret = testapp_stats_tx_invalid_descs(test);
>  		break;
>  	case TEST_TYPE_STATS_RX_FULL:
> -		testapp_stats_rx_full(test);
> +		ret = testapp_stats_rx_full(test);
>  		break;
>  	case TEST_TYPE_STATS_FILL_EMPTY:
> -		testapp_stats_fill_empty(test);
> +		ret = testapp_stats_fill_empty(test);
>  		break;
>  	case TEST_TYPE_TEARDOWN:
> -		testapp_teardown(test);
> +		ret = testapp_teardown(test);
>  		break;
>  	case TEST_TYPE_BIDI:
> -		testapp_bidi(test);
> +		ret = testapp_bidi(test);
>  		break;
>  	case TEST_TYPE_BPF_RES:
> -		testapp_bpf_res(test);
> +		ret = testapp_bpf_res(test);
>  		break;
>  	case TEST_TYPE_RUN_TO_COMPLETION:
>  		test_spec_set_name(test, "RUN_TO_COMPLETION");
> -		testapp_validate_traffic(test);
> +		ret = testapp_validate_traffic(test);
>  		break;
>  	case TEST_TYPE_RUN_TO_COMPLETION_SINGLE_PKT:
>  		test_spec_set_name(test, "RUN_TO_COMPLETION_SINGLE_PKT");
> -		testapp_single_pkt(test);
> +		ret = testapp_single_pkt(test);
>  		break;
>  	case TEST_TYPE_RUN_TO_COMPLETION_2K_FRAME:
>  		test_spec_set_name(test, "RUN_TO_COMPLETION_2K_FRAME_SIZE");
>  		test->ifobj_tx->umem->frame_size = 2048;
>  		test->ifobj_rx->umem->frame_size = 2048;
>  		pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE);
> -		testapp_validate_traffic(test);
> +		ret = testapp_validate_traffic(test);
>  		break;
>  	case TEST_TYPE_RX_POLL:
>  		test->ifobj_rx->use_poll = true;
>  		test_spec_set_name(test, "POLL_RX");
> -		testapp_validate_traffic(test);
> +		ret = testapp_validate_traffic(test);
>  		break;
>  	case TEST_TYPE_TX_POLL:
>  		test->ifobj_tx->use_poll = true;
>  		test_spec_set_name(test, "POLL_TX");
> -		testapp_validate_traffic(test);
> +		ret = testapp_validate_traffic(test);
>  		break;
>  	case TEST_TYPE_POLL_TXQ_TMOUT:
> -		testapp_poll_txq_tmout(test);
> +		ret = testapp_poll_txq_tmout(test);
>  		break;
>  	case TEST_TYPE_POLL_RXQ_TMOUT:
> -		testapp_poll_rxq_tmout(test);
> +		ret = testapp_poll_rxq_tmout(test);
>  		break;
>  	case TEST_TYPE_ALIGNED_INV_DESC:
>  		test_spec_set_name(test, "ALIGNED_INV_DESC");
> -		testapp_invalid_desc(test);
> +		ret = testapp_invalid_desc(test);
>  		break;
>  	case TEST_TYPE_ALIGNED_INV_DESC_2K_FRAME:
>  		test_spec_set_name(test, "ALIGNED_INV_DESC_2K_FRAME_SIZE");
>  		test->ifobj_tx->umem->frame_size = 2048;
>  		test->ifobj_rx->umem->frame_size = 2048;
> -		testapp_invalid_desc(test);
> +		ret = testapp_invalid_desc(test);
>  		break;
>  	case TEST_TYPE_UNALIGNED_INV_DESC:
> -		if (!hugepages_present(test->ifobj_tx)) {
> -			ksft_test_result_skip("No 2M huge pages present.\n");
> -			return;
> -		}
>  		test_spec_set_name(test, "UNALIGNED_INV_DESC");
>  		test->ifobj_tx->umem->unaligned_mode = true;
>  		test->ifobj_rx->umem->unaligned_mode = true;
> -		testapp_invalid_desc(test);
> +		ret = testapp_invalid_desc(test);
>  		break;
>  	case TEST_TYPE_UNALIGNED_INV_DESC_4K1_FRAME: {
>  		u64 page_size, umem_size;
>  
> -		if (!hugepages_present(test->ifobj_tx)) {
> -			ksft_test_result_skip("No 2M huge pages present.\n");
> -			return;
> -		}
>  		test_spec_set_name(test, "UNALIGNED_INV_DESC_4K1_FRAME_SIZE");
>  		/* Odd frame size so the UMEM doesn't end near a page boundary. */
>  		test->ifobj_tx->umem->frame_size = 4001;
> @@ -1814,27 +1813,26 @@ static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
>  		umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
>  		assert(umem_size % page_size > MIN_PKT_SIZE);
>  		assert(umem_size % page_size < page_size - MIN_PKT_SIZE);
> -		testapp_invalid_desc(test);
> +		ret = testapp_invalid_desc(test);
>  		break;
>  	}
>  	case TEST_TYPE_UNALIGNED:
> -		if (!testapp_unaligned(test))
> -			return;
> +		ret = testapp_unaligned(test);
>  		break;
>  	case TEST_TYPE_HEADROOM:
> -		testapp_headroom(test);
> +		ret = testapp_headroom(test);
>  		break;
>  	case TEST_TYPE_XDP_DROP_HALF:
> -		testapp_xdp_drop(test);
> +		ret = testapp_xdp_drop(test);
>  		break;
>  	case TEST_TYPE_XDP_METADATA_COUNT:
> -		testapp_xdp_metadata_count(test);
> +		ret = testapp_xdp_metadata_count(test);
>  		break;
>  	default:
>  		break;
>  	}
>  
> -	if (!test->fail)
> +	if (ret == TEST_PASS)
>  		ksft_test_result_pass("PASS: %s %s%s\n", mode_string(test), busy_poll_string(test),
>  				      test->name);
>  	pkt_stream_restore_default(test);
> diff --git a/tools/testing/selftests/bpf/xskxceiver.h b/tools/testing/selftests/bpf/xskxceiver.h
> index be4664a38d74..00862732e751 100644
> --- a/tools/testing/selftests/bpf/xskxceiver.h
> +++ b/tools/testing/selftests/bpf/xskxceiver.h
> @@ -30,6 +30,7 @@
>  #define TEST_PASS 0
>  #define TEST_FAILURE -1
>  #define TEST_CONTINUE 1
> +#define TEST_SKIP 2
>  #define MAX_INTERFACES 2
>  #define MAX_INTERFACE_NAME_CHARS 16
>  #define MAX_SOCKETS 2
> @@ -148,6 +149,7 @@ struct ifobject {
>  	bool release_rx;
>  	bool shared_umem;
>  	bool use_metadata;
> +	bool unaligned_supp;
>  	u8 dst_mac[ETH_ALEN];
>  	u8 src_mac[ETH_ALEN];
>  };
> -- 
> 2.34.1
>
Fijalkowski, Maciej May 16, 2023, 1:06 p.m. UTC | #2
On Tue, May 16, 2023 at 02:58:26PM +0200, Maciej Fijalkowski wrote:
> On Tue, May 16, 2023 at 12:31:06PM +0200, Magnus Karlsson wrote:
> > From: Magnus Karlsson <magnus.karlsson@intel.com>
> > 
> > Test for hugepages only once at the beginning of the execution of the
> > whole test suite, instead of before each test that needs huge
> > pages. These are the tests that use unaligned mode. As more unaligned
> > tests will be added, so the current system just does not scale.
> > 
> > With this change, there are now three possible outcomes of a test run:
> > fail, pass, or skip. To simplify the handling of this, the function
> > testapp_validate_traffic() now returns this value to the main loop. As
> > this function is used by nearly all tests, it meant a small change to
> > most of them.
> 
> I don't get the need for that change. Why couldn't we just store the
> retval to test_spec and then check it in run_pkt_test() just like we check
> test->fail currently? Am i missing something?

also typo in subject - s/xsx/xsk

> 
> > 
> > Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> > ---
> >  tools/testing/selftests/bpf/xskxceiver.c | 186 +++++++++++------------
> >  tools/testing/selftests/bpf/xskxceiver.h |   2 +
> >  2 files changed, 94 insertions(+), 94 deletions(-)
> >
Magnus Karlsson May 16, 2023, 2:25 p.m. UTC | #3
On Tue, 16 May 2023 at 14:58, Maciej Fijalkowski
<maciej.fijalkowski@intel.com> wrote:
>
> On Tue, May 16, 2023 at 12:31:06PM +0200, Magnus Karlsson wrote:
> > From: Magnus Karlsson <magnus.karlsson@intel.com>
> >
> > Test for hugepages only once at the beginning of the execution of the
> > whole test suite, instead of before each test that needs huge
> > pages. These are the tests that use unaligned mode. As more unaligned
> > tests will be added, so the current system just does not scale.
> >
> > With this change, there are now three possible outcomes of a test run:
> > fail, pass, or skip. To simplify the handling of this, the function
> > testapp_validate_traffic() now returns this value to the main loop. As
> > this function is used by nearly all tests, it meant a small change to
> > most of them.
>
> I don't get the need for that change. Why couldn't we just store the
> retval to test_spec and then check it in run_pkt_test() just like we check
> test->fail currently? Am i missing something?

I think it is nicer to have the test return fail/pass/skip, just like
most functions return non-zero if there is an error, instead of using
a variable embedded in a struct. But maybe it is too much for a single
patch. How about breaking out the void -> int conversion of the return
value in one patch and then have the "remember unaligned mode" in a
separate one? The first one is just a means to be able to reach the
second one. What do you think?

> >
> > Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> > ---
> >  tools/testing/selftests/bpf/xskxceiver.c | 186 +++++++++++------------
> >  tools/testing/selftests/bpf/xskxceiver.h |   2 +
> >  2 files changed, 94 insertions(+), 94 deletions(-)
> >
> > diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
> > index d488d859d3a2..f0d929cb730a 100644
> > --- a/tools/testing/selftests/bpf/xskxceiver.c
> > +++ b/tools/testing/selftests/bpf/xskxceiver.c
> > @@ -1413,6 +1413,12 @@ static int testapp_validate_traffic(struct test_spec *test)
> >       struct ifobject *ifobj_rx = test->ifobj_rx;
> >       struct ifobject *ifobj_tx = test->ifobj_tx;
> >
> > +     if ((ifobj_rx->umem->unaligned_mode && !ifobj_rx->unaligned_supp) ||
> > +         (ifobj_tx->umem->unaligned_mode && !ifobj_tx->unaligned_supp)) {
> > +             ksft_test_result_skip("No huge pages present.\n");
> > +             return TEST_SKIP;
> > +     }
> > +
> >       xsk_attach_xdp_progs(test, ifobj_rx, ifobj_tx);
> >       return __testapp_validate_traffic(test, ifobj_rx, ifobj_tx);
> >  }
> > @@ -1422,16 +1428,18 @@ static int testapp_validate_traffic_single_thread(struct test_spec *test, struct
> >       return __testapp_validate_traffic(test, ifobj, NULL);
> >  }
> >
> > -static void testapp_teardown(struct test_spec *test)
> > +static int testapp_teardown(struct test_spec *test)
> >  {
> >       int i;
> >
> >       test_spec_set_name(test, "TEARDOWN");
> >       for (i = 0; i < MAX_TEARDOWN_ITER; i++) {
> >               if (testapp_validate_traffic(test))
> > -                     return;
> > +                     return TEST_FAILURE;
> >               test_spec_reset(test);
> >       }
> > +
> > +     return TEST_PASS;
> >  }
> >
> >  static void swap_directions(struct ifobject **ifobj1, struct ifobject **ifobj2)
> > @@ -1446,20 +1454,23 @@ static void swap_directions(struct ifobject **ifobj1, struct ifobject **ifobj2)
> >       *ifobj2 = tmp_ifobj;
> >  }
> >
> > -static void testapp_bidi(struct test_spec *test)
> > +static int testapp_bidi(struct test_spec *test)
> >  {
> > +     int res;
> > +
> >       test_spec_set_name(test, "BIDIRECTIONAL");
> >       test->ifobj_tx->rx_on = true;
> >       test->ifobj_rx->tx_on = true;
> >       test->total_steps = 2;
> >       if (testapp_validate_traffic(test))
> > -             return;
> > +             return TEST_FAILURE;
> >
> >       print_verbose("Switching Tx/Rx vectors\n");
> >       swap_directions(&test->ifobj_rx, &test->ifobj_tx);
> > -     __testapp_validate_traffic(test, test->ifobj_rx, test->ifobj_tx);
> > +     res = __testapp_validate_traffic(test, test->ifobj_rx, test->ifobj_tx);
> >
> >       swap_directions(&test->ifobj_rx, &test->ifobj_tx);
> > +     return res;
> >  }
> >
> >  static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj_rx)
> > @@ -1476,115 +1487,94 @@ static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj
> >               exit_with_error(errno);
> >  }
> >
> > -static void testapp_bpf_res(struct test_spec *test)
> > +static int testapp_bpf_res(struct test_spec *test)
> >  {
> >       test_spec_set_name(test, "BPF_RES");
> >       test->total_steps = 2;
> >       test->nb_sockets = 2;
> >       if (testapp_validate_traffic(test))
> > -             return;
> > +             return TEST_FAILURE;
> >
> >       swap_xsk_resources(test->ifobj_tx, test->ifobj_rx);
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_headroom(struct test_spec *test)
> > +static int testapp_headroom(struct test_spec *test)
> >  {
> >       test_spec_set_name(test, "UMEM_HEADROOM");
> >       test->ifobj_rx->umem->frame_headroom = UMEM_HEADROOM_TEST_SIZE;
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_stats_rx_dropped(struct test_spec *test)
> > +static int testapp_stats_rx_dropped(struct test_spec *test)
> >  {
> >       test_spec_set_name(test, "STAT_RX_DROPPED");
> > +     if (test->mode == TEST_MODE_ZC) {
> > +             ksft_test_result_skip("Can not run RX_DROPPED test for ZC mode\n");
> > +             return TEST_SKIP;
> > +     }
> > +
> >       pkt_stream_replace_half(test, MIN_PKT_SIZE * 4, 0);
> >       test->ifobj_rx->umem->frame_headroom = test->ifobj_rx->umem->frame_size -
> >               XDP_PACKET_HEADROOM - MIN_PKT_SIZE * 3;
> >       pkt_stream_receive_half(test);
> >       test->ifobj_rx->validation_func = validate_rx_dropped;
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_stats_tx_invalid_descs(struct test_spec *test)
> > +static int testapp_stats_tx_invalid_descs(struct test_spec *test)
> >  {
> >       test_spec_set_name(test, "STAT_TX_INVALID");
> >       pkt_stream_replace_half(test, XSK_UMEM__INVALID_FRAME_SIZE, 0);
> >       test->ifobj_tx->validation_func = validate_tx_invalid_descs;
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_stats_rx_full(struct test_spec *test)
> > +static int testapp_stats_rx_full(struct test_spec *test)
> >  {
> >       test_spec_set_name(test, "STAT_RX_FULL");
> >       pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
> >       test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
> >                                                        DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
> > -     if (!test->ifobj_rx->pkt_stream)
> > -             exit_with_error(ENOMEM);
> >
> >       test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS;
> >       test->ifobj_rx->release_rx = false;
> >       test->ifobj_rx->validation_func = validate_rx_full;
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_stats_fill_empty(struct test_spec *test)
> > +static int testapp_stats_fill_empty(struct test_spec *test)
> >  {
> >       test_spec_set_name(test, "STAT_RX_FILL_EMPTY");
> >       pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
> >       test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
> >                                                        DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
> > -     if (!test->ifobj_rx->pkt_stream)
> > -             exit_with_error(ENOMEM);
> >
> >       test->ifobj_rx->use_fill_ring = false;
> >       test->ifobj_rx->validation_func = validate_fill_empty;
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -/* Simple test */
> > -static bool hugepages_present(struct ifobject *ifobject)
> > +static int testapp_unaligned(struct test_spec *test)
> >  {
> > -     size_t mmap_sz = 2 * ifobject->umem->num_frames * ifobject->umem->frame_size;
> > -     void *bufs;
> > -
> > -     bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
> > -                 MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_HUGE_2MB, -1, 0);
> > -     if (bufs == MAP_FAILED)
> > -             return false;
> > -
> > -     mmap_sz = ceil_u64(mmap_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
> > -     munmap(bufs, mmap_sz);
> > -     return true;
> > -}
> > -
> > -static bool testapp_unaligned(struct test_spec *test)
> > -{
> > -     if (!hugepages_present(test->ifobj_tx)) {
> > -             ksft_test_result_skip("No 2M huge pages present.\n");
> > -             return false;
> > -     }
> > -
> >       test_spec_set_name(test, "UNALIGNED_MODE");
> >       test->ifobj_tx->umem->unaligned_mode = true;
> >       test->ifobj_rx->umem->unaligned_mode = true;
> >       /* Let half of the packets straddle a 4K buffer boundary */
> >       pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2);
> > -     testapp_validate_traffic(test);
> >
> > -     return true;
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_single_pkt(struct test_spec *test)
> > +static int testapp_single_pkt(struct test_spec *test)
> >  {
> >       struct pkt pkts[] = {{0, MIN_PKT_SIZE, 0, true}};
> >
> >       pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_invalid_desc(struct test_spec *test)
> > +static int testapp_invalid_desc(struct test_spec *test)
> >  {
> >       struct xsk_umem_info *umem = test->ifobj_tx->umem;
> >       u64 umem_size = umem->num_frames * umem->frame_size;
> > @@ -1626,10 +1616,10 @@ static void testapp_invalid_desc(struct test_spec *test)
> >       }
> >
> >       pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_xdp_drop(struct test_spec *test)
> > +static int testapp_xdp_drop(struct test_spec *test)
> >  {
> >       struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
> >       struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
> > @@ -1639,10 +1629,10 @@ static void testapp_xdp_drop(struct test_spec *test)
> >                              skel_rx->maps.xsk, skel_tx->maps.xsk);
> >
> >       pkt_stream_receive_half(test);
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_xdp_metadata_count(struct test_spec *test)
> > +static int testapp_xdp_metadata_count(struct test_spec *test)
> >  {
> >       struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
> >       struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
> > @@ -1663,10 +1653,10 @@ static void testapp_xdp_metadata_count(struct test_spec *test)
> >       if (bpf_map_update_elem(bpf_map__fd(data_map), &key, &count, BPF_ANY))
> >               exit_with_error(errno);
> >
> > -     testapp_validate_traffic(test);
> > +     return testapp_validate_traffic(test);
> >  }
> >
> > -static void testapp_poll_txq_tmout(struct test_spec *test)
> > +static int testapp_poll_txq_tmout(struct test_spec *test)
> >  {
> >       test_spec_set_name(test, "POLL_TXQ_FULL");
> >
> > @@ -1674,14 +1664,14 @@ static void testapp_poll_txq_tmout(struct test_spec *test)
> >       /* create invalid frame by set umem frame_size and pkt length equal to 2048 */
> >       test->ifobj_tx->umem->frame_size = 2048;
> >       pkt_stream_replace(test, 2 * DEFAULT_PKT_CNT, 2048);
> > -     testapp_validate_traffic_single_thread(test, test->ifobj_tx);
> > +     return testapp_validate_traffic_single_thread(test, test->ifobj_tx);
> >  }
> >
> > -static void testapp_poll_rxq_tmout(struct test_spec *test)
> > +static int testapp_poll_rxq_tmout(struct test_spec *test)
> >  {
> >       test_spec_set_name(test, "POLL_RXQ_EMPTY");
> >       test->ifobj_rx->use_poll = true;
> > -     testapp_validate_traffic_single_thread(test, test->ifobj_rx);
> > +     return testapp_validate_traffic_single_thread(test, test->ifobj_rx);
> >  }
> >
> >  static int xsk_load_xdp_programs(struct ifobject *ifobj)
> > @@ -1698,6 +1688,22 @@ static void xsk_unload_xdp_programs(struct ifobject *ifobj)
> >       xsk_xdp_progs__destroy(ifobj->xdp_progs);
> >  }
> >
> > +/* Simple test */
> > +static bool hugepages_present(void)
> > +{
> > +     size_t mmap_sz = 2 * DEFAULT_UMEM_BUFFERS * XSK_UMEM__DEFAULT_FRAME_SIZE;
> > +     void *bufs;
> > +
> > +     bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
> > +                 MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, MAP_HUGE_2MB);
> > +     if (bufs == MAP_FAILED)
> > +             return false;
> > +
> > +     mmap_sz = ceil_u64(mmap_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
> > +     munmap(bufs, mmap_sz);
> > +     return true;
> > +}
> > +
> >  static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *src_mac,
> >                      thread_func_t func_ptr)
> >  {
> > @@ -1713,94 +1719,87 @@ static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *
> >               printf("Error loading XDP program\n");
> >               exit_with_error(err);
> >       }
> > +
> > +     if (hugepages_present())
> > +             ifobj->unaligned_supp = true;
> >  }
> >
> >  static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_type type)
> >  {
> > +     int ret = TEST_SKIP;
> > +
> >       switch (type) {
> >       case TEST_TYPE_STATS_RX_DROPPED:
> > -             if (mode == TEST_MODE_ZC) {
> > -                     ksft_test_result_skip("Can not run RX_DROPPED test for ZC mode\n");
> > -                     return;
> > -             }
> > -             testapp_stats_rx_dropped(test);
> > +             ret = testapp_stats_rx_dropped(test);
> >               break;
> >       case TEST_TYPE_STATS_TX_INVALID_DESCS:
> > -             testapp_stats_tx_invalid_descs(test);
> > +             ret = testapp_stats_tx_invalid_descs(test);
> >               break;
> >       case TEST_TYPE_STATS_RX_FULL:
> > -             testapp_stats_rx_full(test);
> > +             ret = testapp_stats_rx_full(test);
> >               break;
> >       case TEST_TYPE_STATS_FILL_EMPTY:
> > -             testapp_stats_fill_empty(test);
> > +             ret = testapp_stats_fill_empty(test);
> >               break;
> >       case TEST_TYPE_TEARDOWN:
> > -             testapp_teardown(test);
> > +             ret = testapp_teardown(test);
> >               break;
> >       case TEST_TYPE_BIDI:
> > -             testapp_bidi(test);
> > +             ret = testapp_bidi(test);
> >               break;
> >       case TEST_TYPE_BPF_RES:
> > -             testapp_bpf_res(test);
> > +             ret = testapp_bpf_res(test);
> >               break;
> >       case TEST_TYPE_RUN_TO_COMPLETION:
> >               test_spec_set_name(test, "RUN_TO_COMPLETION");
> > -             testapp_validate_traffic(test);
> > +             ret = testapp_validate_traffic(test);
> >               break;
> >       case TEST_TYPE_RUN_TO_COMPLETION_SINGLE_PKT:
> >               test_spec_set_name(test, "RUN_TO_COMPLETION_SINGLE_PKT");
> > -             testapp_single_pkt(test);
> > +             ret = testapp_single_pkt(test);
> >               break;
> >       case TEST_TYPE_RUN_TO_COMPLETION_2K_FRAME:
> >               test_spec_set_name(test, "RUN_TO_COMPLETION_2K_FRAME_SIZE");
> >               test->ifobj_tx->umem->frame_size = 2048;
> >               test->ifobj_rx->umem->frame_size = 2048;
> >               pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE);
> > -             testapp_validate_traffic(test);
> > +             ret = testapp_validate_traffic(test);
> >               break;
> >       case TEST_TYPE_RX_POLL:
> >               test->ifobj_rx->use_poll = true;
> >               test_spec_set_name(test, "POLL_RX");
> > -             testapp_validate_traffic(test);
> > +             ret = testapp_validate_traffic(test);
> >               break;
> >       case TEST_TYPE_TX_POLL:
> >               test->ifobj_tx->use_poll = true;
> >               test_spec_set_name(test, "POLL_TX");
> > -             testapp_validate_traffic(test);
> > +             ret = testapp_validate_traffic(test);
> >               break;
> >       case TEST_TYPE_POLL_TXQ_TMOUT:
> > -             testapp_poll_txq_tmout(test);
> > +             ret = testapp_poll_txq_tmout(test);
> >               break;
> >       case TEST_TYPE_POLL_RXQ_TMOUT:
> > -             testapp_poll_rxq_tmout(test);
> > +             ret = testapp_poll_rxq_tmout(test);
> >               break;
> >       case TEST_TYPE_ALIGNED_INV_DESC:
> >               test_spec_set_name(test, "ALIGNED_INV_DESC");
> > -             testapp_invalid_desc(test);
> > +             ret = testapp_invalid_desc(test);
> >               break;
> >       case TEST_TYPE_ALIGNED_INV_DESC_2K_FRAME:
> >               test_spec_set_name(test, "ALIGNED_INV_DESC_2K_FRAME_SIZE");
> >               test->ifobj_tx->umem->frame_size = 2048;
> >               test->ifobj_rx->umem->frame_size = 2048;
> > -             testapp_invalid_desc(test);
> > +             ret = testapp_invalid_desc(test);
> >               break;
> >       case TEST_TYPE_UNALIGNED_INV_DESC:
> > -             if (!hugepages_present(test->ifobj_tx)) {
> > -                     ksft_test_result_skip("No 2M huge pages present.\n");
> > -                     return;
> > -             }
> >               test_spec_set_name(test, "UNALIGNED_INV_DESC");
> >               test->ifobj_tx->umem->unaligned_mode = true;
> >               test->ifobj_rx->umem->unaligned_mode = true;
> > -             testapp_invalid_desc(test);
> > +             ret = testapp_invalid_desc(test);
> >               break;
> >       case TEST_TYPE_UNALIGNED_INV_DESC_4K1_FRAME: {
> >               u64 page_size, umem_size;
> >
> > -             if (!hugepages_present(test->ifobj_tx)) {
> > -                     ksft_test_result_skip("No 2M huge pages present.\n");
> > -                     return;
> > -             }
> >               test_spec_set_name(test, "UNALIGNED_INV_DESC_4K1_FRAME_SIZE");
> >               /* Odd frame size so the UMEM doesn't end near a page boundary. */
> >               test->ifobj_tx->umem->frame_size = 4001;
> > @@ -1814,27 +1813,26 @@ static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
> >               umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
> >               assert(umem_size % page_size > MIN_PKT_SIZE);
> >               assert(umem_size % page_size < page_size - MIN_PKT_SIZE);
> > -             testapp_invalid_desc(test);
> > +             ret = testapp_invalid_desc(test);
> >               break;
> >       }
> >       case TEST_TYPE_UNALIGNED:
> > -             if (!testapp_unaligned(test))
> > -                     return;
> > +             ret = testapp_unaligned(test);
> >               break;
> >       case TEST_TYPE_HEADROOM:
> > -             testapp_headroom(test);
> > +             ret = testapp_headroom(test);
> >               break;
> >       case TEST_TYPE_XDP_DROP_HALF:
> > -             testapp_xdp_drop(test);
> > +             ret = testapp_xdp_drop(test);
> >               break;
> >       case TEST_TYPE_XDP_METADATA_COUNT:
> > -             testapp_xdp_metadata_count(test);
> > +             ret = testapp_xdp_metadata_count(test);
> >               break;
> >       default:
> >               break;
> >       }
> >
> > -     if (!test->fail)
> > +     if (ret == TEST_PASS)
> >               ksft_test_result_pass("PASS: %s %s%s\n", mode_string(test), busy_poll_string(test),
> >                                     test->name);
> >       pkt_stream_restore_default(test);
> > diff --git a/tools/testing/selftests/bpf/xskxceiver.h b/tools/testing/selftests/bpf/xskxceiver.h
> > index be4664a38d74..00862732e751 100644
> > --- a/tools/testing/selftests/bpf/xskxceiver.h
> > +++ b/tools/testing/selftests/bpf/xskxceiver.h
> > @@ -30,6 +30,7 @@
> >  #define TEST_PASS 0
> >  #define TEST_FAILURE -1
> >  #define TEST_CONTINUE 1
> > +#define TEST_SKIP 2
> >  #define MAX_INTERFACES 2
> >  #define MAX_INTERFACE_NAME_CHARS 16
> >  #define MAX_SOCKETS 2
> > @@ -148,6 +149,7 @@ struct ifobject {
> >       bool release_rx;
> >       bool shared_umem;
> >       bool use_metadata;
> > +     bool unaligned_supp;
> >       u8 dst_mac[ETH_ALEN];
> >       u8 src_mac[ETH_ALEN];
> >  };
> > --
> > 2.34.1
> >
Magnus Karlsson May 16, 2023, 2:26 p.m. UTC | #4
On Tue, 16 May 2023 at 15:07, Maciej Fijalkowski
<maciej.fijalkowski@intel.com> wrote:
>
> On Tue, May 16, 2023 at 02:58:26PM +0200, Maciej Fijalkowski wrote:
> > On Tue, May 16, 2023 at 12:31:06PM +0200, Magnus Karlsson wrote:
> > > From: Magnus Karlsson <magnus.karlsson@intel.com>
> > >
> > > Test for hugepages only once at the beginning of the execution of the
> > > whole test suite, instead of before each test that needs huge
> > > pages. These are the tests that use unaligned mode. As more unaligned
> > > tests will be added, so the current system just does not scale.
> > >
> > > With this change, there are now three possible outcomes of a test run:
> > > fail, pass, or skip. To simplify the handling of this, the function
> > > testapp_validate_traffic() now returns this value to the main loop. As
> > > this function is used by nearly all tests, it meant a small change to
> > > most of them.
> >
> > I don't get the need for that change. Why couldn't we just store the
> > retval to test_spec and then check it in run_pkt_test() just like we check
> > test->fail currently? Am i missing something?
>
> also typo in subject - s/xsx/xsk

Ouch, will fix. Thanks!

> >
> > >
> > > Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> > > ---
> > >  tools/testing/selftests/bpf/xskxceiver.c | 186 +++++++++++------------
> > >  tools/testing/selftests/bpf/xskxceiver.h |   2 +
> > >  2 files changed, 94 insertions(+), 94 deletions(-)
> > >
Fijalkowski, Maciej May 16, 2023, 2:40 p.m. UTC | #5
On Tue, May 16, 2023 at 04:25:30PM +0200, Magnus Karlsson wrote:
> On Tue, 16 May 2023 at 14:58, Maciej Fijalkowski
> <maciej.fijalkowski@intel.com> wrote:
> >
> > On Tue, May 16, 2023 at 12:31:06PM +0200, Magnus Karlsson wrote:
> > > From: Magnus Karlsson <magnus.karlsson@intel.com>
> > >
> > > Test for hugepages only once at the beginning of the execution of the
> > > whole test suite, instead of before each test that needs huge
> > > pages. These are the tests that use unaligned mode. As more unaligned
> > > tests will be added, so the current system just does not scale.
> > >
> > > With this change, there are now three possible outcomes of a test run:
> > > fail, pass, or skip. To simplify the handling of this, the function
> > > testapp_validate_traffic() now returns this value to the main loop. As
> > > this function is used by nearly all tests, it meant a small change to
> > > most of them.
> >
> > I don't get the need for that change. Why couldn't we just store the
> > retval to test_spec and then check it in run_pkt_test() just like we check
> > test->fail currently? Am i missing something?
> 
> I think it is nicer to have the test return fail/pass/skip, just like
> most functions return non-zero if there is an error, instead of using
> a variable embedded in a struct. But maybe it is too much for a single
> patch. How about breaking out the void -> int conversion of the return
> value in one patch and then have the "remember unaligned mode" in a
> separate one? The first one is just a means to be able to reach the
> second one. What do you think?

Yes, please, this would make this patch content to do only what subject of
it relates to. s/void/int does not belong here and is a good candidate for
a preceding patch, so please just pull it out. Thanks!

> 
> > >
> > > Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
> > > ---
> > >  tools/testing/selftests/bpf/xskxceiver.c | 186 +++++++++++------------
> > >  tools/testing/selftests/bpf/xskxceiver.h |   2 +
> > >  2 files changed, 94 insertions(+), 94 deletions(-)
> > >
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
index d488d859d3a2..f0d929cb730a 100644
--- a/tools/testing/selftests/bpf/xskxceiver.c
+++ b/tools/testing/selftests/bpf/xskxceiver.c
@@ -1413,6 +1413,12 @@  static int testapp_validate_traffic(struct test_spec *test)
 	struct ifobject *ifobj_rx = test->ifobj_rx;
 	struct ifobject *ifobj_tx = test->ifobj_tx;
 
+	if ((ifobj_rx->umem->unaligned_mode && !ifobj_rx->unaligned_supp) ||
+	    (ifobj_tx->umem->unaligned_mode && !ifobj_tx->unaligned_supp)) {
+		ksft_test_result_skip("No huge pages present.\n");
+		return TEST_SKIP;
+	}
+
 	xsk_attach_xdp_progs(test, ifobj_rx, ifobj_tx);
 	return __testapp_validate_traffic(test, ifobj_rx, ifobj_tx);
 }
@@ -1422,16 +1428,18 @@  static int testapp_validate_traffic_single_thread(struct test_spec *test, struct
 	return __testapp_validate_traffic(test, ifobj, NULL);
 }
 
-static void testapp_teardown(struct test_spec *test)
+static int testapp_teardown(struct test_spec *test)
 {
 	int i;
 
 	test_spec_set_name(test, "TEARDOWN");
 	for (i = 0; i < MAX_TEARDOWN_ITER; i++) {
 		if (testapp_validate_traffic(test))
-			return;
+			return TEST_FAILURE;
 		test_spec_reset(test);
 	}
+
+	return TEST_PASS;
 }
 
 static void swap_directions(struct ifobject **ifobj1, struct ifobject **ifobj2)
@@ -1446,20 +1454,23 @@  static void swap_directions(struct ifobject **ifobj1, struct ifobject **ifobj2)
 	*ifobj2 = tmp_ifobj;
 }
 
-static void testapp_bidi(struct test_spec *test)
+static int testapp_bidi(struct test_spec *test)
 {
+	int res;
+
 	test_spec_set_name(test, "BIDIRECTIONAL");
 	test->ifobj_tx->rx_on = true;
 	test->ifobj_rx->tx_on = true;
 	test->total_steps = 2;
 	if (testapp_validate_traffic(test))
-		return;
+		return TEST_FAILURE;
 
 	print_verbose("Switching Tx/Rx vectors\n");
 	swap_directions(&test->ifobj_rx, &test->ifobj_tx);
-	__testapp_validate_traffic(test, test->ifobj_rx, test->ifobj_tx);
+	res = __testapp_validate_traffic(test, test->ifobj_rx, test->ifobj_tx);
 
 	swap_directions(&test->ifobj_rx, &test->ifobj_tx);
+	return res;
 }
 
 static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj_rx)
@@ -1476,115 +1487,94 @@  static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj
 		exit_with_error(errno);
 }
 
-static void testapp_bpf_res(struct test_spec *test)
+static int testapp_bpf_res(struct test_spec *test)
 {
 	test_spec_set_name(test, "BPF_RES");
 	test->total_steps = 2;
 	test->nb_sockets = 2;
 	if (testapp_validate_traffic(test))
-		return;
+		return TEST_FAILURE;
 
 	swap_xsk_resources(test->ifobj_tx, test->ifobj_rx);
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_headroom(struct test_spec *test)
+static int testapp_headroom(struct test_spec *test)
 {
 	test_spec_set_name(test, "UMEM_HEADROOM");
 	test->ifobj_rx->umem->frame_headroom = UMEM_HEADROOM_TEST_SIZE;
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_stats_rx_dropped(struct test_spec *test)
+static int testapp_stats_rx_dropped(struct test_spec *test)
 {
 	test_spec_set_name(test, "STAT_RX_DROPPED");
+	if (test->mode == TEST_MODE_ZC) {
+		ksft_test_result_skip("Can not run RX_DROPPED test for ZC mode\n");
+		return TEST_SKIP;
+	}
+
 	pkt_stream_replace_half(test, MIN_PKT_SIZE * 4, 0);
 	test->ifobj_rx->umem->frame_headroom = test->ifobj_rx->umem->frame_size -
 		XDP_PACKET_HEADROOM - MIN_PKT_SIZE * 3;
 	pkt_stream_receive_half(test);
 	test->ifobj_rx->validation_func = validate_rx_dropped;
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_stats_tx_invalid_descs(struct test_spec *test)
+static int testapp_stats_tx_invalid_descs(struct test_spec *test)
 {
 	test_spec_set_name(test, "STAT_TX_INVALID");
 	pkt_stream_replace_half(test, XSK_UMEM__INVALID_FRAME_SIZE, 0);
 	test->ifobj_tx->validation_func = validate_tx_invalid_descs;
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_stats_rx_full(struct test_spec *test)
+static int testapp_stats_rx_full(struct test_spec *test)
 {
 	test_spec_set_name(test, "STAT_RX_FULL");
 	pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
 	test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
 							 DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
-	if (!test->ifobj_rx->pkt_stream)
-		exit_with_error(ENOMEM);
 
 	test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS;
 	test->ifobj_rx->release_rx = false;
 	test->ifobj_rx->validation_func = validate_rx_full;
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_stats_fill_empty(struct test_spec *test)
+static int testapp_stats_fill_empty(struct test_spec *test)
 {
 	test_spec_set_name(test, "STAT_RX_FILL_EMPTY");
 	pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
 	test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
 							 DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
-	if (!test->ifobj_rx->pkt_stream)
-		exit_with_error(ENOMEM);
 
 	test->ifobj_rx->use_fill_ring = false;
 	test->ifobj_rx->validation_func = validate_fill_empty;
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-/* Simple test */
-static bool hugepages_present(struct ifobject *ifobject)
+static int testapp_unaligned(struct test_spec *test)
 {
-	size_t mmap_sz = 2 * ifobject->umem->num_frames * ifobject->umem->frame_size;
-	void *bufs;
-
-	bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
-		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_HUGE_2MB, -1, 0);
-	if (bufs == MAP_FAILED)
-		return false;
-
-	mmap_sz = ceil_u64(mmap_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
-	munmap(bufs, mmap_sz);
-	return true;
-}
-
-static bool testapp_unaligned(struct test_spec *test)
-{
-	if (!hugepages_present(test->ifobj_tx)) {
-		ksft_test_result_skip("No 2M huge pages present.\n");
-		return false;
-	}
-
 	test_spec_set_name(test, "UNALIGNED_MODE");
 	test->ifobj_tx->umem->unaligned_mode = true;
 	test->ifobj_rx->umem->unaligned_mode = true;
 	/* Let half of the packets straddle a 4K buffer boundary */
 	pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2);
-	testapp_validate_traffic(test);
 
-	return true;
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_single_pkt(struct test_spec *test)
+static int testapp_single_pkt(struct test_spec *test)
 {
 	struct pkt pkts[] = {{0, MIN_PKT_SIZE, 0, true}};
 
 	pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_invalid_desc(struct test_spec *test)
+static int testapp_invalid_desc(struct test_spec *test)
 {
 	struct xsk_umem_info *umem = test->ifobj_tx->umem;
 	u64 umem_size = umem->num_frames * umem->frame_size;
@@ -1626,10 +1616,10 @@  static void testapp_invalid_desc(struct test_spec *test)
 	}
 
 	pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_xdp_drop(struct test_spec *test)
+static int testapp_xdp_drop(struct test_spec *test)
 {
 	struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
 	struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
@@ -1639,10 +1629,10 @@  static void testapp_xdp_drop(struct test_spec *test)
 			       skel_rx->maps.xsk, skel_tx->maps.xsk);
 
 	pkt_stream_receive_half(test);
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_xdp_metadata_count(struct test_spec *test)
+static int testapp_xdp_metadata_count(struct test_spec *test)
 {
 	struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
 	struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
@@ -1663,10 +1653,10 @@  static void testapp_xdp_metadata_count(struct test_spec *test)
 	if (bpf_map_update_elem(bpf_map__fd(data_map), &key, &count, BPF_ANY))
 		exit_with_error(errno);
 
-	testapp_validate_traffic(test);
+	return testapp_validate_traffic(test);
 }
 
-static void testapp_poll_txq_tmout(struct test_spec *test)
+static int testapp_poll_txq_tmout(struct test_spec *test)
 {
 	test_spec_set_name(test, "POLL_TXQ_FULL");
 
@@ -1674,14 +1664,14 @@  static void testapp_poll_txq_tmout(struct test_spec *test)
 	/* create invalid frame by set umem frame_size and pkt length equal to 2048 */
 	test->ifobj_tx->umem->frame_size = 2048;
 	pkt_stream_replace(test, 2 * DEFAULT_PKT_CNT, 2048);
-	testapp_validate_traffic_single_thread(test, test->ifobj_tx);
+	return testapp_validate_traffic_single_thread(test, test->ifobj_tx);
 }
 
-static void testapp_poll_rxq_tmout(struct test_spec *test)
+static int testapp_poll_rxq_tmout(struct test_spec *test)
 {
 	test_spec_set_name(test, "POLL_RXQ_EMPTY");
 	test->ifobj_rx->use_poll = true;
-	testapp_validate_traffic_single_thread(test, test->ifobj_rx);
+	return testapp_validate_traffic_single_thread(test, test->ifobj_rx);
 }
 
 static int xsk_load_xdp_programs(struct ifobject *ifobj)
@@ -1698,6 +1688,22 @@  static void xsk_unload_xdp_programs(struct ifobject *ifobj)
 	xsk_xdp_progs__destroy(ifobj->xdp_progs);
 }
 
+/* Simple test */
+static bool hugepages_present(void)
+{
+	size_t mmap_sz = 2 * DEFAULT_UMEM_BUFFERS * XSK_UMEM__DEFAULT_FRAME_SIZE;
+	void *bufs;
+
+	bufs = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
+		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, MAP_HUGE_2MB);
+	if (bufs == MAP_FAILED)
+		return false;
+
+	mmap_sz = ceil_u64(mmap_sz, HUGEPAGE_SIZE) * HUGEPAGE_SIZE;
+	munmap(bufs, mmap_sz);
+	return true;
+}
+
 static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *src_mac,
 		       thread_func_t func_ptr)
 {
@@ -1713,94 +1719,87 @@  static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *
 		printf("Error loading XDP program\n");
 		exit_with_error(err);
 	}
+
+	if (hugepages_present())
+		ifobj->unaligned_supp = true;
 }
 
 static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_type type)
 {
+	int ret = TEST_SKIP;
+
 	switch (type) {
 	case TEST_TYPE_STATS_RX_DROPPED:
-		if (mode == TEST_MODE_ZC) {
-			ksft_test_result_skip("Can not run RX_DROPPED test for ZC mode\n");
-			return;
-		}
-		testapp_stats_rx_dropped(test);
+		ret = testapp_stats_rx_dropped(test);
 		break;
 	case TEST_TYPE_STATS_TX_INVALID_DESCS:
-		testapp_stats_tx_invalid_descs(test);
+		ret = testapp_stats_tx_invalid_descs(test);
 		break;
 	case TEST_TYPE_STATS_RX_FULL:
-		testapp_stats_rx_full(test);
+		ret = testapp_stats_rx_full(test);
 		break;
 	case TEST_TYPE_STATS_FILL_EMPTY:
-		testapp_stats_fill_empty(test);
+		ret = testapp_stats_fill_empty(test);
 		break;
 	case TEST_TYPE_TEARDOWN:
-		testapp_teardown(test);
+		ret = testapp_teardown(test);
 		break;
 	case TEST_TYPE_BIDI:
-		testapp_bidi(test);
+		ret = testapp_bidi(test);
 		break;
 	case TEST_TYPE_BPF_RES:
-		testapp_bpf_res(test);
+		ret = testapp_bpf_res(test);
 		break;
 	case TEST_TYPE_RUN_TO_COMPLETION:
 		test_spec_set_name(test, "RUN_TO_COMPLETION");
-		testapp_validate_traffic(test);
+		ret = testapp_validate_traffic(test);
 		break;
 	case TEST_TYPE_RUN_TO_COMPLETION_SINGLE_PKT:
 		test_spec_set_name(test, "RUN_TO_COMPLETION_SINGLE_PKT");
-		testapp_single_pkt(test);
+		ret = testapp_single_pkt(test);
 		break;
 	case TEST_TYPE_RUN_TO_COMPLETION_2K_FRAME:
 		test_spec_set_name(test, "RUN_TO_COMPLETION_2K_FRAME_SIZE");
 		test->ifobj_tx->umem->frame_size = 2048;
 		test->ifobj_rx->umem->frame_size = 2048;
 		pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE);
-		testapp_validate_traffic(test);
+		ret = testapp_validate_traffic(test);
 		break;
 	case TEST_TYPE_RX_POLL:
 		test->ifobj_rx->use_poll = true;
 		test_spec_set_name(test, "POLL_RX");
-		testapp_validate_traffic(test);
+		ret = testapp_validate_traffic(test);
 		break;
 	case TEST_TYPE_TX_POLL:
 		test->ifobj_tx->use_poll = true;
 		test_spec_set_name(test, "POLL_TX");
-		testapp_validate_traffic(test);
+		ret = testapp_validate_traffic(test);
 		break;
 	case TEST_TYPE_POLL_TXQ_TMOUT:
-		testapp_poll_txq_tmout(test);
+		ret = testapp_poll_txq_tmout(test);
 		break;
 	case TEST_TYPE_POLL_RXQ_TMOUT:
-		testapp_poll_rxq_tmout(test);
+		ret = testapp_poll_rxq_tmout(test);
 		break;
 	case TEST_TYPE_ALIGNED_INV_DESC:
 		test_spec_set_name(test, "ALIGNED_INV_DESC");
-		testapp_invalid_desc(test);
+		ret = testapp_invalid_desc(test);
 		break;
 	case TEST_TYPE_ALIGNED_INV_DESC_2K_FRAME:
 		test_spec_set_name(test, "ALIGNED_INV_DESC_2K_FRAME_SIZE");
 		test->ifobj_tx->umem->frame_size = 2048;
 		test->ifobj_rx->umem->frame_size = 2048;
-		testapp_invalid_desc(test);
+		ret = testapp_invalid_desc(test);
 		break;
 	case TEST_TYPE_UNALIGNED_INV_DESC:
-		if (!hugepages_present(test->ifobj_tx)) {
-			ksft_test_result_skip("No 2M huge pages present.\n");
-			return;
-		}
 		test_spec_set_name(test, "UNALIGNED_INV_DESC");
 		test->ifobj_tx->umem->unaligned_mode = true;
 		test->ifobj_rx->umem->unaligned_mode = true;
-		testapp_invalid_desc(test);
+		ret = testapp_invalid_desc(test);
 		break;
 	case TEST_TYPE_UNALIGNED_INV_DESC_4K1_FRAME: {
 		u64 page_size, umem_size;
 
-		if (!hugepages_present(test->ifobj_tx)) {
-			ksft_test_result_skip("No 2M huge pages present.\n");
-			return;
-		}
 		test_spec_set_name(test, "UNALIGNED_INV_DESC_4K1_FRAME_SIZE");
 		/* Odd frame size so the UMEM doesn't end near a page boundary. */
 		test->ifobj_tx->umem->frame_size = 4001;
@@ -1814,27 +1813,26 @@  static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
 		umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
 		assert(umem_size % page_size > MIN_PKT_SIZE);
 		assert(umem_size % page_size < page_size - MIN_PKT_SIZE);
-		testapp_invalid_desc(test);
+		ret = testapp_invalid_desc(test);
 		break;
 	}
 	case TEST_TYPE_UNALIGNED:
-		if (!testapp_unaligned(test))
-			return;
+		ret = testapp_unaligned(test);
 		break;
 	case TEST_TYPE_HEADROOM:
-		testapp_headroom(test);
+		ret = testapp_headroom(test);
 		break;
 	case TEST_TYPE_XDP_DROP_HALF:
-		testapp_xdp_drop(test);
+		ret = testapp_xdp_drop(test);
 		break;
 	case TEST_TYPE_XDP_METADATA_COUNT:
-		testapp_xdp_metadata_count(test);
+		ret = testapp_xdp_metadata_count(test);
 		break;
 	default:
 		break;
 	}
 
-	if (!test->fail)
+	if (ret == TEST_PASS)
 		ksft_test_result_pass("PASS: %s %s%s\n", mode_string(test), busy_poll_string(test),
 				      test->name);
 	pkt_stream_restore_default(test);
diff --git a/tools/testing/selftests/bpf/xskxceiver.h b/tools/testing/selftests/bpf/xskxceiver.h
index be4664a38d74..00862732e751 100644
--- a/tools/testing/selftests/bpf/xskxceiver.h
+++ b/tools/testing/selftests/bpf/xskxceiver.h
@@ -30,6 +30,7 @@ 
 #define TEST_PASS 0
 #define TEST_FAILURE -1
 #define TEST_CONTINUE 1
+#define TEST_SKIP 2
 #define MAX_INTERFACES 2
 #define MAX_INTERFACE_NAME_CHARS 16
 #define MAX_SOCKETS 2
@@ -148,6 +149,7 @@  struct ifobject {
 	bool release_rx;
 	bool shared_umem;
 	bool use_metadata;
+	bool unaligned_supp;
 	u8 dst_mac[ETH_ALEN];
 	u8 src_mac[ETH_ALEN];
 };