diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile index d5bf4cb638a8..1f21e17d8c22 100644 --- a/tools/testing/selftests/drivers/net/Makefile +++ b/tools/testing/selftests/drivers/net/Makefile @@ -11,13 +11,16 @@ TEST_GEN_FILES := \ # end of TEST_GEN_FILES TEST_PROGS := \ - gro.py \ + gro_hw.py \ + gro_lro.py \ + gro_sw.py \ hds.py \ macsec.py \ napi_id.py \ napi_threaded.py \ netpoll_basic.py \ ping.py \ + pppoe_gro.py \ psp.py \ queues.py \ ring_reconfig.py \ @@ -27,6 +30,10 @@ TEST_PROGS := \ xdp.py \ # end of TEST_PROGS +TEST_FILES := \ + gro_lib.py \ +# end of TEST_FILES + # YNL files, must be before "include ..lib.mk" YNL_GEN_FILES := psp_responder TEST_GEN_FILES += $(YNL_GEN_FILES) diff --git a/tools/testing/selftests/drivers/net/gro_hw.py b/tools/testing/selftests/drivers/net/gro_hw.py new file mode 100755 index 000000000000..06b980220835 --- /dev/null +++ b/tools/testing/selftests/drivers/net/gro_hw.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +""" +GRO conformance tests against the HW GRO implementation (rx-gro-hw). + +See gro_lib.py for the list of test cases. +""" + +from gro_lib import gro_main + +if __name__ == "__main__": + gro_main(__file__, "hw") diff --git a/tools/testing/selftests/drivers/net/gro.py b/tools/testing/selftests/drivers/net/gro_lib.py old mode 100755 new mode 100644 similarity index 92% rename from tools/testing/selftests/drivers/net/gro.py rename to tools/testing/selftests/drivers/net/gro_lib.py index 6ab8c97880d1..45ded8477a50 --- a/tools/testing/selftests/drivers/net/gro.py +++ b/tools/testing/selftests/drivers/net/gro_lib.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 """ @@ -8,6 +7,13 @@ Validates that GRO coalescing works correctly by running the gro binary in different configurations and checking for correct packet coalescing behavior. +The same test cases are run against all three coalescing implementations, +one mode per test program, because a full sweep takes too long to fit in +a single test's timeout: + - gro_sw.py: SW GRO (generic-receive-offload) + - gro_hw.py: HW GRO (rx-gro-hw) + - gro_lro.py: LRO (large-receive-offload) + Test cases: - data_same: Same size data packets coalesce - data_lrg_sml: Large packet followed by smaller one coalesces @@ -323,32 +329,19 @@ def _gro_variants(): "ip_frag6", "ip_v6ext_same", "ip_v6ext_diff", ] - # Tests specific to PPPoE - pppoe_tests = [ - "data_same", "data_lrg_sml", "data_sml_lrg", "data_lrg_1byte", - "data_burst", "pppoe_sid", - ] + for protocol in ["ipv4", "ipv6", "ipip", "ip6ip6"]: + for test_name in common_tests: + yield protocol, test_name - for mode in ["sw", "hw", "lro"]: - for protocol in ["ipv4", "ipv6", "ipip", "ip6ip6"]: - for test_name in common_tests: - yield mode, protocol, test_name - - if protocol in ["ipv4", "ipip"]: - for test_name in ipv4_tests: - yield mode, protocol, test_name - elif protocol == "ipv6": - for test_name in ipv6_tests: - yield mode, protocol, test_name - - for mode in ["sw"]: - for protocol in ["pppoev4", "pppoev6"]: - for test_name in pppoe_tests: - yield mode, protocol, test_name + if protocol in ["ipv4", "ipip"]: + for test_name in ipv4_tests: + yield protocol, test_name + elif protocol == "ipv6": + for test_name in ipv6_tests: + yield protocol, test_name -@ksft_variants(_gro_variants()) -def test(cfg, mode, protocol, test_name): +def run_test(cfg, mode, protocol, test_name): """Run a single GRO test with retries.""" ipver = "6" if protocol[-1] == "6" else "4" @@ -383,16 +376,21 @@ def test(cfg, mode, protocol, test_name): ksft_pr(f"Attempt {attempt + 1}/{max_retries} failed, retrying...") +@ksft_variants(_gro_variants()) +def test(cfg, mode, protocol, test_name): + """Run a single GRO test case.""" + run_test(cfg, mode, protocol, test_name) + + def _capacity_variants(): - """Generate variants for capacity test: mode x queue setup.""" + """Generate variants for capacity test: queue setup.""" setups = [ ("isolated", _setup_isolated_queue), ("1q", lambda cfg: _setup_queue_count(cfg, 1)), ("8q", lambda cfg: _setup_queue_count(cfg, 8)), ] - for mode in ["sw", "hw", "lro"]: - for name, func in setups: - yield KsftNamedVariant(f"{mode}_{name}", mode, func) + for name, func in setups: + yield KsftNamedVariant(name, func) @ksft_variants(_capacity_variants()) @@ -403,7 +401,7 @@ def test_gro_capacity(cfg, mode, setup_func): Start with 8 flows and increase by 2x on each successful run. Retry up to 3 times on failure. - Variants combine mode (sw, hw, lro) with queue setup: + Queue setup variants: - isolated: Use a single queue isolated from RSS - 1q: Configure NIC to use 1 queue - 8q: Configure NIC to use 8 queues @@ -459,15 +457,11 @@ def test_gro_capacity(cfg, mode, setup_func): num_flows *= 2 -def main() -> None: - """ Ksft boiler plate main """ +def gro_main(src_path, mode) -> None: + """ Ksft boiler plate main, run all the cases in the given mode """ - with NetDrvEpEnv(__file__) as cfg: + with NetDrvEpEnv(src_path) as cfg: cfg.ethnl = EthtoolFamily() cfg.netnl = NetdevFamily() - ksft_run(cases=[test, test_gro_capacity], args=(cfg,)) + ksft_run(cases=[test, test_gro_capacity], args=(cfg, mode)) ksft_exit() - - -if __name__ == "__main__": - main() diff --git a/tools/testing/selftests/drivers/net/gro_lro.py b/tools/testing/selftests/drivers/net/gro_lro.py new file mode 100755 index 000000000000..63428d4aa749 --- /dev/null +++ b/tools/testing/selftests/drivers/net/gro_lro.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +""" +GRO conformance tests against the LRO implementation +(large-receive-offload). + +See gro_lib.py for the list of test cases. +""" + +from gro_lib import gro_main + +if __name__ == "__main__": + gro_main(__file__, "lro") diff --git a/tools/testing/selftests/drivers/net/gro_sw.py b/tools/testing/selftests/drivers/net/gro_sw.py new file mode 100755 index 000000000000..b682c092faad --- /dev/null +++ b/tools/testing/selftests/drivers/net/gro_sw.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +""" +GRO conformance tests against the SW GRO implementation. + +See gro_lib.py for the list of test cases. +""" + +from gro_lib import gro_main + +if __name__ == "__main__": + gro_main(__file__, "sw") diff --git a/tools/testing/selftests/drivers/net/hw/Makefile b/tools/testing/selftests/drivers/net/hw/Makefile index 78bb0169350b..6105be8e590f 100644 --- a/tools/testing/selftests/drivers/net/hw/Makefile +++ b/tools/testing/selftests/drivers/net/hw/Makefile @@ -27,7 +27,7 @@ TEST_PROGS = \ ethtool_mm.sh \ ethtool_rmon.sh \ ethtool_std_stats.sh \ - gro_hw.py \ + gro_stats.py \ hw_stats_l3.sh \ hw_stats_l3_gre.sh \ iou-zcrx.py \ diff --git a/tools/testing/selftests/drivers/net/hw/gro_hw.py b/tools/testing/selftests/drivers/net/hw/gro_stats.py similarity index 100% rename from tools/testing/selftests/drivers/net/hw/gro_hw.py rename to tools/testing/selftests/drivers/net/hw/gro_stats.py diff --git a/tools/testing/selftests/drivers/net/pppoe_gro.py b/tools/testing/selftests/drivers/net/pppoe_gro.py new file mode 100755 index 000000000000..3891d5e17ee1 --- /dev/null +++ b/tools/testing/selftests/drivers/net/pppoe_gro.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +""" +GRO conformance tests for PPPoE. + +Only SW GRO is expected to coalesce PPPoE, the HW offloads are not +exercised. PPPoE runs a subset of the cases described in gro_lib.py, +plus one of its own: + - pppoe_sid: Packets with different PPPoE session ID don't coalesce +""" + +from gro_lib import run_test +from lib.py import NetDrvEpEnv, ksft_exit, ksft_run, ksft_variants + + +def _pppoe_variants(): + """Generator that yields all combinations of protocol and test types.""" + + tests = [ + "data_same", "data_lrg_sml", "data_sml_lrg", "data_lrg_1byte", + "data_burst", "pppoe_sid", + ] + + for protocol in ["pppoev4", "pppoev6"]: + for test_name in tests: + yield protocol, test_name + + +@ksft_variants(_pppoe_variants()) +def test(cfg, protocol, test_name): + """Run a single GRO test case.""" + run_test(cfg, "sw", protocol, test_name) + + +def main() -> None: + """ Ksft boiler plate main """ + + with NetDrvEpEnv(__file__) as cfg: + ksft_run(cases=[test], args=(cfg,)) + ksft_exit() + + +if __name__ == "__main__": + main() diff --git a/tools/testing/selftests/drivers/net/settings b/tools/testing/selftests/drivers/net/settings index eef533824a3c..e2206265f67c 100644 --- a/tools/testing/selftests/drivers/net/settings +++ b/tools/testing/selftests/drivers/net/settings @@ -1 +1 @@ -timeout=360 +timeout=900 diff --git a/tools/testing/selftests/net/lib/ksft_setup_loopback.sh b/tools/testing/selftests/net/lib/ksft_setup_loopback.sh index 3defbb1919c5..9ec4c3616795 100755 --- a/tools/testing/selftests/net/lib/ksft_setup_loopback.sh +++ b/tools/testing/selftests/net/lib/ksft_setup_loopback.sh @@ -12,7 +12,7 @@ # # Example use: # export NETIF=eth0 -# ./net/lib/ksft_setup_loopback.sh ./drivers/net/gro.py +# ./net/lib/ksft_setup_loopback.sh ./drivers/net/gro_sw.py if [ -z "$NETIF" ]; then echo "Error: NETIF variable not set"