dev.dpdk.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/3] dts: add tx_offload support in dts
@ 2025-09-02 14:27 Andrew Bailey
  2025-09-02 14:27 ` [PATCH v1 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Andrew Bailey @ 2025-09-02 14:27 UTC (permalink / raw)
  To: luca.vizzarro; +Cc: abailey, dev, dmarx, probb

This patchset introduces the support for TX offload configuration
through DTS, allowing test cases to be written utilizing TX offload
capabilities. Along with configuring these capabilities, they are also
added to the NIC capabilities class, in which they can be required by
test suites. Finally, a test suite was created using the aforementioned
changes to update the RX TX offload test suite in legacy DTS.

Andrew Bailey (3):
  dts: allow mbuf_fast_free to be set with testpmd shell
  dts: add TX offload capabilities to NIC capabilities
  dts: update tx_offload test from old dts

 dts/framework/remote_session/testpmd_shell.py | 340 +++++++++++++++++-
 dts/tests/TestSuite_rxtx_offload.py           | 153 ++++++++
 2 files changed, 492 insertions(+), 1 deletion(-)
 create mode 100644 dts/tests/TestSuite_rxtx_offload.py

--
2.50.1


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

* [PATCH v1 1/3] dts: allow mbuf_fast_free to be set with testpmd shell
  2025-09-02 14:27 [PATCH v1 0/3] dts: add tx_offload support in dts Andrew Bailey
@ 2025-09-02 14:27 ` Andrew Bailey
  2025-09-02 19:37   ` Ivan Malov
  2025-09-02 14:27 ` [PATCH v1 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 16+ messages in thread
From: Andrew Bailey @ 2025-09-02 14:27 UTC (permalink / raw)
  To: luca.vizzarro; +Cc: abailey, dev, dmarx, probb

Currently, there is no way in the testpmd shell class to set the mbuf
fast free offload configuration for RX or TX ports. This prohibits any
test suites to be written utilizing this offload configuration. Additionally,
the NIC capabilities for the TX offload are not gathered. This prevents future
test suites from being skipped if they do not support a TX offload capability.
Introduce methods that support calls to testpmd in order to allow the
configuration of mbuf fast free and to gather TX offload capabilities.

Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
---
 dts/framework/remote_session/testpmd_shell.py | 137 +++++++++++++++++-
 1 file changed, 136 insertions(+), 1 deletion(-)

diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
index 786714d1c5..91642efec5 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -19,7 +19,7 @@
 import time
 from collections.abc import Callable, MutableSet
 from dataclasses import dataclass, field
-from enum import Flag, auto
+from enum import Enum, Flag, auto
 from os import environ
 from pathlib import PurePath
 from typing import TYPE_CHECKING, Any, ClassVar, Concatenate, Literal, ParamSpec, Tuple, TypeAlias
@@ -344,6 +344,13 @@ def make_parser(cls) -> ParserFn:
         )


+class RxTxArgFlag(Enum):
+    """Enum representing receiving or transmitting ports."""
+
+    TX = "tx"
+    RX = "rx"
+
+
 class DeviceCapabilitiesFlag(Flag):
     """Flag representing the device capabilities."""

@@ -2787,6 +2794,134 @@ def get_capabilities_physical_function(
         else:
             unsupported_capabilities.add(NicCapability.PHYSICAL_FUNCTION)

+    @requires_started_ports
+    def get_rxtx_offload_config(
+        self,
+        rxtx: RxTxArgFlag,
+        verify: bool,
+        port_id: int = 0,
+        num_queues: int = 0,
+    ) -> dict[int | str, str]:
+        """Get the RX or TX offload configuration of the queues from the given port.
+
+        Args:
+            rxtx: Whether to get the RX or TX configuration of the given queues.
+            verify: If :data:'True' the output of the command will be scanned in an attempt to
+                verify that the offload configuration was retrieved successfully on all queues.
+            num_queues: The number of queues to get the offload configuration for.
+            port_id: The port ID that contains the desired queues.
+
+        Returns:
+            A dict containing port info at key 'port' and queue info keyed by the appropriate queue
+                id.
+
+        Raises:
+            InteractiveCommandExecutionError: If all queue offload configurations could not be
+                retrieved.
+
+        """
+        returnDict: dict[int | str, str] = {}
+
+        config_output = self.send_command(f"show port {port_id} {rxtx.value}_offload configuration")
+        if verify:
+            if (
+                f"Rx Offloading Configuration of port {port_id}" not in config_output
+                and f"Tx Offloading Configuration of port {port_id}" not in config_output
+            ):
+                self._logger.debug(f"Get port offload config error\n{config_output}")
+                raise InteractiveCommandExecutionError(
+                    f"""Failed to get offload config on port {port_id}:\n{config_output}"""
+                )
+        # Actual output data starts on the thrid line
+        tempList: list[str] = config_output.splitlines()[3::]
+        returnDict["port"] = tempList[0]
+        for i in range(0, num_queues):
+            returnDict[i] = tempList[i + 1]
+        return returnDict
+
+    @requires_stopped_ports
+    def set_port_rxtx_mbuf_fast_free(
+        self, rxtx: RxTxArgFlag, on: bool, verify: bool, port_id: int = 0
+    ) -> None:
+        """Sets the mbuf_fast_free configuration for the RX or TX offload for a given port.
+
+        Args:
+            rxtx: Whether to set the mbuf_fast_free on the RX or TX port.
+            on: If :data:'True' mbuf_fast_free will be enabled, disable it otherwise.
+            verify: If :data:'True' the output of the command will be scanned in an attempt to
+                verify that the mbuf_fast_free was set successfully.
+            port_id: The port number to enable or disable mbuf_fast_free on.
+
+        Raises:
+            InteractiveCommandExecutionError: If mbuf_fast_free could not be set successfully
+        """
+        mbuf_output = self.send_command(
+            f"port config {port_id} {rxtx.value}_offload mbuf_fast_free {"on" if on else "off"}"
+        )
+
+        if "error" in mbuf_output and verify:
+            raise InteractiveCommandExecutionError(
+                f"""Unable to set mbuf_fast_free config on port {port_id}:\n{mbuf_output}"""
+            )
+
+    @requires_stopped_ports
+    def set_queue_rxtx_mbuf_fast_free(
+        self,
+        rxtx: RxTxArgFlag,
+        on: bool,
+        verify: bool,
+        port_id: int = 0,
+        queue_id: int = 0,
+    ) -> None:
+        """Sets RX or TX mbuf_fast_free configuration of the specified queue on a given port.
+
+        Args:
+            rxtx: Whether to set mbuf_fast_free for the RX or TX offload configuration on the
+                given queues.
+            on: If :data:'True' the mbuf_fast_free configuration will be enabled, otherwise
+                disabled.
+            verify: If :data:'True' the output of the command will be scanned in an attempt to
+                verify that mbuf_fast_free was set successfully on all ports.
+            queue_id: The queue to disable mbuf_fast_free on.
+            port_id: The ID of the port containing the queues.
+
+        Raises:
+            InteractiveCommandExecutionError: If all queues could not be set successfully.
+        """
+        toggle = "on" if on else "off"
+        output = self.send_command(
+            f"port {port_id} {rxtx.value}q {queue_id} {rxtx.value}_offload mbuf_fast_free {toggle}"
+        )
+        if verify:
+            if "Error" in output:
+                self._logger.debug(f"Set queue offload config error\n{output}")
+                raise InteractiveCommandExecutionError(
+                    f"Failed to get offload config on port {port_id}, queue {queue_id}:\n{output}"
+                )
+
+    def set_all_queues_rxtx_mbuf_fast_free(
+        self,
+        rxtx: RxTxArgFlag,
+        on: bool,
+        verify: bool,
+        port_id=0,
+        num_queues: int = 0,
+    ) -> None:
+        """Sets mbuf_fast_free configuration for the RX or TX offload of all queues on a given port.
+
+        Args:
+            rxtx: Whether to set mbuf_fast_free for the RX or TX offload configuration on the
+                given queues.
+            on: If :data:'True' the mbuf fast_free_configuration will be enabled, otherwise
+                disabled.
+            verify: If :data:'True' the output of the command will be scanned in an attempt to
+                verify that mbuf_fast_free was set successfully on all ports.
+            port_id: The ID of the port containing the queues.
+            num_queues: The queue to disable mbuf_fast_free on.
+        """
+        for i in range(0, num_queues):
+            self.set_queue_rxtx_mbuf_fast_free(rxtx, on, verify, port_id=port_id, queue_id=i)
+

 class NicCapability(NoAliasEnum):
     """A mapping between capability names and the associated :class:`TestPmdShell` methods.
--
2.50.1


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

* [PATCH v1 2/3] dts: add TX offload capabilities to NIC capabilities
  2025-09-02 14:27 [PATCH v1 0/3] dts: add tx_offload support in dts Andrew Bailey
  2025-09-02 14:27 ` [PATCH v1 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
@ 2025-09-02 14:27 ` Andrew Bailey
  2025-09-04 14:43   ` Luca Vizzarro
  2025-09-02 14:27 ` [PATCH v1 3/3] dts: update tx_offload test from old dts Andrew Bailey
  2025-09-03 18:04 ` [PATCH v2 0/3] dts: add tx_offlaod support in dts Andrew Bailey
  3 siblings, 1 reply; 16+ messages in thread
From: Andrew Bailey @ 2025-09-02 14:27 UTC (permalink / raw)
  To: luca.vizzarro; +Cc: abailey, dev, dmarx, probb

Currently, there is support for tracking the RX offload capabilities of
a NIC, but not for TX offload capabilities. This is an issue if a test
suite is written requiring one of these capabilities, since there is no
way currently to verify that the NIC in use meets the requirements. Add
TX capabilities to the NIC capabiltiies at beginning of dts so
requirements can be verified.

Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
---
 dts/framework/remote_session/testpmd_shell.py | 203 ++++++++++++++++++
 1 file changed, 203 insertions(+)

diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
index ad8cb273dc..786714d1c5 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -1278,6 +1278,99 @@ class TestPmdVerbosePacket(TextParser):
     )


+class TxOffloadCapability(Flag):
+    """TX offload capabilities of a device.
+
+    The flags are taken from ``lib/ethdev/rte_ethdev.h``.
+    They're prefixed with ``RTE_ETH_TX_OFFLOAD`` in ``lib/ethdev/rte_ethdev.h``
+    instead of ``TX_OFFLOAD``, which is what testpmd changes the prefix to.
+    The values are not contiguous, so the correspondence is preserved
+    by specifying concrete values interspersed between auto() values.
+
+    The ``TX_OFFLOAD`` prefix has been preserved so that the same flag names can be used
+    in :class:`NicCapability`. The prefix is needed in :class:`NicCapability` since there's
+    no other qualifier which would sufficiently distinguish it from other capabilities.
+
+    References:
+        DPDK lib: ``lib/ethdev/rte_ethdev.h``
+        testpmd display function: ``app/test-pmd/cmdline.c:print_rx_offloads()``
+    """
+
+    TX_OFFLOAD_VLAN_INSERT = auto()
+    TX_OFFLOAD_IPV4_CKSUM = auto()
+    TX_OFFLOAD_UDP_CKSUM = auto()
+    TX_OFFLOAD_TCP_CKSUM = auto()
+    TX_OFFLOAD_SCTP_CKSUM = auto()
+    TX_OFFLOAD_TCP_TSO = auto()
+    TX_OFFLOAD_UDP_TSO = auto()
+    TX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
+    TX_OFFLOAD_QINQ_INSERT = auto()
+    TX_OFFLOAD_VXLAN_TNL_TSO = auto()
+    TX_OFFLOAD_GRE_TNL_TSO = auto()
+    TX_OFFLOAD_IPIP_TNL_TSO = auto()
+    TX_OFFLOAD_GENEVE_TNL_TSO = auto()
+    TX_OFFLOAD_MACSEC_INSERT = auto()
+    TX_OFFLOAD_MT_LOCKFREE = auto()
+    TX_OFFLOAD_MULTI_SEGS = auto()
+    TX_OFFLOAD_MBUF_FAST_FREE = auto()
+    TX_OFFLOAD_SECURITY = auto()
+    TX_OFFLOAD_UDP_TNL_TSO = auto()
+    TX_OFFLOAD_IP_TNL_TSO = auto()
+    TX_OFFLOAD_OUTER_UDP_CKSUM = auto()
+    TX_OFFLOAD_SEND_ON_TIMESTAMP = auto()
+
+    @classmethod
+    def from_string(cls, line: str) -> Self:
+        """Make an instance from a string containing the flag names separated with a space.
+
+        Args:
+            line: The line to parse.
+
+        Returns:
+            A new instance containing all found flags.
+        """
+        flag = cls(0)
+        for flag_name in line.split():
+            flag |= cls[f"TX_OFFLOAD_{flag_name}"]
+        return flag
+
+    @classmethod
+    def make_parser(cls, per_port: bool) -> ParserFn:
+        """Make a parser function.
+
+        Args:
+            per_port: If :data:`True`, will return capabilities per port. If :data:`False`,
+                will return capabilities per queue.
+
+        Returns:
+            ParserFn: A dictionary for the `dataclasses.field` metadata argument containing a
+                parser function that makes an instance of this flag from text.
+        """
+        granularity = "Port" if per_port else "Queue"
+        return TextParser.wrap(
+            TextParser.find(rf"Per {granularity}\s+:(.*)$", re.MULTILINE),
+            cls.from_string,
+        )
+
+
+@dataclass
+class TxOffloadCapabilities(TextParser):
+    """The result of testpmd's ``show port <port_id> tx_offload capabilities`` command.
+
+    References:
+        testpmd command function: ``app/test-pmd/cmdline.c:cmd_tx_offload_get_capa()``
+        testpmd display function: ``app/test-pmd/cmdline.c:cmd_tx_offload_get_capa_parsed()``
+    """
+
+    port_id: int = field(
+        metadata=TextParser.find_int(r"Tx Offloading Capabilities of port (\d+) :")
+    )
+    #: Per-queue Tx offload capabilities.
+    per_queue: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(False))
+    #: Capabilities other than per-queue Tx offload capabilities.
+    per_port: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(True))
+
+
 class RxOffloadCapability(Flag):
     """Rx offload capabilities of a device.

@@ -2390,6 +2483,28 @@ def close(self) -> None:
     ====== Capability retrieval methods ======
     """

+    def get_capabilities_tx_offload(
+        self,
+        supported_capabilities: MutableSet["NicCapability"],
+        unsupported_capabilities: MutableSet["NicCapability"],
+    ) -> None:
+        """Get all TX offload capabilities and divide them into supported and unsupported.
+
+        Args:
+            supported_capabilities: Supported capabilities will be added to this set.
+            unsupported_capabilities: Unsupported capabilities will be added to this set.
+        """
+        self._logger.debug("Getting TX offload capabilities.")
+        command = f"show port {self.ports[0].id} tx_offload capabilities"
+        tx_offload_capabilities_out = self.send_command(command)
+        tx_offload_capabilities = TxOffloadCapabilities.parse(tx_offload_capabilities_out)
+        self._update_capabilities_from_flag(
+            supported_capabilities,
+            unsupported_capabilities,
+            TxOffloadCapability,
+            tx_offload_capabilities.per_port | tx_offload_capabilities.per_queue,
+        )
+
     def get_capabilities_rx_offload(
         self,
         supported_capabilities: MutableSet["NicCapability"],
@@ -2698,6 +2813,94 @@ class NicCapability(NoAliasEnum):
     we don't go looking for it again if a different test case also needs it.
     """

+    TX_OFFLOAD_VLAN_INSERT: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_IPV4_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_UDP_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_TCP_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_SCTP_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_TCP_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_UDP_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_QINQ_INSERT: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_MACSEC_INSERT: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_MT_LOCKFREE: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_MULTI_SEGS: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_SECURITY: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_IP_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_SEND_ON_TIMESTAMP: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
     #: Scattered packets Rx enabled
     SCATTERED_RX_ENABLED: TestPmdShellNicCapability = (
         TestPmdShell.get_capabilities_rxq_info,
--
2.50.1


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

* [PATCH v1 3/3] dts: update tx_offload test from old dts
  2025-09-02 14:27 [PATCH v1 0/3] dts: add tx_offload support in dts Andrew Bailey
  2025-09-02 14:27 ` [PATCH v1 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
  2025-09-02 14:27 ` [PATCH v1 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
@ 2025-09-02 14:27 ` Andrew Bailey
  2025-09-03 18:04 ` [PATCH v2 0/3] dts: add tx_offlaod support in dts Andrew Bailey
  3 siblings, 0 replies; 16+ messages in thread
From: Andrew Bailey @ 2025-09-02 14:27 UTC (permalink / raw)
  To: luca.vizzarro; +Cc: abailey, dev, dmarx, probb

Currently, the RX/TX offload test in old DTS expects the TX ports to be
initially configured to use mbuf fast free. This is no longer the case
and must be updated to assume mbuf fast free is not initially utilized
by capable NICs. Add updated test suite to test mbuf fast free
configuration.

Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
---
 dts/tests/TestSuite_rxtx_offload.py | 153 ++++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)
 create mode 100644 dts/tests/TestSuite_rxtx_offload.py

diff --git a/dts/tests/TestSuite_rxtx_offload.py b/dts/tests/TestSuite_rxtx_offload.py
new file mode 100644
index 0000000000..f4a51a5eed
--- /dev/null
+++ b/dts/tests/TestSuite_rxtx_offload.py
@@ -0,0 +1,153 @@
+# Copyright(c) 2025 University of New Hampshire
+
+"""RX TX offload test suite.
+
+Test the testpmd feature of configuring RX and TX offloads
+"""
+
+from framework.remote_session.testpmd_shell import (
+    NicCapability,
+    RxTxArgFlag,
+    TestPmdShell,
+)
+from framework.test_suite import TestSuite, func_test
+from framework.testbed_model.capability import requires
+
+
+@requires(NicCapability.TX_OFFLOAD_MBUF_FAST_FREE)
+class TestRxTxOffload(TestSuite):
+    """RX/TX offload test suite."""
+
+    def check_port_config(
+        self,
+        testpmd: TestPmdShell,
+        offload: str,
+        rxtx: RxTxArgFlag,
+        verify: bool,
+        port_id: int = 0,
+    ) -> bool:
+        """Checks that the current port configuration matches the given offload.
+
+        Args:
+            testpmd: The currrent testpmd shell session to send commands to.
+            offload: The expected configuration of the given port.
+            rxtx: Whether to check the RX or TX configuration of the given port.
+            verify: Whether to verify the result of call to testpmd.
+            port_id: Id of the port to check.
+
+        Returns:
+            Whether current configuration matches given offload.
+        """
+        output = testpmd.get_rxtx_offload_config(rxtx, verify, port_id, 0)
+        return offload in output["port"] or (
+            offload == "NULL" and "MBUF_FAST_FREE" not in output["port"]
+        )
+
+    def check_queue_config(
+        self,
+        testpmd: TestPmdShell,
+        offload: list[str],
+        rxtx: RxTxArgFlag,
+        verify: bool,
+        port_id: int = 0,
+        num_queues: int = 0,
+    ) -> bool:
+        """Checks that the queue configuration matches the given offload.
+
+        Args:
+            testpmd: The currrent testpmd shell session to send commands to.
+            offload: The expected configuration of the queues, each index corresponds
+                to the queue id.
+            rxtx: Whether to check the RX or TX configuration of the given queues.
+            verify: Whether to verify commands sent to testpmd.
+            port_id: The port of which the queues reside.
+            num_queues: The number of queues to check.
+
+        Returns:
+            Whether current configuration matches given offload
+        """
+        output = testpmd.get_rxtx_offload_config(rxtx, verify, port_id, num_queues)
+        for i in range(0, num_queues):
+            if not (
+                offload[i] in output[i]
+                or (offload[i] == "NULL" and "MBUF_FAST_FREE" not in output[i])
+            ):
+                return False
+        return True
+
+    @func_test
+    def test_mbuf_fast_free_configurations(self) -> None:
+        """Ensure mbuf_fast_free can be configured with testpmd.
+
+        Steps:
+            Start up testpmd shell.
+            Toggle mbuf_fast_free on.
+            Toggle mbuf_fast_free off.
+
+        Verify:
+            Mbuf_fast_free starts disabled.
+            Mbuf_fast_free can be configured on.
+            Mbuf_fast_free can be configured off.
+        """
+        with TestPmdShell() as testpmd:
+            verify: bool = True
+            port_id: int = 0
+            num_queues: int = 4
+            queue_off: list[str] = []
+            queue_on: list[str] = []
+            mbuf_on = "MBUF_FAST_FREE"
+            mbuf_off = "NULL"
+            tx = RxTxArgFlag.TX
+
+            for _ in range(0, num_queues):
+                queue_off.append(mbuf_off)
+                queue_on.append(mbuf_on)
+
+            testpmd.set_ports_queues(num_queues)
+            testpmd.start_all_ports()
+
+            # Ensure mbuf_fast_free is disabled by default on port and queues
+            self.verify(
+                self.check_port_config(testpmd, mbuf_off, tx, verify, port_id),
+                "Mbuf_fast_free enabled on port start",
+            )
+            self.verify(
+                self.check_queue_config(testpmd, queue_off, tx, verify, port_id, num_queues),
+                "Mbuf_fast_free enabled on queue start",
+            )
+
+            # Enable mbuf_fast_free per queue and verify
+            testpmd.set_all_queues_rxtx_mbuf_fast_free(tx, True, verify, port_id, num_queues)
+            self.verify(
+                self.check_port_config(testpmd, mbuf_off, tx, verify, port_id),
+                "Port configuration changed without call",
+            )
+            self.verify(
+                self.check_queue_config(testpmd, queue_on, tx, verify, port_id, num_queues),
+                "Queues failed to enable mbuf_fast_free",
+            )
+
+            # Enable mbuf_fast_free per port and verify
+            testpmd.set_port_rxtx_mbuf_fast_free(tx, True, verify, port_id)
+            self.verify(
+                self.check_port_config(testpmd, mbuf_on, tx, verify, port_id),
+                "Port failed to enable mbuf_fast_free",
+            )
+
+            # Disable mbuf_fast_free per queue and verify
+            testpmd.set_all_queues_rxtx_mbuf_fast_free(tx, False, verify, port_id, num_queues)
+            self.verify(
+                self.check_port_config(testpmd, mbuf_on, tx, verify, port_id),
+                "Port configuration changed without call",
+            )
+            self.verify(
+                self.check_queue_config(testpmd, queue_off, tx, verify, port_id, num_queues),
+                "Queues failed to disable mbuf_fast_free",
+            )
+
+            # Disable mbuf_fast_free per port and verify
+            testpmd.set_port_rxtx_mbuf_fast_free(tx, False, verify, port_id)
+            self.verify(
+                self.check_port_config(testpmd, mbuf_off, tx, verify, port_id),
+                "Port failed to disable mbuf_fast_free",
+            )
--
2.50.1


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

* Re: [PATCH v1 1/3] dts: allow mbuf_fast_free to be set with testpmd shell
  2025-09-02 14:27 ` [PATCH v1 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
@ 2025-09-02 19:37   ` Ivan Malov
  2025-09-02 19:48     ` Ivan Malov
  0 siblings, 1 reply; 16+ messages in thread
From: Ivan Malov @ 2025-09-02 19:37 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: luca.vizzarro, dev, dmarx, probb

Hi Andrew,

On Tue, 2 Sep 2025, Andrew Bailey wrote:

> Currently, there is no way in the testpmd shell class to set the mbuf
> fast free offload configuration for RX or TX ports. This prohibits any

To me, this reads like some ports can be Rx-only while others can be Tx-only,
which is a little bit confusing. Also, let's double check that it makes to talk
about the 'mbuf fast free offload' in the context of an Rx queue; -- it was my
impression that this offload is only applicable to Tx queues, as they are meant
to 'reap' mbufs associated with 'done' Tx descriptors. Am I missing something?

> test suites to be written utilizing this offload configuration. Additionally,
> the NIC capabilities for the TX offload are not gathered. This prevents future
> test suites from being skipped if they do not support a TX offload capability.
> Introduce methods that support calls to testpmd in order to allow the
> configuration of mbuf fast free and to gather TX offload capabilities.

This added ability to collect Tx offload capability info is good.

One more point to consider: this handles 'mbuf_fast_free' on per-queue level,
but if it is valid on port-global level, too, may be one can also cover that.

>
> Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
> ---
> dts/framework/remote_session/testpmd_shell.py | 137 +++++++++++++++++-
> 1 file changed, 136 insertions(+), 1 deletion(-)
>
> diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
> index 786714d1c5..91642efec5 100644
> --- a/dts/framework/remote_session/testpmd_shell.py
> +++ b/dts/framework/remote_session/testpmd_shell.py
> @@ -19,7 +19,7 @@
> import time
> from collections.abc import Callable, MutableSet
> from dataclasses import dataclass, field
> -from enum import Flag, auto
> +from enum import Enum, Flag, auto
> from os import environ
> from pathlib import PurePath
> from typing import TYPE_CHECKING, Any, ClassVar, Concatenate, Literal, ParamSpec, Tuple, TypeAlias
> @@ -344,6 +344,13 @@ def make_parser(cls) -> ParserFn:
>         )
>
>
> +class RxTxArgFlag(Enum):
> +    """Enum representing receiving or transmitting ports."""
> +
> +    TX = "tx"
> +    RX = "rx"
> +
> +
> class DeviceCapabilitiesFlag(Flag):
>     """Flag representing the device capabilities."""
>
> @@ -2787,6 +2794,134 @@ def get_capabilities_physical_function(
>         else:
>             unsupported_capabilities.add(NicCapability.PHYSICAL_FUNCTION)
>
> +    @requires_started_ports
> +    def get_rxtx_offload_config(
> +        self,
> +        rxtx: RxTxArgFlag,
> +        verify: bool,
> +        port_id: int = 0,
> +        num_queues: int = 0,
> +    ) -> dict[int | str, str]:
> +        """Get the RX or TX offload configuration of the queues from the given port.
> +
> +        Args:
> +            rxtx: Whether to get the RX or TX configuration of the given queues.
> +            verify: If :data:'True' the output of the command will be scanned in an attempt to
> +                verify that the offload configuration was retrieved successfully on all queues.
> +            num_queues: The number of queues to get the offload configuration for.
> +            port_id: The port ID that contains the desired queues.
> +
> +        Returns:
> +            A dict containing port info at key 'port' and queue info keyed by the appropriate queue
> +                id.
> +
> +        Raises:
> +            InteractiveCommandExecutionError: If all queue offload configurations could not be
> +                retrieved.
> +
> +        """
> +        returnDict: dict[int | str, str] = {}
> +
> +        config_output = self.send_command(f"show port {port_id} {rxtx.value}_offload configuration")
> +        if verify:
> +            if (
> +                f"Rx Offloading Configuration of port {port_id}" not in config_output
> +                and f"Tx Offloading Configuration of port {port_id}" not in config_output
> +            ):
> +                self._logger.debug(f"Get port offload config error\n{config_output}")
> +                raise InteractiveCommandExecutionError(
> +                    f"""Failed to get offload config on port {port_id}:\n{config_output}"""
> +                )
> +        # Actual output data starts on the thrid line
> +        tempList: list[str] = config_output.splitlines()[3::]
> +        returnDict["port"] = tempList[0]
> +        for i in range(0, num_queues):
> +            returnDict[i] = tempList[i + 1]
> +        return returnDict
> +
> +    @requires_stopped_ports
> +    def set_port_rxtx_mbuf_fast_free(
> +        self, rxtx: RxTxArgFlag, on: bool, verify: bool, port_id: int = 0
> +    ) -> None:
> +        """Sets the mbuf_fast_free configuration for the RX or TX offload for a given port.
> +
> +        Args:
> +            rxtx: Whether to set the mbuf_fast_free on the RX or TX port.
> +            on: If :data:'True' mbuf_fast_free will be enabled, disable it otherwise.
> +            verify: If :data:'True' the output of the command will be scanned in an attempt to
> +                verify that the mbuf_fast_free was set successfully.
> +            port_id: The port number to enable or disable mbuf_fast_free on.
> +
> +        Raises:
> +            InteractiveCommandExecutionError: If mbuf_fast_free could not be set successfully
> +        """
> +        mbuf_output = self.send_command(
> +            f"port config {port_id} {rxtx.value}_offload mbuf_fast_free {"on" if on else "off"}"
> +        )
> +
> +        if "error" in mbuf_output and verify:
> +            raise InteractiveCommandExecutionError(
> +                f"""Unable to set mbuf_fast_free config on port {port_id}:\n{mbuf_output}"""
> +            )
> +
> +    @requires_stopped_ports
> +    def set_queue_rxtx_mbuf_fast_free(
> +        self,
> +        rxtx: RxTxArgFlag,

So this is questionable. Please see below.

> +        on: bool,
> +        verify: bool,
> +        port_id: int = 0,
> +        queue_id: int = 0,
> +    ) -> None:
> +        """Sets RX or TX mbuf_fast_free configuration of the specified queue on a given port.
> +
> +        Args:
> +            rxtx: Whether to set mbuf_fast_free for the RX or TX offload configuration on the
> +                given queues.
> +            on: If :data:'True' the mbuf_fast_free configuration will be enabled, otherwise
> +                disabled.
> +            verify: If :data:'True' the output of the command will be scanned in an attempt to
> +                verify that mbuf_fast_free was set successfully on all ports.
> +            queue_id: The queue to disable mbuf_fast_free on.
> +            port_id: The ID of the port containing the queues.
> +
> +        Raises:
> +            InteractiveCommandExecutionError: If all queues could not be set successfully.
> +        """
> +        toggle = "on" if on else "off"
> +        output = self.send_command(
> +            f"port {port_id} {rxtx.value}q {queue_id} {rxtx.value}_offload mbuf_fast_free {toggle}"

For me, on a slightly dated DPDK build, setting this on an Rx queue fails:

testpmd> port 0 rxq 0 rx_offload mbuf_fast_free off
Bad arguments

An equivalent Tx command works, albeit unsupported in my specific circumstances.

testpmd> port 0 txq 0 tx_offload mbuf_fast_free off
Error: port 0 doesn't support per queue offload: mbuf_fast_free.

> +        )
> +        if verify:
> +            if "Error" in output:
> +                self._logger.debug(f"Set queue offload config error\n{output}")
> +                raise InteractiveCommandExecutionError(
> +                    f"Failed to get offload config on port {port_id}, queue {queue_id}:\n{output}"
> +                )
> +
> +    def set_all_queues_rxtx_mbuf_fast_free(
> +        self,
> +        rxtx: RxTxArgFlag,
> +        on: bool,
> +        verify: bool,
> +        port_id=0,
> +        num_queues: int = 0,
> +    ) -> None:
> +        """Sets mbuf_fast_free configuration for the RX or TX offload of all queues on a given port.
> +
> +        Args:
> +            rxtx: Whether to set mbuf_fast_free for the RX or TX offload configuration on the
> +                given queues.
> +            on: If :data:'True' the mbuf fast_free_configuration will be enabled, otherwise
> +                disabled.
> +            verify: If :data:'True' the output of the command will be scanned in an attempt to
> +                verify that mbuf_fast_free was set successfully on all ports.
> +            port_id: The ID of the port containing the queues.
> +            num_queues: The queue to disable mbuf_fast_free on.

While I'm not well-versed in DTS style in general and cannot push to choose
some specific naming, I'd say, to me, 'queue_ids' would read less ambiguous.

Thank you.

> +        """
> +        for i in range(0, num_queues):
> +            self.set_queue_rxtx_mbuf_fast_free(rxtx, on, verify, port_id=port_id, queue_id=i)
> +
>
> class NicCapability(NoAliasEnum):
>     """A mapping between capability names and the associated :class:`TestPmdShell` methods.
> --
> 2.50.1
>
>

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

* Re: [PATCH v1 1/3] dts: allow mbuf_fast_free to be set with testpmd shell
  2025-09-02 19:37   ` Ivan Malov
@ 2025-09-02 19:48     ` Ivan Malov
  0 siblings, 0 replies; 16+ messages in thread
From: Ivan Malov @ 2025-09-02 19:48 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: luca.vizzarro, dev, dmarx, probb

On Tue, 2 Sep 2025, Ivan Malov wrote:

<snip>

>> +            port_id: The ID of the port containing the queues.
>> +            num_queues: The queue to disable mbuf_fast_free on.
>
> While I'm not well-versed in DTS style in general and cannot push to choose
> some specific naming, I'd say, to me, 'queue_ids' would read less ambiguous.
>

Sorry, I now see this is not a queue ID array but the total number of queues. If
so, the description should be corrected to say so. Right now it reads like this
is a specific queue index.

Thank you.

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

* [PATCH v2 0/3] dts: add tx_offlaod support in dts
  2025-09-02 14:27 [PATCH v1 0/3] dts: add tx_offload support in dts Andrew Bailey
                   ` (2 preceding siblings ...)
  2025-09-02 14:27 ` [PATCH v1 3/3] dts: update tx_offload test from old dts Andrew Bailey
@ 2025-09-03 18:04 ` Andrew Bailey
  2025-09-03 18:04   ` [PATCH v2 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
                     ` (2 more replies)
  3 siblings, 3 replies; 16+ messages in thread
From: Andrew Bailey @ 2025-09-03 18:04 UTC (permalink / raw)
  To: luca.vizzarro; +Cc: abailey, dev, dmarx, ivan.malov, probb

This patchset introduces the support for Tx offload configuration
through DTS, allowing test cases to be written utilizing Tx offload
capabilities. Along with configuring these capabilities, they are also
added to the NIC capabilities class, in which they can be required by
test suites. Finally, a test suite was created using the aforementioned
changes to update the Rx\Tx offload test suite in legacy DTS.

---
v2:
* Removed mentions of mbuf_fast_free being configured for Rx queues/ports
  as this is not accurate behaviour.
* Clarify argument descriptions in docstrings.

Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>

Andrew Bailey (3):
  dts: allow mbuf_fast_free to be set with testpmd shell
  dts: add TX offload capabilities to NIC capabilities
  dts: update tx_offload test from old dts

 dts/framework/remote_session/testpmd_shell.py | 333 +++++++++++++++++-
 dts/tests/TestSuite_rxtx_offload.py           | 150 ++++++++
 2 files changed, 482 insertions(+), 1 deletion(-)
 create mode 100644 dts/tests/TestSuite_rxtx_offload.py

--
2.50.1


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

* [PATCH v2 1/3] dts: allow mbuf_fast_free to be set with testpmd shell
  2025-09-03 18:04 ` [PATCH v2 0/3] dts: add tx_offlaod support in dts Andrew Bailey
@ 2025-09-03 18:04   ` Andrew Bailey
  2025-09-04 15:15     ` Luca Vizzarro
  2025-09-03 18:04   ` [PATCH v2 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
  2025-09-03 18:04   ` [PATCH v2 3/3] dts: update tx_offload test from old dts Andrew Bailey
  2 siblings, 1 reply; 16+ messages in thread
From: Andrew Bailey @ 2025-09-03 18:04 UTC (permalink / raw)
  To: luca.vizzarro; +Cc: abailey, dev, dmarx, ivan.malov, probb

Currently, there is no way in the testpmd shell class to set the mbuf
fast free offload configuration for queues or ports. This prohibits any
test suites to be written utilizing this offload configuration.
Additionally, the NIC capabilities for the Tx offload are not gathered.
This prevents future test suites from being skipped if they do not
support a Tx offload capability. Introduce methods that support calls
to testpmd in order to allow the configuration of mbuf fast free and to
gather Tx offload capabilities.

Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
---
 dts/framework/remote_session/testpmd_shell.py | 128 +++++++++++++++++-
 1 file changed, 127 insertions(+), 1 deletion(-)

diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
index ad8cb273dc..4d9caceb37 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -19,7 +19,7 @@
 import time
 from collections.abc import Callable, MutableSet
 from dataclasses import dataclass, field
-from enum import Flag, auto
+from enum import Enum, Flag, auto
 from os import environ
 from pathlib import PurePath
 from typing import TYPE_CHECKING, Any, ClassVar, Concatenate, Literal, ParamSpec, Tuple, TypeAlias
@@ -344,6 +344,13 @@ def make_parser(cls) -> ParserFn:
         )
 
 
+class RxTxArgFlag(Enum):
+    """Enum representing receiving or transmitting ports."""
+
+    TX = "tx"
+    RX = "rx"
+
+
 class DeviceCapabilitiesFlag(Flag):
     """Flag representing the device capabilities."""
 
@@ -2672,6 +2679,125 @@ def get_capabilities_physical_function(
         else:
             unsupported_capabilities.add(NicCapability.PHYSICAL_FUNCTION)
 
+    @requires_started_ports
+    def get_rxtx_offload_config(
+        self,
+        rxtx: RxTxArgFlag,
+        verify: bool,
+        port_id: int = 0,
+        num_queues: int = 0,
+    ) -> dict[int | str, str]:
+        """Get the Rx or Tx offload configuration of the queues from the given port.
+
+        Args:
+            rxtx: Whether to get the Rx or Tx configuration of the given queues.
+            verify: If :data:'True' the output of the command will be scanned in an attempt to
+                verify that the offload configuration was retrieved successfully on all queues.
+            port_id: The port ID that contains the desired queues.
+            num_queues: The number of queues to get the offload configuration for.
+
+        Returns:
+            A dict containing port info at key 'port' and queue info keyed by the appropriate queue
+                id.
+
+        Raises:
+            InteractiveCommandExecutionError: If all queue offload configurations could not be
+                retrieved.
+
+        """
+        returnDict: dict[int | str, str] = {}
+
+        config_output = self.send_command(f"show port {port_id} {rxtx.value}_offload configuration")
+        if verify:
+            if (
+                f"Rx Offloading Configuration of port {port_id}" not in config_output
+                and f"Tx Offloading Configuration of port {port_id}" not in config_output
+            ):
+                self._logger.debug(f"Get port offload config error\n{config_output}")
+                raise InteractiveCommandExecutionError(
+                    f"""Failed to get offload config on port {port_id}:\n{config_output}"""
+                )
+        # Actual output data starts on the third line
+        tempList: list[str] = config_output.splitlines()[3::]
+        returnDict["port"] = tempList[0]
+        for i in range(0, num_queues):
+            returnDict[i] = tempList[i + 1]
+        return returnDict
+
+    @requires_stopped_ports
+    def set_port_mbuf_fast_free(self, on: bool, verify: bool, port_id: int = 0) -> None:
+        """Sets the mbuf_fast_free configuration for the Tx offload for a given port.
+
+        Args:
+            on: If :data:'True' mbuf_fast_free will be enabled, disable it otherwise.
+            verify: If :data:'True' the output of the command will be scanned in an attempt to
+                verify that the mbuf_fast_free was set successfully.
+            port_id: The port number to enable or disable mbuf_fast_free on.
+
+        Raises:
+            InteractiveCommandExecutionError: If mbuf_fast_free could not be set successfully
+        """
+        mbuf_output = self.send_command(
+            f"port config {port_id} tx_offload mbuf_fast_free {"on" if on else "off"}"
+        )
+
+        if "error" in mbuf_output and verify:
+            raise InteractiveCommandExecutionError(
+                f"""Unable to set mbuf_fast_free config on port {port_id}:\n{mbuf_output}"""
+            )
+
+    @requires_stopped_ports
+    def set_queue_mbuf_fast_free(
+        self,
+        on: bool,
+        verify: bool,
+        port_id: int = 0,
+        queue_id: int = 0,
+    ) -> None:
+        """Sets the Tx mbuf_fast_free configuration of the specified queue on a given port.
+
+        Args:
+            on: If :data:'True' the mbuf_fast_free configuration will be enabled, otherwise
+                disabled.
+            verify: If :data:'True' the output of the command will be scanned in an attempt to
+                verify that mbuf_fast_free was set successfully on all ports.
+            port_id: The ID of the port containing the queues.
+            queue_id: The queue to disable mbuf_fast_free on.
+
+        Raises:
+            InteractiveCommandExecutionError: If all queues could not be set successfully.
+        """
+        toggle = "on" if on else "off"
+        output = self.send_command(
+            f"port {port_id} txq {queue_id} tx_offload mbuf_fast_free {toggle}"
+        )
+        if verify:
+            if "Error" in output:
+                self._logger.debug(f"Set queue offload config error\n{output}")
+                raise InteractiveCommandExecutionError(
+                    f"Failed to get offload config on port {port_id}, queue {queue_id}:\n{output}"
+                )
+
+    def set_all_queues_mbuf_fast_free(
+        self,
+        on: bool,
+        verify: bool,
+        port_id=0,
+        num_queues: int = 0,
+    ) -> None:
+        """Sets mbuf_fast_free configuration for the Tx offload of all queues on a given port.
+
+        Args:
+            on: If :data:'True' the mbuf_fast_free configuration will be enabled, otherwise
+                disabled.
+            verify: If :data:'True' the output of the command will be scanned in an attempt to
+                verify that mbuf_fast_free was set successfully on all ports.
+            port_id: The ID of the port containing the queues.
+            num_queues: The amount of queues to disable mbuf_fast_free on.
+        """
+        for i in range(0, num_queues):
+            self.set_queue_mbuf_fast_free(on, verify, port_id=port_id, queue_id=i)
+
 
 class NicCapability(NoAliasEnum):
     """A mapping between capability names and the associated :class:`TestPmdShell` methods.
-- 
2.50.1


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

* [PATCH v2 2/3] dts: add TX offload capabilities to NIC capabilities
  2025-09-03 18:04 ` [PATCH v2 0/3] dts: add tx_offlaod support in dts Andrew Bailey
  2025-09-03 18:04   ` [PATCH v2 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
@ 2025-09-03 18:04   ` Andrew Bailey
  2025-09-03 18:36     ` Patrick Robb
  2025-09-04 14:47     ` Luca Vizzarro
  2025-09-03 18:04   ` [PATCH v2 3/3] dts: update tx_offload test from old dts Andrew Bailey
  2 siblings, 2 replies; 16+ messages in thread
From: Andrew Bailey @ 2025-09-03 18:04 UTC (permalink / raw)
  To: luca.vizzarro; +Cc: abailey, dev, dmarx, ivan.malov, probb

Currently, there is support for tracking the Rx offload capabilities of
a NIC, but not for Tx offload capabilities. This is an issue if a test
suite is written requiring one of these capabilities, since there is no
way currently to verify that the NIC in use meets the requirements. Add
Tx capabilities to the NIC capabilities at beginning of dts so
requirements can be verified.

Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
---
 dts/framework/remote_session/testpmd_shell.py | 203 ++++++++++++++++++
 1 file changed, 203 insertions(+)

diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
index 4d9caceb37..dfd83ebdb3 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -1285,6 +1285,99 @@ class TestPmdVerbosePacket(TextParser):
     )
 
 
+class TxOffloadCapability(Flag):
+    """TX offload capabilities of a device.
+
+    The flags are taken from ``lib/ethdev/rte_ethdev.h``.
+    They're prefixed with ``RTE_ETH_TX_OFFLOAD`` in ``lib/ethdev/rte_ethdev.h``
+    instead of ``TX_OFFLOAD``, which is what testpmd changes the prefix to.
+    The values are not contiguous, so the correspondence is preserved
+    by specifying concrete values interspersed between auto() values.
+
+    The ``TX_OFFLOAD`` prefix has been preserved so that the same flag names can be used
+    in :class:`NicCapability`. The prefix is needed in :class:`NicCapability` since there's
+    no other qualifier which would sufficiently distinguish it from other capabilities.
+
+    References:
+        DPDK lib: ``lib/ethdev/rte_ethdev.h``
+        testpmd display function: ``app/test-pmd/cmdline.c:print_rx_offloads()``
+    """
+
+    TX_OFFLOAD_VLAN_INSERT = auto()
+    TX_OFFLOAD_IPV4_CKSUM = auto()
+    TX_OFFLOAD_UDP_CKSUM = auto()
+    TX_OFFLOAD_TCP_CKSUM = auto()
+    TX_OFFLOAD_SCTP_CKSUM = auto()
+    TX_OFFLOAD_TCP_TSO = auto()
+    TX_OFFLOAD_UDP_TSO = auto()
+    TX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
+    TX_OFFLOAD_QINQ_INSERT = auto()
+    TX_OFFLOAD_VXLAN_TNL_TSO = auto()
+    TX_OFFLOAD_GRE_TNL_TSO = auto()
+    TX_OFFLOAD_IPIP_TNL_TSO = auto()
+    TX_OFFLOAD_GENEVE_TNL_TSO = auto()
+    TX_OFFLOAD_MACSEC_INSERT = auto()
+    TX_OFFLOAD_MT_LOCKFREE = auto()
+    TX_OFFLOAD_MULTI_SEGS = auto()
+    TX_OFFLOAD_MBUF_FAST_FREE = auto()
+    TX_OFFLOAD_SECURITY = auto()
+    TX_OFFLOAD_UDP_TNL_TSO = auto()
+    TX_OFFLOAD_IP_TNL_TSO = auto()
+    TX_OFFLOAD_OUTER_UDP_CKSUM = auto()
+    TX_OFFLOAD_SEND_ON_TIMESTAMP = auto()
+
+    @classmethod
+    def from_string(cls, line: str) -> Self:
+        """Make an instance from a string containing the flag names separated with a space.
+
+        Args:
+            line: The line to parse.
+
+        Returns:
+            A new instance containing all found flags.
+        """
+        flag = cls(0)
+        for flag_name in line.split():
+            flag |= cls[f"TX_OFFLOAD_{flag_name}"]
+        return flag
+
+    @classmethod
+    def make_parser(cls, per_port: bool) -> ParserFn:
+        """Make a parser function.
+
+        Args:
+            per_port: If :data:`True`, will return capabilities per port. If :data:`False`,
+                will return capabilities per queue.
+
+        Returns:
+            ParserFn: A dictionary for the `dataclasses.field` metadata argument containing a
+                parser function that makes an instance of this flag from text.
+        """
+        granularity = "Port" if per_port else "Queue"
+        return TextParser.wrap(
+            TextParser.find(rf"Per {granularity}\s+:(.*)$", re.MULTILINE),
+            cls.from_string,
+        )
+
+
+@dataclass
+class TxOffloadCapabilities(TextParser):
+    """The result of testpmd's ``show port <port_id> tx_offload capabilities`` command.
+
+    References:
+        testpmd command function: ``app/test-pmd/cmdline.c:cmd_tx_offload_get_capa()``
+        testpmd display function: ``app/test-pmd/cmdline.c:cmd_tx_offload_get_capa_parsed()``
+    """
+
+    port_id: int = field(
+        metadata=TextParser.find_int(r"Tx Offloading Capabilities of port (\d+) :")
+    )
+    #: Per-queue Tx offload capabilities.
+    per_queue: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(False))
+    #: Capabilities other than per-queue Tx offload capabilities.
+    per_port: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(True))
+
+
 class RxOffloadCapability(Flag):
     """Rx offload capabilities of a device.
 
@@ -2397,6 +2490,28 @@ def close(self) -> None:
     ====== Capability retrieval methods ======
     """
 
+    def get_capabilities_tx_offload(
+        self,
+        supported_capabilities: MutableSet["NicCapability"],
+        unsupported_capabilities: MutableSet["NicCapability"],
+    ) -> None:
+        """Get all TX offload capabilities and divide them into supported and unsupported.
+
+        Args:
+            supported_capabilities: Supported capabilities will be added to this set.
+            unsupported_capabilities: Unsupported capabilities will be added to this set.
+        """
+        self._logger.debug("Getting TX offload capabilities.")
+        command = f"show port {self.ports[0].id} tx_offload capabilities"
+        tx_offload_capabilities_out = self.send_command(command)
+        tx_offload_capabilities = TxOffloadCapabilities.parse(tx_offload_capabilities_out)
+        self._update_capabilities_from_flag(
+            supported_capabilities,
+            unsupported_capabilities,
+            TxOffloadCapability,
+            tx_offload_capabilities.per_port | tx_offload_capabilities.per_queue,
+        )
+
     def get_capabilities_rx_offload(
         self,
         supported_capabilities: MutableSet["NicCapability"],
@@ -2824,6 +2939,94 @@ class NicCapability(NoAliasEnum):
     we don't go looking for it again if a different test case also needs it.
     """
 
+    TX_OFFLOAD_VLAN_INSERT: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_IPV4_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_UDP_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_TCP_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_SCTP_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_TCP_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_UDP_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_QINQ_INSERT: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_MACSEC_INSERT: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_MT_LOCKFREE: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_MULTI_SEGS: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_SECURITY: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_IP_TNL_TSO: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
+    TX_OFFLOAD_SEND_ON_TIMESTAMP: TestPmdShellNicCapability = (
+        TestPmdShell.get_capabilities_tx_offload,
+        None,
+    )
     #: Scattered packets Rx enabled
     SCATTERED_RX_ENABLED: TestPmdShellNicCapability = (
         TestPmdShell.get_capabilities_rxq_info,
-- 
2.50.1


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

* [PATCH v2 3/3] dts: update tx_offload test from old dts
  2025-09-03 18:04 ` [PATCH v2 0/3] dts: add tx_offlaod support in dts Andrew Bailey
  2025-09-03 18:04   ` [PATCH v2 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
  2025-09-03 18:04   ` [PATCH v2 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
@ 2025-09-03 18:04   ` Andrew Bailey
  2025-09-04 15:25     ` Luca Vizzarro
  2 siblings, 1 reply; 16+ messages in thread
From: Andrew Bailey @ 2025-09-03 18:04 UTC (permalink / raw)
  To: luca.vizzarro; +Cc: abailey, dev, dmarx, ivan.malov, probb

Currently, the Rx/Tx offload test in old DTS expects the Tx ports to be
initially configured to use mbuf fast free. This is no longer the case
and must be updated to assume mbuf fast free is not initially utilized
by capable NICs. Add updated test suite to test mbuf fast free
configuration.

Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
---
 dts/tests/TestSuite_rxtx_offload.py | 148 ++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 dts/tests/TestSuite_rxtx_offload.py

diff --git a/dts/tests/TestSuite_rxtx_offload.py b/dts/tests/TestSuite_rxtx_offload.py
new file mode 100644
index 0000000000..133994d795
--- /dev/null
+++ b/dts/tests/TestSuite_rxtx_offload.py
@@ -0,0 +1,148 @@
+# Copyright(c) 2025 University of New Hampshire
+
+"""Rx Tx offload test suite.
+
+Test the testpmd feature of configuring Rx and Tx offloads
+"""
+
+from framework.remote_session.testpmd_shell import (
+    NicCapability,
+    RxTxArgFlag,
+    TestPmdShell,
+)
+from framework.test_suite import TestSuite, func_test
+from framework.testbed_model.capability import requires
+
+
+@requires(NicCapability.TX_OFFLOAD_MBUF_FAST_FREE)
+class TestRxTxOffload(TestSuite):
+    """RX/TX offload test suite."""
+
+    def check_port_config(
+        self,
+        testpmd: TestPmdShell,
+        offload: str,
+        verify: bool,
+        port_id: int = 0,
+    ) -> bool:
+        """Checks that the current port configuration matches the given offload.
+
+        Args:
+            testpmd: The current testpmd shell session to send commands to.
+            offload: The expected configuration of the given port.
+            verify: Whether to verify the result of call to testpmd.
+            port_id: Id of the port to check.
+
+        Returns:
+            Whether current configuration matches given offload.
+        """
+        output = testpmd.get_rxtx_offload_config(RxTxArgFlag.TX, verify, port_id, 0)
+        return offload in output["port"] or (
+            offload == "NULL" and "MBUF_FAST_FREE" not in output["port"]
+        )
+
+    def check_queue_config(
+        self,
+        testpmd: TestPmdShell,
+        offload: list[str],
+        verify: bool,
+        port_id: int = 0,
+        num_queues: int = 0,
+    ) -> bool:
+        """Checks that the queue configuration matches the given offload.
+
+        Args:
+            testpmd: The current testpmd shell session to send commands to.
+            offload: The expected configuration of the queues, each index corresponds
+                to the queue id.
+            verify: Whether to verify commands sent to testpmd.
+            port_id: The port of which the queues reside.
+            num_queues: The number of queues to check.
+
+        Returns:
+            Whether current configuration matches given offload
+        """
+        output = testpmd.get_rxtx_offload_config(RxTxArgFlag.TX, verify, port_id, num_queues)
+        for i in range(0, num_queues):
+            if not (
+                offload[i] in output[i]
+                or (offload[i] == "NULL" and "MBUF_FAST_FREE" not in output[i])
+            ):
+                return False
+        return True
+
+    @func_test
+    def test_mbuf_fast_free_configurations(self) -> None:
+        """Ensure mbuf_fast_free can be configured with testpmd.
+
+        Steps:
+            Start up testpmd shell.
+            Toggle mbuf_fast_free on.
+            Toggle mbuf_fast_free off.
+
+        Verify:
+            Mbuf_fast_free starts disabled.
+            Mbuf_fast_free can be configured on.
+            Mbuf_fast_free can be configured off.
+        """
+        with TestPmdShell() as testpmd:
+            verify: bool = True
+            port_id: int = 0
+            num_queues: int = 4
+            queue_off: list[str] = []
+            queue_on: list[str] = []
+            mbuf_on = "MBUF_FAST_FREE"
+            mbuf_off = "NULL"
+
+            for _ in range(0, num_queues):
+                queue_off.append(mbuf_off)
+                queue_on.append(mbuf_on)
+
+            testpmd.set_ports_queues(num_queues)
+            testpmd.start_all_ports()
+
+            # Ensure mbuf_fast_free is disabled by default on port and queues
+            self.verify(
+                self.check_port_config(testpmd, mbuf_off, verify, port_id),
+                "Mbuf_fast_free enabled on port start",
+            )
+            self.verify(
+                self.check_queue_config(testpmd, queue_off, verify, port_id, num_queues),
+                "Mbuf_fast_free enabled on queue start",
+            )
+
+            # Enable mbuf_fast_free per queue and verify
+            testpmd.set_all_queues_mbuf_fast_free(True, verify, port_id, num_queues)
+            self.verify(
+                self.check_port_config(testpmd, mbuf_off, verify, port_id),
+                "Port configuration changed without call",
+            )
+            self.verify(
+                self.check_queue_config(testpmd, queue_on, verify, port_id, num_queues),
+                "Queues failed to enable mbuf_fast_free",
+            )
+
+            # Enable mbuf_fast_free per port and verify
+            testpmd.set_port_mbuf_fast_free(True, verify, port_id)
+            self.verify(
+                self.check_port_config(testpmd, mbuf_on, verify, port_id),
+                "Port failed to enable mbuf_fast_free",
+            )
+
+            # Disable mbuf_fast_free per queue and verify
+            testpmd.set_all_queues_mbuf_fast_free(False, verify, port_id, num_queues)
+            self.verify(
+                self.check_port_config(testpmd, mbuf_on, verify, port_id),
+                "Port configuration changed without call",
+            )
+            self.verify(
+                self.check_queue_config(testpmd, queue_off, verify, port_id, num_queues),
+                "Queues failed to disable mbuf_fast_free",
+            )
+
+            # Disable mbuf_fast_free per port and verify
+            testpmd.set_port_mbuf_fast_free(False, verify, port_id)
+            self.verify(
+                self.check_port_config(testpmd, mbuf_off, verify, port_id),
+                "Port failed to disable mbuf_fast_free",
+            )
-- 
2.50.1


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

* Re: [PATCH v2 2/3] dts: add TX offload capabilities to NIC capabilities
  2025-09-03 18:04   ` [PATCH v2 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
@ 2025-09-03 18:36     ` Patrick Robb
  2025-09-04 14:47     ` Luca Vizzarro
  1 sibling, 0 replies; 16+ messages in thread
From: Patrick Robb @ 2025-09-03 18:36 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: luca.vizzarro, dev, dmarx, ivan.malov

[-- Attachment #1: Type: text/plain, Size: 10187 bytes --]

On Wed, Sep 3, 2025 at 2:04 PM Andrew Bailey <abailey@iol.unh.edu> wrote:

> Currently, there is support for tracking the Rx offload capabilities of
> a NIC, but not for Tx offload capabilities. This is an issue if a test
> suite is written requiring one of these capabilities, since there is no
> way currently to verify that the NIC in use meets the requirements. Add
> Tx capabilities to the NIC capabilities at beginning of dts so
> requirements can be verified.
>
> Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
> ---
>  dts/framework/remote_session/testpmd_shell.py | 203 ++++++++++++++++++
>  1 file changed, 203 insertions(+)
>
> diff --git a/dts/framework/remote_session/testpmd_shell.py
> b/dts/framework/remote_session/testpmd_shell.py
> index 4d9caceb37..dfd83ebdb3 100644
> --- a/dts/framework/remote_session/testpmd_shell.py
> +++ b/dts/framework/remote_session/testpmd_shell.py
> @@ -1285,6 +1285,99 @@ class TestPmdVerbosePacket(TextParser):
>      )
>
>
> +class TxOffloadCapability(Flag):
> +    """TX offload capabilities of a device.
> +
> +    The flags are taken from ``lib/ethdev/rte_ethdev.h``.
> +    They're prefixed with ``RTE_ETH_TX_OFFLOAD`` in
> ``lib/ethdev/rte_ethdev.h``
> +    instead of ``TX_OFFLOAD``, which is what testpmd changes the prefix
> to.
> +    The values are not contiguous, so the correspondence is preserved
> +    by specifying concrete values interspersed between auto() values.
>

afaik only rx_offloads specify concrete values. It looks like these flags
are all auto().


> +
> +    The ``TX_OFFLOAD`` prefix has been preserved so that the same flag
> names can be used
> +    in :class:`NicCapability`. The prefix is needed in
> :class:`NicCapability` since there's
> +    no other qualifier which would sufficiently distinguish it from other
> capabilities.
> +
> +    References:
> +        DPDK lib: ``lib/ethdev/rte_ethdev.h``
> +        testpmd display function:
> ``app/test-pmd/cmdline.c:print_rx_offloads()``
> +    """
> +
> +    TX_OFFLOAD_VLAN_INSERT = auto()
> +    TX_OFFLOAD_IPV4_CKSUM = auto()
> +    TX_OFFLOAD_UDP_CKSUM = auto()
> +    TX_OFFLOAD_TCP_CKSUM = auto()
> +    TX_OFFLOAD_SCTP_CKSUM = auto()
> +    TX_OFFLOAD_TCP_TSO = auto()
> +    TX_OFFLOAD_UDP_TSO = auto()
> +    TX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
> +    TX_OFFLOAD_QINQ_INSERT = auto()
> +    TX_OFFLOAD_VXLAN_TNL_TSO = auto()
> +    TX_OFFLOAD_GRE_TNL_TSO = auto()
> +    TX_OFFLOAD_IPIP_TNL_TSO = auto()
> +    TX_OFFLOAD_GENEVE_TNL_TSO = auto()
> +    TX_OFFLOAD_MACSEC_INSERT = auto()
> +    TX_OFFLOAD_MT_LOCKFREE = auto()
> +    TX_OFFLOAD_MULTI_SEGS = auto()
> +    TX_OFFLOAD_MBUF_FAST_FREE = auto()
> +    TX_OFFLOAD_SECURITY = auto()
> +    TX_OFFLOAD_UDP_TNL_TSO = auto()
> +    TX_OFFLOAD_IP_TNL_TSO = auto()
> +    TX_OFFLOAD_OUTER_UDP_CKSUM = auto()
> +    TX_OFFLOAD_SEND_ON_TIMESTAMP = auto()
> +
> +    @classmethod
> +    def from_string(cls, line: str) -> Self:
> +        """Make an instance from a string containing the flag names
> separated with a space.
> +
> +        Args:
> +            line: The line to parse.
> +
> +        Returns:
> +            A new instance containing all found flags.
> +        """
> +        flag = cls(0)
> +        for flag_name in line.split():
> +            flag |= cls[f"TX_OFFLOAD_{flag_name}"]
> +        return flag
> +
> +    @classmethod
> +    def make_parser(cls, per_port: bool) -> ParserFn:
> +        """Make a parser function.
> +
> +        Args:
> +            per_port: If :data:`True`, will return capabilities per port.
> If :data:`False`,
> +                will return capabilities per queue.
> +
> +        Returns:
> +            ParserFn: A dictionary for the `dataclasses.field` metadata
> argument containing a
> +                parser function that makes an instance of this flag from
> text.
> +        """
> +        granularity = "Port" if per_port else "Queue"
> +        return TextParser.wrap(
> +            TextParser.find(rf"Per {granularity}\s+:(.*)$", re.MULTILINE),
> +            cls.from_string,
> +        )
> +
> +
> +@dataclass
> +class TxOffloadCapabilities(TextParser):
> +    """The result of testpmd's ``show port <port_id> tx_offload
> capabilities`` command.
> +
> +    References:
> +        testpmd command function:
> ``app/test-pmd/cmdline.c:cmd_tx_offload_get_capa()``
> +        testpmd display function:
> ``app/test-pmd/cmdline.c:cmd_tx_offload_get_capa_parsed()``
> +    """
> +
> +    port_id: int = field(
> +        metadata=TextParser.find_int(r"Tx Offloading Capabilities of port
> (\d+) :")
> +    )
> +    #: Per-queue Tx offload capabilities.
> +    per_queue: TxOffloadCapability =
> field(metadata=TxOffloadCapability.make_parser(False))
> +    #: Capabilities other than per-queue Tx offload capabilities.
> +    per_port: TxOffloadCapability =
> field(metadata=TxOffloadCapability.make_parser(True))
> +
> +
>  class RxOffloadCapability(Flag):
>      """Rx offload capabilities of a device.
>
> @@ -2397,6 +2490,28 @@ def close(self) -> None:
>      ====== Capability retrieval methods ======
>      """
>
> +    def get_capabilities_tx_offload(
> +        self,
> +        supported_capabilities: MutableSet["NicCapability"],
> +        unsupported_capabilities: MutableSet["NicCapability"],
> +    ) -> None:
> +        """Get all TX offload capabilities and divide them into supported
> and unsupported.
> +
> +        Args:
> +            supported_capabilities: Supported capabilities will be added
> to this set.
> +            unsupported_capabilities: Unsupported capabilities will be
> added to this set.
> +        """
> +        self._logger.debug("Getting TX offload capabilities.")
> +        command = f"show port {self.ports[0].id} tx_offload capabilities"
> +        tx_offload_capabilities_out = self.send_command(command)
> +        tx_offload_capabilities =
> TxOffloadCapabilities.parse(tx_offload_capabilities_out)
> +        self._update_capabilities_from_flag(
> +            supported_capabilities,
> +            unsupported_capabilities,
> +            TxOffloadCapability,
> +            tx_offload_capabilities.per_port |
> tx_offload_capabilities.per_queue,
> +        )
> +
>      def get_capabilities_rx_offload(
>          self,
>          supported_capabilities: MutableSet["NicCapability"],
> @@ -2824,6 +2939,94 @@ class NicCapability(NoAliasEnum):
>      we don't go looking for it again if a different test case also needs
> it.
>      """
>
> +    TX_OFFLOAD_VLAN_INSERT: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_IPV4_CKSUM: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_UDP_CKSUM: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_TCP_CKSUM: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_SCTP_CKSUM: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_TCP_TSO: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_UDP_TSO: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_QINQ_INSERT: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_MACSEC_INSERT: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_MT_LOCKFREE: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_MULTI_SEGS: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_SECURITY: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_IP_TNL_TSO: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
> +    TX_OFFLOAD_SEND_ON_TIMESTAMP: TestPmdShellNicCapability = (
> +        TestPmdShell.get_capabilities_tx_offload,
> +        None,
> +    )
>      #: Scattered packets Rx enabled
>      SCATTERED_RX_ENABLED: TestPmdShellNicCapability = (
>          TestPmdShell.get_capabilities_rxq_info,
> --
> 2.50.1
>
>
Looks good. Have you verified the docs will build from this patch? If you
haven't done this yet it's

meson setup my_build
ninja -C my_build doc

Reviewed-by: Patrick Robb <probb@iol.unh.edu>

[-- Attachment #2: Type: text/html, Size: 12276 bytes --]

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

* Re: [PATCH v1 2/3] dts: add TX offload capabilities to NIC capabilities
  2025-09-02 14:27 ` [PATCH v1 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
@ 2025-09-04 14:43   ` Luca Vizzarro
  2025-09-04 14:45     ` Luca Vizzarro
  0 siblings, 1 reply; 16+ messages in thread
From: Luca Vizzarro @ 2025-09-04 14:43 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: dev, dmarx, probb

Hi Andrew,

thank you for your patches!

On Tue, Sep 02, 2025 at 10:27:24AM +0000, Andrew Bailey wrote:
> diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
> index ad8cb273dc..786714d1c5 100644
> --- a/dts/framework/remote_session/testpmd_shell.py
> +++ b/dts/framework/remote_session/testpmd_shell.py
> @@ -1278,6 +1278,99 @@ class TestPmdVerbosePacket(TextParser):
>      )
> 
> 
> +class TxOffloadCapability(Flag):
> +    """TX offload capabilities of a device.
> +
> +    The flags are taken from ``lib/ethdev/rte_ethdev.h``.
> +    They're prefixed with ``RTE_ETH_TX_OFFLOAD`` in ``lib/ethdev/rte_ethdev.h``
> +    instead of ``TX_OFFLOAD``, which is what testpmd changes the prefix to.
> +    The values are not contiguous, so the correspondence is preserved
> +    by specifying concrete values interspersed between auto() values.
> +
> +    The ``TX_OFFLOAD`` prefix has been preserved so that the same flag names can be used
> +    in :class:`NicCapability`. The prefix is needed in :class:`NicCapability` since there's
> +    no other qualifier which would sufficiently distinguish it from other capabilities.
> +
> +    References:
> +        DPDK lib: ``lib/ethdev/rte_ethdev.h``
> +        testpmd display function: ``app/test-pmd/cmdline.c:print_rx_offloads()``
> +    """
> +
> +    TX_OFFLOAD_VLAN_INSERT = auto()
> +    TX_OFFLOAD_IPV4_CKSUM = auto()
> +    TX_OFFLOAD_UDP_CKSUM = auto()
> +    TX_OFFLOAD_TCP_CKSUM = auto()
> +    TX_OFFLOAD_SCTP_CKSUM = auto()
> +    TX_OFFLOAD_TCP_TSO = auto()
> +    TX_OFFLOAD_UDP_TSO = auto()
> +    TX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
> +    TX_OFFLOAD_QINQ_INSERT = auto()
> +    TX_OFFLOAD_VXLAN_TNL_TSO = auto()
> +    TX_OFFLOAD_GRE_TNL_TSO = auto()
> +    TX_OFFLOAD_IPIP_TNL_TSO = auto()
> +    TX_OFFLOAD_GENEVE_TNL_TSO = auto()
> +    TX_OFFLOAD_MACSEC_INSERT = auto()
> +    TX_OFFLOAD_MT_LOCKFREE = auto()
> +    TX_OFFLOAD_MULTI_SEGS = auto()
> +    TX_OFFLOAD_MBUF_FAST_FREE = auto()
> +    TX_OFFLOAD_SECURITY = auto()
> +    TX_OFFLOAD_UDP_TNL_TSO = auto()
> +    TX_OFFLOAD_IP_TNL_TSO = auto()
> +    TX_OFFLOAD_OUTER_UDP_CKSUM = auto()
> +    TX_OFFLOAD_SEND_ON_TIMESTAMP = auto()
> +
> +    @classmethod
> +    def from_string(cls, line: str) -> Self:
> +        """Make an instance from a string containing the flag names separated with a space.
> +
> +        Args:
> +            line: The line to parse.
> +
> +        Returns:
> +            A new instance containing all found flags.
> +        """
> +        flag = cls(0)
> +        for flag_name in line.split():
> +            flag |= cls[f"TX_OFFLOAD_{flag_name}"]
> +        return flag
> +
> +    @classmethod
> +    def make_parser(cls, per_port: bool) -> ParserFn:
> +        """Make a parser function.
> +
> +        Args:
> +            per_port: If :data:`True`, will return capabilities per port. If :data:`False`,
> +                will return capabilities per queue.
> +
> +        Returns:
> +            ParserFn: A dictionary for the `dataclasses.field` metadata argument containing a
> +                parser function that makes an instance of this flag from text.
> +        """
> +        granularity = "Port" if per_port else "Queue"
> +        return TextParser.wrap(
> +            TextParser.find(rf"Per {granularity}\s+:(.*)$", re.MULTILINE),
> +            cls.from_string,
> +        )

The above is creating a lot of duplication. I'd personally implement the
functions in a class that the flags RxOffload and TxOffload can inherit
from. You can deal with `cls[f"TX_OFFLOAD_{flag_name}"]` by introducing
a "PREFIX" ClassVar for all the classes where you can specify it:

    PREFIX: ClassVar[str] = "TX_OFFLOAD_"

    ...

    cls[f"{cls.PREFIX}{flag_name}"]

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

* Re: [PATCH v1 2/3] dts: add TX offload capabilities to NIC capabilities
  2025-09-04 14:43   ` Luca Vizzarro
@ 2025-09-04 14:45     ` Luca Vizzarro
  0 siblings, 0 replies; 16+ messages in thread
From: Luca Vizzarro @ 2025-09-04 14:45 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: dev, dmarx, probb

whoops! I was meant to reply to the v2 patch. The same applies though.

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

* Re: [PATCH v2 2/3] dts: add TX offload capabilities to NIC capabilities
  2025-09-03 18:04   ` [PATCH v2 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
  2025-09-03 18:36     ` Patrick Robb
@ 2025-09-04 14:47     ` Luca Vizzarro
  1 sibling, 0 replies; 16+ messages in thread
From: Luca Vizzarro @ 2025-09-04 14:47 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: dev, dmarx, ivan.malov, probb

Copying reply from v1.

On Wed, Sep 03, 2025 at 02:04:13PM +0000, Andrew Bailey wrote:
> diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
> index 4d9caceb37..dfd83ebdb3 100644
> --- a/dts/framework/remote_session/testpmd_shell.py
> +++ b/dts/framework/remote_session/testpmd_shell.py
> @@ -1285,6 +1285,99 @@ class TestPmdVerbosePacket(TextParser):
>      )
>  
>  
> +class TxOffloadCapability(Flag):
> +    """TX offload capabilities of a device.
> +
> +    The flags are taken from ``lib/ethdev/rte_ethdev.h``.
> +    They're prefixed with ``RTE_ETH_TX_OFFLOAD`` in ``lib/ethdev/rte_ethdev.h``
> +    instead of ``TX_OFFLOAD``, which is what testpmd changes the prefix to.
> +    The values are not contiguous, so the correspondence is preserved
> +    by specifying concrete values interspersed between auto() values.
> +
> +    The ``TX_OFFLOAD`` prefix has been preserved so that the same flag names can be used
> +    in :class:`NicCapability`. The prefix is needed in :class:`NicCapability` since there's
> +    no other qualifier which would sufficiently distinguish it from other capabilities.
> +
> +    References:
> +        DPDK lib: ``lib/ethdev/rte_ethdev.h``
> +        testpmd display function: ``app/test-pmd/cmdline.c:print_rx_offloads()``
> +    """
> +
> +    TX_OFFLOAD_VLAN_INSERT = auto()
> +    TX_OFFLOAD_IPV4_CKSUM = auto()
> +    TX_OFFLOAD_UDP_CKSUM = auto()
> +    TX_OFFLOAD_TCP_CKSUM = auto()
> +    TX_OFFLOAD_SCTP_CKSUM = auto()
> +    TX_OFFLOAD_TCP_TSO = auto()
> +    TX_OFFLOAD_UDP_TSO = auto()
> +    TX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
> +    TX_OFFLOAD_QINQ_INSERT = auto()
> +    TX_OFFLOAD_VXLAN_TNL_TSO = auto()
> +    TX_OFFLOAD_GRE_TNL_TSO = auto()
> +    TX_OFFLOAD_IPIP_TNL_TSO = auto()
> +    TX_OFFLOAD_GENEVE_TNL_TSO = auto()
> +    TX_OFFLOAD_MACSEC_INSERT = auto()
> +    TX_OFFLOAD_MT_LOCKFREE = auto()
> +    TX_OFFLOAD_MULTI_SEGS = auto()
> +    TX_OFFLOAD_MBUF_FAST_FREE = auto()
> +    TX_OFFLOAD_SECURITY = auto()
> +    TX_OFFLOAD_UDP_TNL_TSO = auto()
> +    TX_OFFLOAD_IP_TNL_TSO = auto()
> +    TX_OFFLOAD_OUTER_UDP_CKSUM = auto()
> +    TX_OFFLOAD_SEND_ON_TIMESTAMP = auto()
> +
> +    @classmethod
> +    def from_string(cls, line: str) -> Self:
> +        """Make an instance from a string containing the flag names separated with a space.
> +
> +        Args:
> +            line: The line to parse.
> +
> +        Returns:
> +            A new instance containing all found flags.
> +        """
> +        flag = cls(0)
> +        for flag_name in line.split():
> +            flag |= cls[f"TX_OFFLOAD_{flag_name}"]
> +        return flag
> +
> +    @classmethod
> +    def make_parser(cls, per_port: bool) -> ParserFn:
> +        """Make a parser function.
> +
> +        Args:
> +            per_port: If :data:`True`, will return capabilities per port. If :data:`False`,
> +                will return capabilities per queue.
> +
> +        Returns:
> +            ParserFn: A dictionary for the `dataclasses.field` metadata argument containing a
> +                parser function that makes an instance of this flag from text.
> +        """
> +        granularity = "Port" if per_port else "Queue"
> +        return TextParser.wrap(
> +            TextParser.find(rf"Per {granularity}\s+:(.*)$", re.MULTILINE),
> +            cls.from_string,
> +        )

The above is creating a lot of duplication. I'd personally implement the
functions in a class that the flags RxOffload and TxOffload can inherit
from. You can deal with `cls[f"TX_OFFLOAD_{flag_name}"]` by introducing
a "PREFIX" ClassVar for all the classes where you can specify it:

    PREFIX: ClassVar[str] = "TX_OFFLOAD_"

    ...

    cls[f"{cls.PREFIX}{flag_name}"]

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

* Re: [PATCH v2 1/3] dts: allow mbuf_fast_free to be set with testpmd shell
  2025-09-03 18:04   ` [PATCH v2 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
@ 2025-09-04 15:15     ` Luca Vizzarro
  0 siblings, 0 replies; 16+ messages in thread
From: Luca Vizzarro @ 2025-09-04 15:15 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: dev, dmarx, ivan.malov, probb

On Wed, Sep 03, 2025 at 02:04:12PM +0000, Andrew Bailey wrote:
> diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
> index ad8cb273dc..4d9caceb37 100644
> --- a/dts/framework/remote_session/testpmd_shell.py
> +++ b/dts/framework/remote_session/testpmd_shell.py
> @@ -19,7 +19,7 @@
>  import time
>  from collections.abc import Callable, MutableSet
>  from dataclasses import dataclass, field
> -from enum import Flag, auto
> +from enum import Enum, Flag, auto
>  from os import environ
>  from pathlib import PurePath
>  from typing import TYPE_CHECKING, Any, ClassVar, Concatenate, Literal, ParamSpec, Tuple, TypeAlias
> @@ -344,6 +344,13 @@ def make_parser(cls) -> ParserFn:
>          )
>  
>  
> +class RxTxArgFlag(Enum):

this could be StrEnum given the values used. Moreover, is it a
flag? Looks like a regular enum to me.

> +    """Enum representing receiving or transmitting ports."""
> +
> +    TX = "tx"
> +    RX = "rx"
> +
> +
>  class DeviceCapabilitiesFlag(Flag):
>      """Flag representing the device capabilities."""
>  
> @@ -2672,6 +2679,125 @@ def get_capabilities_physical_function(
>          else:
>              unsupported_capabilities.add(NicCapability.PHYSICAL_FUNCTION)
>  
> +    @requires_started_ports
> +    def get_rxtx_offload_config(
if we are considering rxtx as two words, they should be split by _
> +        self,
> +        rxtx: RxTxArgFlag,
as above. If the whole purpose of the Enum is just a switch for the
argument, you can consider using a Literal instead, it'll be easier to
write from a user perspective as well:

  RxTxLiteralSwitch = Literal["rx", "tx"]
  ...
  get_rx_tx_offload_config("rx")

This also makes me question whether we need rx_tx at all in the name of
the method.

> +        verify: bool,
We've made verify an optional argument across the board, should be the
same here.
> +        port_id: int = 0,
I would also *not* make port_id optional. For the sake of readability
when using, you can split rx_tx from port_id using a /. This will
determine the end of positional arguments, therefore making anything
after mandatory keyword arguments.
> +        num_queues: int = 0,
> +    ) -> dict[int | str, str]:
This return type looks like it needs a dedicated data structure.
> +        """Get the Rx or Tx offload configuration of the queues from the given port.
> +
> +        Args:
> +            rxtx: Whether to get the Rx or Tx configuration of the given queues.
> +            verify: If :data:'True' the output of the command will be scanned in an attempt to
Any RST directives need backticks:

  :data:`True`

> +                verify that the offload configuration was retrieved successfully on all queues.
> +            port_id: The port ID that contains the desired queues.
> +            num_queues: The number of queues to get the offload configuration for.
> +
> +        Returns:
> +            A dict containing port info at key 'port' and queue info keyed by the appropriate queue
> +                id.
Keys cannot be enforced by mypy with a generic dict. Consider using a
NamedDict or a dataclass appropriately.
> +
> +        Raises:
> +            InteractiveCommandExecutionError: If all queue offload configurations could not be
> +                retrieved.
> +
extra empty line shouldn't be here.
> +        """
> +        returnDict: dict[int | str, str] = {}
snake_case notation is used for variables.
> +
> +        config_output = self.send_command(f"show port {port_id} {rxtx.value}_offload configuration")
> +        if verify:
> +            if (
> +                f"Rx Offloading Configuration of port {port_id}" not in config_output
> +                and f"Tx Offloading Configuration of port {port_id}" not in config_output
> +            ):
> +                self._logger.debug(f"Get port offload config error\n{config_output}")
> +                raise InteractiveCommandExecutionError(
> +                    f"""Failed to get offload config on port {port_id}:\n{config_output}"""
No need to use multi-line quotes for a single line.
> +                )
> +        # Actual output data starts on the third line
> +        tempList: list[str] = config_output.splitlines()[3::]
> +        returnDict["port"] = tempList[0]
> +        for i in range(0, num_queues):
> +            returnDict[i] = tempList[i + 1]
Looks like an occasion to use a TextParser for the return data structure.
> +        return returnDict
> +
> +    @requires_stopped_ports
> +    def set_port_mbuf_fast_free(self, on: bool, verify: bool, port_id: int = 0) -> None:
Similar situation for port_id and verify as above.
> +        """Sets the mbuf_fast_free configuration for the Tx offload for a given port.
> +
> +        Args:
> +            on: If :data:'True' mbuf_fast_free will be enabled, disable it otherwise.
backticks instead of single quotes
> +            verify: If :data:'True' the output of the command will be scanned in an attempt to
backticks instead of single quotes
> +                verify that the mbuf_fast_free was set successfully.
> +            port_id: The port number to enable or disable mbuf_fast_free on.
> +
> +        Raises:
> +            InteractiveCommandExecutionError: If mbuf_fast_free could not be set successfully
missed full stop at the end.
> +        """
> +        mbuf_output = self.send_command(
> +            f"port config {port_id} tx_offload mbuf_fast_free {"on" if on else "off"}"
> +        )
> +
> +        if "error" in mbuf_output and verify:
This is not really that important but you may always want to check for
the boolean first as that will spare doing a text search if set to
False. Writing it like this is generally better:

    if verify and "error" in mbuf_output:

> +            raise InteractiveCommandExecutionError(
> +                f"""Unable to set mbuf_fast_free config on port {port_id}:\n{mbuf_output}"""
multi-line quotes in single line string.
> +            )
> +
> +    @requires_stopped_ports
> +    def set_queue_mbuf_fast_free(
> +        self,
> +        on: bool,
> +        verify: bool,
> +        port_id: int = 0,
> +        queue_id: int = 0,
> +    ) -> None:
same discussion for verify, port_id and queue_id.
> +        """Sets the Tx mbuf_fast_free configuration of the specified queue on a given port.
> +
> +        Args:
> +            on: If :data:'True' the mbuf_fast_free configuration will be enabled, otherwise
backticks instead of single quotes
> +                disabled.
> +            verify: If :data:'True' the output of the command will be scanned in an attempt to
backticks instead of single quotes
> +                verify that mbuf_fast_free was set successfully on all ports.
> +            port_id: The ID of the port containing the queues.
> +            queue_id: The queue to disable mbuf_fast_free on.
> +
> +        Raises:
> +            InteractiveCommandExecutionError: If all queues could not be set successfully.
> +        """
> +        toggle = "on" if on else "off"
> +        output = self.send_command(
> +            f"port {port_id} txq {queue_id} tx_offload mbuf_fast_free {toggle}"
> +        )
> +        if verify:
> +            if "Error" in output:
the two conditions could be merged together, and it will read easier
requiring one level less of indentation.
> +                self._logger.debug(f"Set queue offload config error\n{output}")
> +                raise InteractiveCommandExecutionError(
> +                    f"Failed to get offload config on port {port_id}, queue {queue_id}:\n{output}"
> +                )
> +
> +    def set_all_queues_mbuf_fast_free(
> +        self,
> +        on: bool,
> +        verify: bool,
> +        port_id=0,
> +        num_queues: int = 0,
> +    ) -> None:
same discussion for the args.
> +        """Sets mbuf_fast_free configuration for the Tx offload of all queues on a given port.
> +
> +        Args:
> +            on: If :data:'True' the mbuf_fast_free configuration will be enabled, otherwise
backticks instead of single quotes
> +                disabled.
> +            verify: If :data:'True' the output of the command will be scanned in an attempt to
backticks instead of single quotes
> +                verify that mbuf_fast_free was set successfully on all ports.
> +            port_id: The ID of the port containing the queues.
> +            num_queues: The amount of queues to disable mbuf_fast_free on.
> +        """
> +        for i in range(0, num_queues):
> +            self.set_queue_mbuf_fast_free(on, verify, port_id=port_id, queue_id=i)
So far we have been mostly replicating the testpmd functionality. I am
wondering if this is actually needed to be implemented on the
TestPmdShell side.
> +
>  
>  class NicCapability(NoAliasEnum):
>      """A mapping between capability names and the associated :class:`TestPmdShell` methods.
> -- 
> 2.50.1
> 

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

* Re: [PATCH v2 3/3] dts: update tx_offload test from old dts
  2025-09-03 18:04   ` [PATCH v2 3/3] dts: update tx_offload test from old dts Andrew Bailey
@ 2025-09-04 15:25     ` Luca Vizzarro
  0 siblings, 0 replies; 16+ messages in thread
From: Luca Vizzarro @ 2025-09-04 15:25 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: dev, dmarx, ivan.malov, probb

On Wed, Sep 03, 2025 at 02:04:14PM +0000, Andrew Bailey wrote:
> Currently, the Rx/Tx offload test in old DTS expects the Tx ports to be
> initially configured to use mbuf fast free. This is no longer the case
> and must be updated to assume mbuf fast free is not initially utilized
> by capable NICs. Add updated test suite to test mbuf fast free
> configuration.
> 
> Signed-off-by: Andrew Bailey <abailey@iol.unh.edu>
> ---
>  dts/tests/TestSuite_rxtx_offload.py | 148 ++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
>  create mode 100644 dts/tests/TestSuite_rxtx_offload.py
> 
> diff --git a/dts/tests/TestSuite_rxtx_offload.py b/dts/tests/TestSuite_rxtx_offload.py
> new file mode 100644
> index 0000000000..133994d795
> --- /dev/null
> +++ b/dts/tests/TestSuite_rxtx_offload.py
> @@ -0,0 +1,148 @@
Missing SPDX License identifier
> +# Copyright(c) 2025 University of New Hampshire
> +
> +"""Rx Tx offload test suite.
> +
> +Test the testpmd feature of configuring Rx and Tx offloads
missed full stop at the end.
> +"""
> +
> +from framework.remote_session.testpmd_shell import (
> +    NicCapability,
> +    RxTxArgFlag,
> +    TestPmdShell,
> +)
> +from framework.test_suite import TestSuite, func_test
> +from framework.testbed_model.capability import requires
> +
> +
> +@requires(NicCapability.TX_OFFLOAD_MBUF_FAST_FREE)
> +class TestRxTxOffload(TestSuite):
Have you tested this test suite? From the looks of it, it doesn't seem
it was ever tested. The current test suite discovery logic matches the
file name to the class name, and they are currently mismatching.

  TestSuite_rxtx_offload -> TestRxtxOffload
  TestRxTxOffload -> TestSuite_rx_tx_offload

> +    """RX/TX offload test suite."""
> +
> +    def check_port_config(
Any method that is not a test case should be made private.
> +        self,
> +        testpmd: TestPmdShell,
> +        offload: str,
> +        verify: bool,
> +        port_id: int = 0,
> +    ) -> bool:
> +        """Checks that the current port configuration matches the given offload.
> +
> +        Args:
> +            testpmd: The current testpmd shell session to send commands to.
> +            offload: The expected configuration of the given port.
> +            verify: Whether to verify the result of call to testpmd.
> +            port_id: Id of the port to check.
> +
> +        Returns:
> +            Whether current configuration matches given offload.
> +        """
And docstrings shoud be reserved for test suite module and test case
methods only. This docstring won't be rendered as a private method.
> +        output = testpmd.get_rxtx_offload_config(RxTxArgFlag.TX, verify, port_id, 0)
> +        return offload in output["port"] or (
> +            offload == "NULL" and "MBUF_FAST_FREE" not in output["port"]
> +        )
> +
> +    def check_queue_config(
> +        self,
> +        testpmd: TestPmdShell,
> +        offload: list[str],
> +        verify: bool,
> +        port_id: int = 0,
> +        num_queues: int = 0,
> +    ) -> bool:
> +        """Checks that the queue configuration matches the given offload.
> +
> +        Args:
> +            testpmd: The current testpmd shell session to send commands to.
> +            offload: The expected configuration of the queues, each index corresponds
> +                to the queue id.
> +            verify: Whether to verify commands sent to testpmd.
> +            port_id: The port of which the queues reside.
> +            num_queues: The number of queues to check.
> +
> +        Returns:
> +            Whether current configuration matches given offload
> +        """
as above.
> +        output = testpmd.get_rxtx_offload_config(RxTxArgFlag.TX, verify, port_id, num_queues)
> +        for i in range(0, num_queues):
> +            if not (
> +                offload[i] in output[i]
> +                or (offload[i] == "NULL" and "MBUF_FAST_FREE" not in output[i])
> +            ):
> +                return False
> +        return True
> +
> +    @func_test
> +    def test_mbuf_fast_free_configurations(self) -> None:
> +        """Ensure mbuf_fast_free can be configured with testpmd.
> +
> +        Steps:
> +            Start up testpmd shell.
> +            Toggle mbuf_fast_free on.
> +            Toggle mbuf_fast_free off.
> +
> +        Verify:
> +            Mbuf_fast_free starts disabled.
> +            Mbuf_fast_free can be configured on.
> +            Mbuf_fast_free can be configured off.
Improperly formatted unordered lists. Should prefix the lines with *
> +        """
> +        with TestPmdShell() as testpmd:
> +            verify: bool = True
> +            port_id: int = 0
> +            num_queues: int = 4
The types are inferred from the assigned value, there is no need to
specify it explicitly.
> +            queue_off: list[str] = []
> +            queue_on: list[str] = []
> +            mbuf_on = "MBUF_FAST_FREE"
> +            mbuf_off = "NULL"
> +
> +            for _ in range(0, num_queues):
> +                queue_off.append(mbuf_off)
> +                queue_on.append(mbuf_on)
This should be rather written as a list comprehension.
> +
> +            testpmd.set_ports_queues(num_queues)
> +            testpmd.start_all_ports()
> +
> +            # Ensure mbuf_fast_free is disabled by default on port and queues
> +            self.verify(
> +                self.check_port_config(testpmd, mbuf_off, verify, port_id),
> +                "Mbuf_fast_free enabled on port start",
Full stop at the end of the sentence.
> +            )
> +            self.verify(
> +                self.check_queue_config(testpmd, queue_off, verify, port_id, num_queues),
> +                "Mbuf_fast_free enabled on queue start",
Full stop at the end of the sentence.
> +            )
> +
> +            # Enable mbuf_fast_free per queue and verify
> +            testpmd.set_all_queues_mbuf_fast_free(True, verify, port_id, num_queues)
> +            self.verify(
> +                self.check_port_config(testpmd, mbuf_off, verify, port_id),
> +                "Port configuration changed without call",
Full stop at the end of the sentence.
> +            )
> +            self.verify(
> +                self.check_queue_config(testpmd, queue_on, verify, port_id, num_queues),
> +                "Queues failed to enable mbuf_fast_free",
Full stop at the end of the sentence.
> +            )
> +
> +            # Enable mbuf_fast_free per port and verify
> +            testpmd.set_port_mbuf_fast_free(True, verify, port_id)
> +            self.verify(
> +                self.check_port_config(testpmd, mbuf_on, verify, port_id),
> +                "Port failed to enable mbuf_fast_free",
Full stop at the end of the sentence.
> +            )
> +
> +            # Disable mbuf_fast_free per queue and verify
> +            testpmd.set_all_queues_mbuf_fast_free(False, verify, port_id, num_queues)
> +            self.verify(
> +                self.check_port_config(testpmd, mbuf_on, verify, port_id),
> +                "Port configuration changed without call",
Full stop at the end of the sentence.
> +            )
> +            self.verify(
> +                self.check_queue_config(testpmd, queue_off, verify, port_id, num_queues),
> +                "Queues failed to disable mbuf_fast_free",
Full stop at the end of the sentence.
> +            )
> +
> +            # Disable mbuf_fast_free per port and verify
> +            testpmd.set_port_mbuf_fast_free(False, verify, port_id)
> +            self.verify(
> +                self.check_port_config(testpmd, mbuf_off, verify, port_id),
> +                "Port failed to disable mbuf_fast_free",
Full stop at the end of the sentence.
> +            )
> -- 
> 2.50.1
> 
It looks like mbuf_off and mbuf_on are the same throughout, is there a
need to make these a variable and pass it along the methods?

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

end of thread, other threads:[~2025-09-04 15:25 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-02 14:27 [PATCH v1 0/3] dts: add tx_offload support in dts Andrew Bailey
2025-09-02 14:27 ` [PATCH v1 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
2025-09-02 19:37   ` Ivan Malov
2025-09-02 19:48     ` Ivan Malov
2025-09-02 14:27 ` [PATCH v1 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
2025-09-04 14:43   ` Luca Vizzarro
2025-09-04 14:45     ` Luca Vizzarro
2025-09-02 14:27 ` [PATCH v1 3/3] dts: update tx_offload test from old dts Andrew Bailey
2025-09-03 18:04 ` [PATCH v2 0/3] dts: add tx_offlaod support in dts Andrew Bailey
2025-09-03 18:04   ` [PATCH v2 1/3] dts: allow mbuf_fast_free to be set with testpmd shell Andrew Bailey
2025-09-04 15:15     ` Luca Vizzarro
2025-09-03 18:04   ` [PATCH v2 2/3] dts: add TX offload capabilities to NIC capabilities Andrew Bailey
2025-09-03 18:36     ` Patrick Robb
2025-09-04 14:47     ` Luca Vizzarro
2025-09-03 18:04   ` [PATCH v2 3/3] dts: update tx_offload test from old dts Andrew Bailey
2025-09-04 15:25     ` Luca Vizzarro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).