From patchwork Tue Sep 3 19:46:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Spewock X-Patchwork-Id: 143578 X-Patchwork-Delegate: paul.szczepanek@arm.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 43082458F4; Tue, 3 Sep 2024 21:47:13 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 29CEF410E7; Tue, 3 Sep 2024 21:47:13 +0200 (CEST) Received: from mail-pg1-f227.google.com (mail-pg1-f227.google.com [209.85.215.227]) by mails.dpdk.org (Postfix) with ESMTP id CC3F8410E3 for ; Tue, 3 Sep 2024 21:47:11 +0200 (CEST) Received: by mail-pg1-f227.google.com with SMTP id 41be03b00d2f7-7cd8afc9ff3so5121a12.0 for ; Tue, 03 Sep 2024 12:47:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1725392831; x=1725997631; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Pqb0mo+xatnCzo/UHe+weg5Qcpn595YBKPauPeBPA4M=; b=fEQgC1x6bzX9R9vJRq2eJRJ9zhQm18DhhNqFUbDiLdKH4ToLAn4cDbQ+OFWkoe4lis hrjGYz/LOptKvXq6E7r52fuwthi0jrCV2EEbrh/0hS99IA11Ue+8L3eqOizaQMNOLfKb UPD6t17yXxDZbXOE+O/PGQMuUXxN/Uj5d/hVQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725392831; x=1725997631; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Pqb0mo+xatnCzo/UHe+weg5Qcpn595YBKPauPeBPA4M=; b=scGXs9wP3yuUitt3yfbsOihO7RYRYYbc7zZry3nRx2ssXnZf/yYtomUggcUO3tm6KD 0pG0UTQIrw63s0rRlAhjxJ6jyaRN9nLBkOyAzHrImeKTgz54M/8ie/4efEFehNnGhVWs t+Td9ehiwWACoZ1anq0teh2pEzsSWJ4mg35pZHBPWIe2NZQb8Y303ewtC3Hi2GcyhBPM KUueKK7dAg7+kt171M2VucWvkH0kTk6UVN8+q+yMRu61ZDwTnjIouDFZhgoLwP6r0rVf 2DQbww+VOOPdAsU34qh00WSxCWNH5YM4/La9mtuGO0cLXLdaS1vKxlQ06Mo3D0nD2FA8 xWrg== X-Gm-Message-State: AOJu0YxN5CpPWLuHX4MdY3FOm34axeT0B/eOa+vxNDwrMClpxP3B5OjB C3d8NXiojxFKg+HQMKpAXF3rJC5N03qyyVxnWprHbGSGB5kCbqTWVkEBPpk1acGiK/ttSX1ncY+ ghHL1/jKOzPwBqW1AwtiiHU9NvyEUt4TGJXlnda8hf03MPc8Q X-Google-Smtp-Source: AGHT+IFmkk3cC7j9WsI66DF4fgPZA/jKOw/kabshrA4Up5rGRqr7KcE/4B2BBIU/Rk795NK2Zted1UAUcsPI X-Received: by 2002:a17:90a:c794:b0:2d8:25ce:e6e3 with SMTP id 98e67ed59e1d1-2d856a2e852mr29191123a91.5.1725392830708; Tue, 03 Sep 2024 12:47:10 -0700 (PDT) Received: from postal.iol.unh.edu (postal.iol.unh.edu. [2606:4100:3880:1234::84]) by smtp-relay.gmail.com with ESMTPS id 98e67ed59e1d1-2d8446d1dddsm713958a91.16.2024.09.03.12.47.10 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Sep 2024 12:47:10 -0700 (PDT) X-Relaying-Domain: iol.unh.edu Received: from iol.unh.edu (unknown [IPv6:2606:4100:3880:1257::1083]) by postal.iol.unh.edu (Postfix) with ESMTP id 363CB605C380; Tue, 3 Sep 2024 15:47:09 -0400 (EDT) From: jspewock@iol.unh.edu To: yoan.picchi@foss.arm.com, npratte@iol.unh.edu, juraj.linkes@pantheon.tech, probb@iol.unh.edu, thomas@monjalon.net, paul.szczepanek@arm.com, wathsala.vithanage@arm.com, alex.chapman@arm.com, Luca.Vizzarro@arm.com, Honnappa.Nagarahalli@arm.com Cc: dev@dpdk.org, Jeremy Spewock Subject: [PATCH v2 1/5] dts: add TX offload capabilities Date: Tue, 3 Sep 2024 15:46:24 -0400 Message-ID: <20240903194642.24458-2-jspewock@iol.unh.edu> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240903194642.24458-1-jspewock@iol.unh.edu> References: <20240831000058.23009-1-jspewock@iol.unh.edu> <20240903194642.24458-1-jspewock@iol.unh.edu> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Jeremy Spewock The ability to query RX offloading capabilities of a device already exist, but there are situations in other test suites where skipping a test case/suite based on if a TX capability is missing is also desirable. This patch expands the RX offloading capabilities class to also allow for collecting TX offloading capabilities by creating a common parent class with parsing utility that is generalized to both. Signed-off-by: Jeremy Spewock --- dts/framework/remote_session/testpmd_shell.py | 395 +++++++++++++----- 1 file changed, 297 insertions(+), 98 deletions(-) diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py index 99f327a91b..13001d6666 100644 --- a/dts/framework/remote_session/testpmd_shell.py +++ b/dts/framework/remote_session/testpmd_shell.py @@ -21,7 +21,7 @@ from enum import Flag, auto from functools import partial from pathlib import PurePath -from typing import TYPE_CHECKING, Any, ClassVar, TypeAlias +from typing import TYPE_CHECKING, Any, ClassVar, TypeAlias, cast if TYPE_CHECKING: from enum import Enum as NoAliasEnum @@ -661,55 +661,8 @@ class TestPmdPortStats(TextParser): tx_bps: int = field(metadata=TextParser.find_int(r"Tx-bps:\s+(\d+)")) - -class RxOffloadCapability(Flag): - """Rx offload capabilities of a device.""" - - #: - RX_OFFLOAD_VLAN_STRIP = auto() - #: Device supports L3 checksum offload. - RX_OFFLOAD_IPV4_CKSUM = auto() - #: Device supports L4 checksum offload. - RX_OFFLOAD_UDP_CKSUM = auto() - #: Device supports L4 checksum offload. - RX_OFFLOAD_TCP_CKSUM = auto() - #: Device supports Large Receive Offload. - RX_OFFLOAD_TCP_LRO = auto() - #: Device supports QinQ (queue in queue) offload. - RX_OFFLOAD_QINQ_STRIP = auto() - #: Device supports inner packet L3 checksum. - RX_OFFLOAD_OUTER_IPV4_CKSUM = auto() - #: Device supports MACsec. - RX_OFFLOAD_MACSEC_STRIP = auto() - #: Device supports filtering of a VLAN Tag identifier. - RX_OFFLOAD_VLAN_FILTER = 1 << 9 - #: Device supports VLAN offload. - RX_OFFLOAD_VLAN_EXTEND = auto() - #: Device supports receiving segmented mbufs. - RX_OFFLOAD_SCATTER = 1 << 13 - #: Device supports Timestamp. - RX_OFFLOAD_TIMESTAMP = auto() - #: Device supports crypto processing while packet is received in NIC. - RX_OFFLOAD_SECURITY = auto() - #: Device supports CRC stripping. - RX_OFFLOAD_KEEP_CRC = auto() - #: Device supports L4 checksum offload. - RX_OFFLOAD_SCTP_CKSUM = auto() - #: Device supports inner packet L4 checksum. - RX_OFFLOAD_OUTER_UDP_CKSUM = auto() - #: Device supports RSS hashing. - RX_OFFLOAD_RSS_HASH = auto() - #: Device supports - RX_OFFLOAD_BUFFER_SPLIT = auto() - #: Device supports all checksum capabilities. - RX_OFFLOAD_CHECKSUM = RX_OFFLOAD_IPV4_CKSUM | RX_OFFLOAD_UDP_CKSUM | RX_OFFLOAD_TCP_CKSUM - #: Device supports all VLAN capabilities. - RX_OFFLOAD_VLAN = ( - RX_OFFLOAD_VLAN_STRIP - | RX_OFFLOAD_VLAN_FILTER - | RX_OFFLOAD_VLAN_EXTEND - | RX_OFFLOAD_QINQ_STRIP - ) +class OffloadCapability(Flag): + """Offload capabilities of a device.""" @classmethod def from_string(cls, line: str) -> Self: @@ -723,7 +676,7 @@ def from_string(cls, line: str) -> Self: """ flag = cls(0) for flag_name in line.split(): - flag |= cls[f"RX_OFFLOAD_{flag_name}"] + flag |= cls[flag_name] return flag @classmethod @@ -745,20 +698,130 @@ def make_parser(cls, per_port: bool) -> ParserFn: ) +class RxOffloadCapability(OffloadCapability): + """Rx offload capabilities of a device.""" + + #: Device supports L3 checksum offload. + IPV4_CKSUM = auto() + #: Device supports L4 checksum offload. + UDP_CKSUM = auto() + #: Device supports L4 checksum offload. + TCP_CKSUM = auto() + #: Device supports inner packet L3 checksum. + OUTER_IPV4_CKSUM = auto() + #: Device supports crypto processing while packet is received in NIC. + SECURITY = auto() + #: + VLAN_STRIP = auto() + #: Device supports Large Receive Offload. + TCP_LRO = auto() + #: Device supports QinQ (queue in queue) offload. + QINQ_STRIP = auto() + #: Device supports MACsec. + MACSEC_STRIP = auto() + #: Device supports filtering of a VLAN Tag identifier. + VLAN_FILTER = 1 << 9 + #: Device supports VLAN offload. + VLAN_EXTEND = auto() + #: Device supports receiving segmented mbufs. + SCATTER = 1 << 13 + #: Device supports Timestamp. + TIMESTAMP = auto() + #: Device supports CRC stripping. + KEEP_CRC = auto() + #: Device supports L4 checksum offload. + SCTP_CKSUM = auto() + #: Device supports inner packet L4 checksum. + OUTER_UDP_CKSUM = auto() + #: Device supports RSS hashing. + RSS_HASH = auto() + #: Device supports + BUFFER_SPLIT = auto() + #: Device supports all checksum capabilities. + CHECKSUM = IPV4_CKSUM | UDP_CKSUM | TCP_CKSUM + #: Device supports all VLAN capabilities. + VLAN = VLAN_STRIP | VLAN_FILTER | VLAN_EXTEND | QINQ_STRIP + + +class TxOffloadCapability(OffloadCapability): + """Tx offload capabilities of a device.""" + + #: Device supports L3 checksum offload. + IPV4_CKSUM = auto() + #: Device supports L4 checksum offload. + UDP_CKSUM = auto() + #: Device supports L4 checksum offload. + TCP_CKSUM = auto() + #: Device supports inner packet L3 checksum. + OUTER_IPV4_CKSUM = auto() + #: Device supports crypto processing while packet is received in NIC. + SECURITY = auto() + #: + VLAN_INSERT = auto() + #: + QINQ_INSERT = auto() + #: + SCTP_CKSUM = auto() + #: Device supports QinQ (queue in queue) stripping offload. + QINQ_STRIP = auto() + #: Device supports TCP Segmentation Offload. + TCP_TSO = auto() + #: Device supports TCP Segmentation Offload with UDP. + UDP_TSO = auto() + #: Device supports TCP Segmentation Offload with VXLAN tunnels. + VXLAN_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with GRE tunnels. + GRE_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with IPIP tunnels. + IPIP_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with IP tunnels. + IP_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with GENEVE tunnels. + GENEVE_TNL_TSO = auto() + #: Device supports TCP Segmentation Offload with UDP tunnels. + UDP_TNL_TSO = auto() + #: + MACSEC_INSERT = auto() + #: + MT_LOCKFREE = auto() + #: + MULTI_SEGS = auto() + #: + MBUF_FAST_FREE = auto() + + @dataclass -class RxOffloadCapabilities(TextParser): - """The result of testpmd's ``show port rx_offload capabilities`` command.""" +class OffloadCapabilities(TextParser): + """The result of testpmd's ``show port rx/tx_offload capabilities`` command.""" + + #: + port_id: int = field(metadata=TextParser.find_int(r"Offloading Capabilities of port (\d+) :")) + #: Per-queue offload capabilities. + per_queue: RxOffloadCapability | TxOffloadCapability + #: Capabilities other than per-queue offload capabilities. + per_port: RxOffloadCapability | TxOffloadCapability + + +@dataclass +class RxOffloadCapabilities(OffloadCapabilities): + """Extends :class:`OffloadCapabilities` with Rx specific functionality.""" #: - port_id: int = field( - metadata=TextParser.find_int(r"Rx Offloading Capabilities of port (\d+) :") - ) - #: Per-queue Rx offload capabilities. per_queue: RxOffloadCapability = field(metadata=RxOffloadCapability.make_parser(False)) - #: Capabilities other than per-queue Rx offload capabilities. + #: per_port: RxOffloadCapability = field(metadata=RxOffloadCapability.make_parser(True)) +@dataclass +class TxOffloadCapabilities(OffloadCapabilities): + """Extends :class:`OffloadCapabilities` with Tx specific functionality.""" + + #: + per_queue: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(False)) + #: + per_port: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(True)) + + T = TypeVarTuple("T") # type: ignore[misc] @@ -1501,6 +1564,32 @@ def show_port_stats(self, port_id: int) -> TestPmdPortStats: return TestPmdPortStats.parse(output) + def show_port_rx_offload_capabilities(self, port_id: int) -> RxOffloadCapabilities: + """Query the offloading capabilities of a given Rx port. + + Args: + port_id: The ID of the port to query. + + Returns: + Offloading capabilities of the port whose ID matches `port_id`. + """ + command = f"show port {port_id} rx_offload capabilities" + offload_capabilities_out = self.send_command(command) + return RxOffloadCapabilities.parse(offload_capabilities_out) + + def show_port_tx_offload_capabilities(self, port_id: int) -> TxOffloadCapabilities: + """Query the offloading capabilities of a given Tx port. + + Args: + port_id: The ID of the port to query. + + Returns: + Offloading capabilities of the port whose ID matches `port_id`. + """ + command = f"show port {port_id} tx_offload capabilities" + offload_capabilities_out = self.send_command(command) + return TxOffloadCapabilities.parse(offload_capabilities_out) + def _stop_port(self, port_id: int, verify: bool = True) -> None: """Stop port with `port_id` in testpmd. @@ -1856,27 +1945,52 @@ def _close(self) -> None: ====== Capability retrieval methods ====== """ - def get_capabilities_rx_offload( - self, - supported_capabilities: MutableSet["NicCapability"], - unsupported_capabilities: MutableSet["NicCapability"], - ) -> None: - """Get all rx offload capabilities and divide them into supported and unsupported. + @staticmethod + def get_offload_capabilities_func( + is_rx: bool, + ) -> Callable[["TestPmdShell", MutableSet["NicCapability"], MutableSet["NicCapability"]], None]: + """High-order function that returns a method for gathering Rx/Tx offload capabilities. Args: - supported_capabilities: Supported capabilities will be added to this set. - unsupported_capabilities: Unsupported capabilities will be added to this set. + is_rx: If :data:`True` the method that is returned will gather Rx capabilities. If + :data:`False` the returned method will return Tx capabilities. + + Returns: + A method for gathering Rx/Tx offload capabilities that meets the required structure. """ - self._logger.debug("Getting rx offload capabilities.") - command = f"show port {self.ports[0].id} rx_offload capabilities" - rx_offload_capabilities_out = self.send_command(command) - rx_offload_capabilities = RxOffloadCapabilities.parse(rx_offload_capabilities_out) - self._update_capabilities_from_flag( - supported_capabilities, - unsupported_capabilities, - RxOffloadCapability, - rx_offload_capabilities.per_port | rx_offload_capabilities.per_queue, - ) + + def get_capabilities( + self: "TestPmdShell", + supported_capabilities: MutableSet["NicCapability"], + unsupported_capabilities: MutableSet["NicCapability"], + ) -> None: + """Get all rx/tx offload capabilities and divide them into supported and unsupported. + + Args: + self: The shell to get the capabilities from. + supported_capabilities: Supported capabilities will be added to this set. + unsupported_capabilities: Unsupported capabilities will be added to this set. + """ + capabilities_class = RxOffloadCapability if is_rx else TxOffloadCapability + offload_type = "RX" if is_rx else "TX" + offload_capabilities_func = ( + self.show_port_rx_offload_capabilities + if is_rx + else self.show_port_tx_offload_capabilities + ) + offload_capabilities = offload_capabilities_func(self.ports[0].id) + # Cast to the generic type for mypy + per_port = cast(OffloadCapability, offload_capabilities.per_port) + per_queue = cast(OffloadCapability, offload_capabilities.per_queue) + self._update_capabilities_from_flag( + supported_capabilities, + unsupported_capabilities, + capabilities_class, + per_port | per_queue, + prefix=f"{offload_type}_OFFLOAD_", + ) + + return get_capabilities def _update_capabilities_from_flag( self, @@ -1884,13 +1998,14 @@ def _update_capabilities_from_flag( unsupported_capabilities: MutableSet["NicCapability"], flag_class: type[Flag], supported_flags: Flag, + prefix: str = "", ) -> None: """Divide all flags from `flag_class` into supported and unsupported.""" for flag in flag_class: if flag in supported_flags: - supported_capabilities.add(NicCapability[str(flag.name)]) + supported_capabilities.add(NicCapability[f"{prefix}{flag.name}"]) else: - unsupported_capabilities.add(NicCapability[str(flag.name)]) + unsupported_capabilities.add(NicCapability[f"{prefix}{flag.name}"]) def get_capabilities_rxq_info( self, @@ -1983,83 +2098,167 @@ class NicCapability(NoAliasEnum): ) #: RX_OFFLOAD_VLAN_STRIP: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L3 checksum offload. RX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. RX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. RX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports Large Receive Offload. RX_OFFLOAD_TCP_LRO: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports QinQ (queue in queue) offload. RX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports inner packet L3 checksum. RX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports MACsec. RX_OFFLOAD_MACSEC_STRIP: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports filtering of a VLAN Tag identifier. RX_OFFLOAD_VLAN_FILTER: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports VLAN offload. RX_OFFLOAD_VLAN_EXTEND: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports receiving segmented mbufs. RX_OFFLOAD_SCATTER: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports Timestamp. RX_OFFLOAD_TIMESTAMP: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports crypto processing while packet is received in NIC. RX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports CRC stripping. RX_OFFLOAD_KEEP_CRC: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. RX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports inner packet L4 checksum. RX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports RSS hashing. RX_OFFLOAD_RSS_HASH: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports scatter Rx packets to segmented mbufs. RX_OFFLOAD_BUFFER_SPLIT: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports all checksum capabilities. RX_OFFLOAD_CHECKSUM: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports all VLAN capabilities. RX_OFFLOAD_VLAN: TestPmdShellCapabilityMethod = partial( - TestPmdShell.get_capabilities_rx_offload + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports L3 checksum offload. + TX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports L4 checksum offload. + TX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports L4 checksum offload. + TX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports inner packet L3 checksum. + TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports crypto processing while packet is received in NIC. + TX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_VLAN_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_QINQ_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports QinQ (queue in queue) stripping offload. + TX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload. + TX_OFFLOAD_TCP_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with UDP. + TX_OFFLOAD_UDP_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with VXLAN tunnels. + TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with GRE tunnels. + TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with IPIP tunnels. + TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with IP tunnels. + TX_OFFLOAD_IP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with GENEVE tunnels. + TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload with UDP tunnels. + TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_MACSEC_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_MT_LOCKFREE: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_MULTI_SEGS: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports Rx queue setup after device started. RUNTIME_RX_QUEUE_SETUP: TestPmdShellCapabilityMethod = partial( From patchwork Tue Sep 3 19:46:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Spewock X-Patchwork-Id: 143579 X-Patchwork-Delegate: paul.szczepanek@arm.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D3F6A458F4; Tue, 3 Sep 2024 21:47:22 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id BFE85410FD; Tue, 3 Sep 2024 21:47:22 +0200 (CEST) Received: from mail-io1-f97.google.com (mail-io1-f97.google.com [209.85.166.97]) by mails.dpdk.org (Postfix) with ESMTP id 8ABEF410F9 for ; Tue, 3 Sep 2024 21:47:21 +0200 (CEST) Received: by mail-io1-f97.google.com with SMTP id ca18e2360f4ac-82a274dd17eso205968739f.1 for ; Tue, 03 Sep 2024 12:47:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1725392841; x=1725997641; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=K22fTdHRLvxZ23hZFfvj1GXB50/yYVQg4WtjMqCqWPU=; b=by6lxD+wdKrQmras+KnDh/veK4J8hWvWd7ZzBuuz/jhjAohXUQ6fuzCGVESuSHRDCS EXwgK44wW4uhqm+yq1oUnCUbhIqGf9qZAryL7zeEjKA7c3v7vKhzPPXn8XmLhqHBCH3q RC6nwh2rZliZnDp/0lII6rfNm6i8N5l8Nu0Yc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725392841; x=1725997641; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=K22fTdHRLvxZ23hZFfvj1GXB50/yYVQg4WtjMqCqWPU=; b=MV11fuKYRYPzBb9GAOhqz3MyohexJjjWGmQ/TW0PIYaPgHzL61KacEW+agCqaWU86t KMaQ2T57sKyP6dS1Xby8hCh51b4aAKhrcfLqQfJOxOa62508wZ9dfW0IXjmhxPRw2QRo jYeNbo9r0X0Ni6iE/7z1W8R44ttz5+QpYZZ2Em3dzeWdeeZmxMMvgN9efx3mfXjHx8yu o7h4PtxjFoLKlJTPgxyA1j7kNzx53/f3iqJ08OuHJj+LIGTbVtkTrLJPnq183aLmgHuf G7Co/bWiPyLHY4LKH3sZz6Hmrvw0GpwcFJCZKaJ/lKVW3OEIZhD2QKKKxYg+8AiwLpQI BT2g== X-Gm-Message-State: AOJu0YyfL2AZk/c7kR6CqfSQqTBZigMXnkFDGYoSITsca5DK60iJVa97 mkpvvW6eMg090h4pnXDloUZ0cYCGJLfd+u3F1+9WFPjGyQffSFma07PyHH4I+TIXZyqbJH2gTW2 VpM0mw89cBfB7VAiZtrx7+LlJ1vE9TlXo X-Google-Smtp-Source: AGHT+IEYhD3kbwD0m5xnLCMEDU1V93Dij0JeJ5XWKRJKbc0Pp8vsxHA6Acj4ebj7EEkpC/boTIOu7SlB0SUY X-Received: by 2002:a05:6602:3fc7:b0:82a:3dc3:cfc6 with SMTP id ca18e2360f4ac-82a3dc3d0d6mr829622539f.8.1725392840697; Tue, 03 Sep 2024 12:47:20 -0700 (PDT) Received: from postal.iol.unh.edu (postal.iol.unh.edu. [132.177.123.84]) by smtp-relay.gmail.com with ESMTPS id ca18e2360f4ac-82a1a498964sm25023839f.27.2024.09.03.12.47.20 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Sep 2024 12:47:20 -0700 (PDT) X-Relaying-Domain: iol.unh.edu Received: from iol.unh.edu (unknown [IPv6:2606:4100:3880:1257::1083]) by postal.iol.unh.edu (Postfix) with ESMTP id 54E70605C380; Tue, 3 Sep 2024 15:47:19 -0400 (EDT) From: jspewock@iol.unh.edu To: yoan.picchi@foss.arm.com, npratte@iol.unh.edu, juraj.linkes@pantheon.tech, probb@iol.unh.edu, thomas@monjalon.net, paul.szczepanek@arm.com, wathsala.vithanage@arm.com, alex.chapman@arm.com, Luca.Vizzarro@arm.com, Honnappa.Nagarahalli@arm.com Cc: dev@dpdk.org, Jeremy Spewock Subject: [PATCH v2 2/5] dts: add a distinction between port and queue offload capabilities Date: Tue, 3 Sep 2024 15:46:25 -0400 Message-ID: <20240903194642.24458-3-jspewock@iol.unh.edu> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240903194642.24458-1-jspewock@iol.unh.edu> References: <20240831000058.23009-1-jspewock@iol.unh.edu> <20240903194642.24458-1-jspewock@iol.unh.edu> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Jeremy Spewock Currently in the framework offloading capabilities are collected at a device-level meaning that, if a capability is supported on either an entire port or individual queues on that port, it is marked as supported for the device. In some cases there is a want for being able to get the granularity of if an offload can be applied on queues rather than just on the device in general since all capabilities that are supported on queues are supported on ports, but not all capabilities that are supported on ports are supported on queues. This means that the less granular option of a combination of the two is still achievable by simply specifying that you require a port to be capable of an offload. This allows for granularity where needed, but generalization elsewhere. Signed-off-by: Jeremy Spewock --- dts/framework/remote_session/testpmd_shell.py | 257 +++++++++++++++--- dts/tests/TestSuite_pmd_buffer_scatter.py | 2 +- 2 files changed, 216 insertions(+), 43 deletions(-) diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py index 13001d6666..df4ed7ce5c 100644 --- a/dts/framework/remote_session/testpmd_shell.py +++ b/dts/framework/remote_session/testpmd_shell.py @@ -1982,12 +1982,21 @@ def get_capabilities( # Cast to the generic type for mypy per_port = cast(OffloadCapability, offload_capabilities.per_port) per_queue = cast(OffloadCapability, offload_capabilities.per_queue) + # Any offload that can be set on an individual queue can also be set on the whole port, + # but not every capability that can be set on the port can be set on each queue. self._update_capabilities_from_flag( supported_capabilities, unsupported_capabilities, capabilities_class, per_port | per_queue, - prefix=f"{offload_type}_OFFLOAD_", + prefix=f"PORT_{offload_type}_OFFLOAD_", + ) + self._update_capabilities_from_flag( + supported_capabilities, + unsupported_capabilities, + capabilities_class, + per_queue, + prefix=f"QUEUE_{offload_type}_OFFLOAD_", ) return get_capabilities @@ -2097,167 +2106,331 @@ class NicCapability(NoAliasEnum): TestPmdShell.get_capabilities_rxq_info ) #: - RX_OFFLOAD_VLAN_STRIP: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_VLAN_STRIP: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L3 checksum offload. - RX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. - RX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. - RX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports Large Receive Offload. - RX_OFFLOAD_TCP_LRO: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_TCP_LRO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports QinQ (queue in queue) offload. - RX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports inner packet L3 checksum. - RX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports MACsec. - RX_OFFLOAD_MACSEC_STRIP: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_MACSEC_STRIP: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports filtering of a VLAN Tag identifier. - RX_OFFLOAD_VLAN_FILTER: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_VLAN_FILTER: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports VLAN offload. - RX_OFFLOAD_VLAN_EXTEND: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_VLAN_EXTEND: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports receiving segmented mbufs. - RX_OFFLOAD_SCATTER: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_SCATTER: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports Timestamp. - RX_OFFLOAD_TIMESTAMP: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_TIMESTAMP: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports crypto processing while packet is received in NIC. - RX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports CRC stripping. - RX_OFFLOAD_KEEP_CRC: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_KEEP_CRC: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L4 checksum offload. - RX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports inner packet L4 checksum. - RX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports RSS hashing. - RX_OFFLOAD_RSS_HASH: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_RSS_HASH: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports scatter Rx packets to segmented mbufs. - RX_OFFLOAD_BUFFER_SPLIT: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_BUFFER_SPLIT: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports all checksum capabilities. - RX_OFFLOAD_CHECKSUM: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_CHECKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports all VLAN capabilities. - RX_OFFLOAD_VLAN: TestPmdShellCapabilityMethod = partial( + PORT_RX_OFFLOAD_VLAN: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(True) ) #: Device supports L3 checksum offload. - TX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports L4 checksum offload. - TX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports L4 checksum offload. - TX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports inner packet L3 checksum. - TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports crypto processing while packet is received in NIC. - TX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: - TX_OFFLOAD_VLAN_INSERT: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_VLAN_INSERT: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: - TX_OFFLOAD_QINQ_INSERT: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_QINQ_INSERT: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: - TX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports QinQ (queue in queue) stripping offload. - TX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports TCP Segmentation Offload. - TX_OFFLOAD_TCP_TSO: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_TCP_TSO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports TCP Segmentation Offload with UDP. - TX_OFFLOAD_UDP_TSO: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_UDP_TSO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports TCP Segmentation Offload with VXLAN tunnels. - TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports TCP Segmentation Offload with GRE tunnels. - TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports TCP Segmentation Offload with IPIP tunnels. - TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports TCP Segmentation Offload with IP tunnels. - TX_OFFLOAD_IP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_IP_TNL_TSO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports TCP Segmentation Offload with GENEVE tunnels. - TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports TCP Segmentation Offload with UDP tunnels. - TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + PORT_TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + PORT_TX_OFFLOAD_MACSEC_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + PORT_TX_OFFLOAD_MT_LOCKFREE: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + PORT_TX_OFFLOAD_MULTI_SEGS: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + PORT_TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + QUEUE_RX_OFFLOAD_VLAN_STRIP: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports L3 checksum offload on queues. + QUEUE_RX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports L4 checksum offload on queues. + QUEUE_RX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports L4 checksum offload on queues. + QUEUE_RX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports Large Receive Offload on queues. + QUEUE_RX_OFFLOAD_TCP_LRO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports QinQ (queue in queue) offload on queues. + QUEUE_RX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports inner packet L3 checksum on queues. + QUEUE_RX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports MACsec on queues. + QUEUE_RX_OFFLOAD_MACSEC_STRIP: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports filtering of a VLAN Tag identifier on queues. + QUEUE_RX_OFFLOAD_VLAN_FILTER: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports VLAN offload on queues. + QUEUE_RX_OFFLOAD_VLAN_EXTEND: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports receiving segmented mbufs on queues. + QUEUE_RX_OFFLOAD_SCATTER: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports Timestamp on queues. + QUEUE_RX_OFFLOAD_TIMESTAMP: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports crypto processing on queues while packet is received in NIC. + QUEUE_RX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports CRC stripping on queues. + QUEUE_RX_OFFLOAD_KEEP_CRC: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports L4 checksum offload on queues. + QUEUE_RX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports inner packet L4 checksum o nqueues. + QUEUE_RX_OFFLOAD_OUTER_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports RSS hashing on queues. + QUEUE_RX_OFFLOAD_RSS_HASH: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports scatter Rx packets to segmented mbufs on queues. + QUEUE_RX_OFFLOAD_BUFFER_SPLIT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports all checksum capabilities on queues. + QUEUE_RX_OFFLOAD_CHECKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports all VLAN capabilities on queues. + QUEUE_RX_OFFLOAD_VLAN: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(True) + ) + #: Device supports L3 checksum offload on queues. + QUEUE_TX_OFFLOAD_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports L4 checksum offload on queues. + QUEUE_TX_OFFLOAD_UDP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports L4 checksum offload on queues. + QUEUE_TX_OFFLOAD_TCP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports inner packet L3 checksum on queues. + QUEUE_TX_OFFLOAD_OUTER_IPV4_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports crypto processing on queues while packet is received in NIC. + QUEUE_TX_OFFLOAD_SECURITY: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + QUEUE_TX_OFFLOAD_VLAN_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + QUEUE_TX_OFFLOAD_QINQ_INSERT: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: + QUEUE_TX_OFFLOAD_SCTP_CKSUM: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports QinQ (queue in queue) stripping offload on queues. + QUEUE_TX_OFFLOAD_QINQ_STRIP: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload on queues. + QUEUE_TX_OFFLOAD_TCP_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload on queues with UDP. + QUEUE_TX_OFFLOAD_UDP_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload on queues with VXLAN tunnels. + QUEUE_TX_OFFLOAD_VXLAN_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload on queues with GRE tunnels. + QUEUE_TX_OFFLOAD_GRE_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload on queues with IPIP tunnels. + QUEUE_TX_OFFLOAD_IPIP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload on queues with IP tunnels. + QUEUE_TX_OFFLOAD_IP_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: Device supports TCP Segmentation Offload on queues with GENEVE tunnels. + QUEUE_TX_OFFLOAD_GENEVE_TNL_TSO: TestPmdShellCapabilityMethod = partial( + TestPmdShell.get_offload_capabilities_func(False) + ) + #: #: Device supports TCP Segmentation Offload on queues with UDP tunnels. + QUEUE_TX_OFFLOAD_UDP_TNL_TSO: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: - TX_OFFLOAD_MACSEC_INSERT: TestPmdShellCapabilityMethod = partial( + QUEUE_TX_OFFLOAD_MACSEC_INSERT: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: - TX_OFFLOAD_MT_LOCKFREE: TestPmdShellCapabilityMethod = partial( + QUEUE_TX_OFFLOAD_MT_LOCKFREE: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: - TX_OFFLOAD_MULTI_SEGS: TestPmdShellCapabilityMethod = partial( + QUEUE_TX_OFFLOAD_MULTI_SEGS: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: - TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellCapabilityMethod = partial( + QUEUE_TX_OFFLOAD_MBUF_FAST_FREE: TestPmdShellCapabilityMethod = partial( TestPmdShell.get_offload_capabilities_func(False) ) #: Device supports Rx queue setup after device started. diff --git a/dts/tests/TestSuite_pmd_buffer_scatter.py b/dts/tests/TestSuite_pmd_buffer_scatter.py index 64c48b0793..a1803588da 100644 --- a/dts/tests/TestSuite_pmd_buffer_scatter.py +++ b/dts/tests/TestSuite_pmd_buffer_scatter.py @@ -28,7 +28,7 @@ from framework.testbed_model.capability import NicCapability, requires -@requires(NicCapability.RX_OFFLOAD_SCATTER) +@requires(NicCapability.PORT_RX_OFFLOAD_SCATTER) class TestPmdBufferScatter(TestSuite): """DPDK PMD packet scattering test suite. From patchwork Tue Sep 3 19:46:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Spewock X-Patchwork-Id: 143580 X-Patchwork-Delegate: paul.szczepanek@arm.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id F0CC2458F4; Tue, 3 Sep 2024 21:47:29 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 030C041109; Tue, 3 Sep 2024 21:47:25 +0200 (CEST) Received: from mail-oa1-f98.google.com (mail-oa1-f98.google.com [209.85.160.98]) by mails.dpdk.org (Postfix) with ESMTP id 5260C41104 for ; Tue, 3 Sep 2024 21:47:23 +0200 (CEST) Received: by mail-oa1-f98.google.com with SMTP id 586e51a60fabf-277e6be2ef6so1371836fac.0 for ; Tue, 03 Sep 2024 12:47:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1725392842; x=1725997642; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fOxSaaN8pkSFtnECdzM/kjwL3ccA7MJgQ6hCr9W45tg=; b=OreT63vT+PuUaNf5RXqVqlNij7Fr+R0z7MXH+6x2MdiPXgIDlITzWVpMqc4Tl5OJRn KkThq2ud+HzDxqk3qfvk1k6Su0j8xWrij6jpaHbMtJHEi8hQhpcdhP6l/58yD7/FJ4OQ JFrGY+F8/oXa/LvpSVcETJLTUfM9lj3OQM6vA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725392842; x=1725997642; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fOxSaaN8pkSFtnECdzM/kjwL3ccA7MJgQ6hCr9W45tg=; b=XrZ6Z/xfMT/ZzJc8l9wLX0il7lG3qaO84RYDnVMP41Mi1XJ6LUBHxOjGw46gNOdjPI ZSjFmofBQgAGJEvb7OvqDlIMfZ0/nxYeXzvpB+qtEwaiP0WP+cYt0JApcAuhfvuO4DdW 98jsSTGCQtAM3W0m7TW+QcGG2Ny46TWNLzKKK4dxPadFaVqO48lolitdqsBL+IHB5Vft lafJS96OjX3bLTefBRIvMr4i+gY4ZL57v+tfE95NNQQ5UjiqvZglIFa/yjcLHc2PZm2P xY2PFWWdW9AMIKMflJZ8NAb2WiaMoZmHtyGPtmU0SoVr49H1E9+eQC6ppTUAVCl3x9ZT 52Ug== X-Gm-Message-State: AOJu0YzQl6Ns+ICC2GnAkBNcddxsnm1bp6BASRLn4sW4tDpVTbnBHGGZ TWvb4KxXM+kKcTZPFYHNvYp5oRuX4+jTgE2+SQWYr2GUDePRnscKhNXGVGAe4aLwLABWqQdfUWj y3aQhzoYzmHD5VQT1N79FmoQjWIeerUyEDeroY9E+Vasyl4+E X-Google-Smtp-Source: AGHT+IG6e3QzaKb4NfUgvkNUY9BYM9D+9tIZZZ1VnRzLdPBlbVaH+maQJSAzX7DUw8DbSVlfro3i6SGLTbRt X-Received: by 2002:a05:6870:158f:b0:270:25e:b341 with SMTP id 586e51a60fabf-2780050e057mr7618619fac.36.1725392842328; Tue, 03 Sep 2024 12:47:22 -0700 (PDT) Received: from postal.iol.unh.edu (postal.iol.unh.edu. [2606:4100:3880:1234::84]) by smtp-relay.gmail.com with ESMTPS id 586e51a60fabf-277abd199f7sm351366fac.36.2024.09.03.12.47.22 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Sep 2024 12:47:22 -0700 (PDT) X-Relaying-Domain: iol.unh.edu Received: from iol.unh.edu (unknown [IPv6:2606:4100:3880:1257::1083]) by postal.iol.unh.edu (Postfix) with ESMTP id 47C40605C380; Tue, 3 Sep 2024 15:47:21 -0400 (EDT) From: jspewock@iol.unh.edu To: yoan.picchi@foss.arm.com, npratte@iol.unh.edu, juraj.linkes@pantheon.tech, probb@iol.unh.edu, thomas@monjalon.net, paul.szczepanek@arm.com, wathsala.vithanage@arm.com, alex.chapman@arm.com, Luca.Vizzarro@arm.com, Honnappa.Nagarahalli@arm.com Cc: dev@dpdk.org, Jeremy Spewock Subject: [PATCH v2 3/5] dts: add offload configuration querying to testpmd Date: Tue, 3 Sep 2024 15:46:26 -0400 Message-ID: <20240903194642.24458-4-jspewock@iol.unh.edu> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240903194642.24458-1-jspewock@iol.unh.edu> References: <20240831000058.23009-1-jspewock@iol.unh.edu> <20240903194642.24458-1-jspewock@iol.unh.edu> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Jeremy Spewock Testpmd offers methods for querying the runtime configuration of offloads on a device that are useful for verification, but bindings to reach these methods do not exist in the Testpmd API offered in the framework. This patch creates methods that can query this configuration and also generalizes the OffloadCapability class to allow it to account for parsing the configuration output as well since the flag values will be the same. Signed-off-by: Jeremy Spewock --- dts/framework/remote_session/testpmd_shell.py | 92 ++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py index df4ed7ce5c..71859c63da 100644 --- a/dts/framework/remote_session/testpmd_shell.py +++ b/dts/framework/remote_session/testpmd_shell.py @@ -680,21 +680,45 @@ def from_string(cls, line: str) -> Self: return flag @classmethod - def make_parser(cls, per_port: bool) -> ParserFn: + def from_list(cls, lines: list[str]) -> list[Self]: + """Make a list of instances from a list of strings that contain flag names. + + The strings are expected to separate the flag names by whitespace. + + Args: + lines: The list of strings to parse. + + Returns: + A list of instances parsed from each string in `lines`. + """ + return [cls.from_string(line) for line in lines] + + @classmethod + def make_parser(cls, per_port: bool, find_multiple: bool = False) -> ParserFn: """Make a parser function. Args: per_port: If :data:`True`, will return capabilities per port. If :data:`False`, will return capabilities per queue. + find_multiple: If :data:`True`, will use :func:`TextParser.find_all` to find all + matches for the regex query and return a list of instances based on those matches. + If :data:`False`, will return a single instance of the flag based off a single + match. 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" + parser_func: Callable[..., ParserFn] | Callable[..., ParserFn] = ( + TextParser.find_all if find_multiple else TextParser.find + ) + instance_func: Callable[..., list[OffloadCapability]] | Callable[..., OffloadCapability] = ( + cls.from_list if find_multiple else cls.from_string + ) return TextParser.wrap( - TextParser.find(rf"Per {granularity}\s+:(.*)$", re.MULTILINE), - cls.from_string, + parser_func(rf"{granularity}[\s\[\]\d]+:(.*)$", re.MULTILINE), + instance_func, ) @@ -822,6 +846,42 @@ class TxOffloadCapabilities(OffloadCapabilities): per_port: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(True)) +@dataclass +class OffloadConfiguration(TextParser): + """The result of testpmd's ``show port rx/tx_offload configuration`` command.""" + + #: + port_id: int = field(metadata=TextParser.find_int(r"Offloading Configuration of port (\d+) :")) + #: Queue offload configurations. + queues: list[RxOffloadCapability] | list[TxOffloadCapability] + #: Port offload configuration. + port: RxOffloadCapability | TxOffloadCapability + + +@dataclass +class RxOffloadConfiguration(OffloadConfiguration): + """Extends :class:`OffloadingConfiguration` with Rx specific functionality.""" + + #: + queues: list[RxOffloadCapability] = field( + metadata=RxOffloadCapability.make_parser(False, find_multiple=True) + ) + #: + port: RxOffloadCapability = field(metadata=RxOffloadCapability.make_parser(True)) + + +@dataclass +class TxOffloadConfiguration(OffloadConfiguration): + """Extends :class:`OffloadingConfiguration` with Tx specific functionality.""" + + #: + queues: list[TxOffloadCapability] = field( + metadata=TxOffloadCapability.make_parser(False, find_multiple=True) + ) + #: + port: TxOffloadCapability = field(metadata=TxOffloadCapability.make_parser(True)) + + T = TypeVarTuple("T") # type: ignore[misc] @@ -1590,6 +1650,32 @@ def show_port_tx_offload_capabilities(self, port_id: int) -> TxOffloadCapabiliti offload_capabilities_out = self.send_command(command) return TxOffloadCapabilities.parse(offload_capabilities_out) + def show_port_rx_offload_configuration(self, port_id: int) -> RxOffloadConfiguration: + """Get the Rx offload configuration on a given port. + + Args: + port_id: The ID of the port to query the configuration of. + + Returns: + An instance of :class:`RxOffloadConfiguration` containing the offload configuration of + the port. + """ + output = self.send_command(f"show port {port_id} rx_offload configuration") + return RxOffloadConfiguration.parse(output) + + def show_port_tx_offload_configuration(self, port_id: int) -> TxOffloadConfiguration: + """Get the Tx offload configuration on a given port. + + Args: + port_id: The ID of the port to query the configuration of. + + Returns: + An instance of :class:`TxOffloadConfiguration` containing the offload configuration of + the port. + """ + output = self.send_command(f"show port {port_id} tx_offload configuration") + return TxOffloadConfiguration.parse(output) + def _stop_port(self, port_id: int, verify: bool = True) -> None: """Stop port with `port_id` in testpmd. From patchwork Tue Sep 3 19:46:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Spewock X-Patchwork-Id: 143581 X-Patchwork-Delegate: paul.szczepanek@arm.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 63F12458F4; Tue, 3 Sep 2024 21:47:41 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C507341148; Tue, 3 Sep 2024 21:47:26 +0200 (CEST) Received: from mail-il1-f228.google.com (mail-il1-f228.google.com [209.85.166.228]) by mails.dpdk.org (Postfix) with ESMTP id 3F1F7410F1 for ; Tue, 3 Sep 2024 21:47:24 +0200 (CEST) Received: by mail-il1-f228.google.com with SMTP id e9e14a558f8ab-39f4ec52c5fso13741205ab.2 for ; Tue, 03 Sep 2024 12:47:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1725392843; x=1725997643; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YCUMYDQj1AHeCuQWEQbgc8rLUZNamzndptquhhcUAGY=; b=WTiCOtvpCa0ezy91mhqmKdW79jyRuhCW08incXoI+AhEHc5rFdSiZ1XfFUaxHxZgKf dFlsqgr0TmhnnvKfRTUXBztH8sL384w7Mpc7LvSiHiQsSvIb6HblJjBK26N9DP8aK9TF IdfvY9cdweL/jk1pNSXvbUZRv5rUv1uBZk984= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725392843; x=1725997643; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YCUMYDQj1AHeCuQWEQbgc8rLUZNamzndptquhhcUAGY=; b=Sm+slNac3y7JgGdYeQ7gN9+ux4IE7zoa/ReM678O2Bg3fo6a1kHYKIHCOQSjZU0HsQ S/GnO9+1XSGWjfZMJG6qQQTVCFZk+dJlkPM3ICXWsSBC+eiJPGIkDEpAavxEmDVQnBaV AXnX/zzPnm/cRCaRq6uEX45I9JjB5n3fachpY9EDT097eb1fzbvgFQkyEK2fgWRBAlgR a1rUNzlkx+MltKnM6mAdfzJ+JIkS3F7O5d4yi4DvUHxY4IETIxlM5qCd/r4xppA5OhFr uQ93OtouGHsQFQbiE1+avX/+m085TehYJ/J9o/yynZD/jjVgjPCBDtBrSvS+RX5oH01S Vl0Q== X-Gm-Message-State: AOJu0YxLOf97GJlWN3AYooAEVCJBAsFmnEjTMsriH18xF1YnNwbL3bgj 0JFadlSjUii2TO/siR0m1lrCN4S2JY+e+rABEWnMIUsWrjhgXq3kq8cFoi8+ROneW0T1zcS125W VbsWn8Xwrkfd87pat860wJj7d5Y1gQaaZ X-Google-Smtp-Source: AGHT+IGvzfpadbD72OvJRlJzrXTkepaiAbDOURHv5OkeLaov4tfnDvVN/ZuA1AYYDW4yeJIcvH+vicbspFg1 X-Received: by 2002:a05:6e02:2145:b0:397:351b:2c0c with SMTP id e9e14a558f8ab-39f4f6c1792mr113832895ab.17.1725392843494; Tue, 03 Sep 2024 12:47:23 -0700 (PDT) Received: from postal.iol.unh.edu (postal.iol.unh.edu. [132.177.123.84]) by smtp-relay.gmail.com with ESMTPS id e9e14a558f8ab-39f3b0787c2sm4477085ab.62.2024.09.03.12.47.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Sep 2024 12:47:23 -0700 (PDT) X-Relaying-Domain: iol.unh.edu Received: from iol.unh.edu (unknown [IPv6:2606:4100:3880:1257::1083]) by postal.iol.unh.edu (Postfix) with ESMTP id 60288605C381; Tue, 3 Sep 2024 15:47:22 -0400 (EDT) From: jspewock@iol.unh.edu To: yoan.picchi@foss.arm.com, npratte@iol.unh.edu, juraj.linkes@pantheon.tech, probb@iol.unh.edu, thomas@monjalon.net, paul.szczepanek@arm.com, wathsala.vithanage@arm.com, alex.chapman@arm.com, Luca.Vizzarro@arm.com, Honnappa.Nagarahalli@arm.com Cc: dev@dpdk.org, Jeremy Spewock Subject: [PATCH v2 4/5] dts: add methods for configuring offloads on a device in testpmd Date: Tue, 3 Sep 2024 15:46:27 -0400 Message-ID: <20240903194642.24458-5-jspewock@iol.unh.edu> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240903194642.24458-1-jspewock@iol.unh.edu> References: <20240831000058.23009-1-jspewock@iol.unh.edu> <20240903194642.24458-1-jspewock@iol.unh.edu> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Jeremy Spewock Testpmd offers methods to add and remove offloads from both ports and queues on ports, but there are not yet method bindings in the Testpmd API that the framework provides to reach them. This patch adds these bindings for future test cases/suites that require certain functionalities to be offloaded on the device. Signed-off-by: Jeremy Spewock --- dts/framework/remote_session/testpmd_shell.py | 142 +++++++++++++++++- 1 file changed, 141 insertions(+), 1 deletion(-) diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py index 71859c63da..447d6a617d 100644 --- a/dts/framework/remote_session/testpmd_shell.py +++ b/dts/framework/remote_session/testpmd_shell.py @@ -32,7 +32,7 @@ from typing_extensions import TypeVarTuple -from framework.exception import InteractiveCommandExecutionError +from framework.exception import InteractiveCommandExecutionError, InternalError from framework.params.testpmd import SimpleForwardingModes, TestPmdParams from framework.params.types import TestPmdParamsDict from framework.parser import ParserFn, TextParser @@ -2002,6 +2002,146 @@ def set_verbose(self, level: int, verify: bool = True) -> None: f"Testpmd failed to set verbose level to {level}." ) + @stop_then_start_port() + def _set_offload( + self, + port_id: int, + is_rx: bool, + offloads: OffloadCapability, + on: bool, + queue_id: int | None = None, + verify: bool = True, + ) -> None: + """Base method for configuring offloads on ports and queues. + + If `queue_id` is not specified then it is assumed that you want to set the offloads on the + port rather than a queue. + """ + for offload in type(offloads): + if offload not in offloads or offload.name is None: + continue + port_type = "rx" if is_rx else "tx" + command = [ + "port", + f"{port_id}", + f"{port_type}_offload", + f"{offload.name.lower()}", + f"{'on' if on else 'off'}", + ] + if queue_id is not None: + # If modifying queues the command is "port rxq ..." + command.insert(2, f"{port_type}q {queue_id}") + else: + # If modifying a port the command is "port config ..." + command.insert(1, "config") + + self.send_command(" ".join(command)) + if verify: + # verification of ports has to be done based on if it was applied to all queues or + # not because the "Per Port" line doesn't get modified until the port is started. + current_offload_conf: OffloadConfiguration = ( + self.show_port_rx_offload_configuration(port_id) + if is_rx + else self.show_port_tx_offload_configuration(port_id) + ) + # Casting to the generic type is required for mypy + queues_capabilities = cast(list[OffloadCapability], current_offload_conf.queues) + if queue_id is not None and len(current_offload_conf.queues) < queue_id + 1: + raise InternalError(f"Queue {queue_id} does not exist in testpmd") + capability_is_set = ( + len(current_offload_conf.queues) > 0 + and (queue_id is not None and offload in queues_capabilities[queue_id]) + or all(offload in conf for conf in queues_capabilities) + ) + if capability_is_set != on: + self._logger.debug( + f"Test pmd failed to modify capabilities on port {port_id}:\n" + f"{current_offload_conf.queues}" + ) + raise InteractiveCommandExecutionError( + f"Test pmd failed to {'add' if on else 'remove'} capability {offload.name} " + f"{'to' if on else 'from'} port {port_id}." + ) + + def set_port_offload( + self, + port_id: int, + is_rx: bool, + offload: OffloadCapability, + on: bool, + verify: bool = True, + ) -> None: + """Configure Rx/Tx offload on a port. + + Args: + port_id: The ID of the port to set configure the offload on. + is_rx: A flag that signifies which type of offload to set. If :data:`True` an Rx + offload will be set, otherwise a Tx offload will be set. + offload: The offload to set on the port. + on: If :data:`True` the specified offload will be set turned on, otherwise the offload + will be turned off. + verify: If :data:`True` an additional command will be sent to check the configuration + of offloads on the port to verify `offload` was set properly. Defaults to + :data:`True`. + + Raises: + InteractiveCommandExecutionError: If `verify` is :data:`True` and testpmd failed to + set the offload on the port. + """ + self._set_offload(port_id, is_rx, offload, on, None, verify) + + def set_queue_offload( + self, + port_id: int, + queue_id: int, + is_rx: bool, + offload: OffloadCapability, + on: bool, + verify: bool = True, + ) -> None: + """Configure Rx/Tx offload on a queue that resides on a specified port. + + Args: + port_id: The ID of the port where the queue resides. + queue_id: The ID of the queue on the port. + is_rx: A flag that signifies which type of offload to set. If :data:`True` an Rx + offload will be set, otherwise a Tx offload will be set. + offload: The offload to set on a port. + on: If :data:`True` the offload will be turned on, otherwise the offload will be turned + off. + verify: If :data:`True` an additional command will be sent to check the configuration + of the queue to validate that the offload was configured properly. Defaults to + :data:`True`. + + Raises: + InteractiveCommandExecutionError: If `verify` is :data:`True` and testpmd failed to + set the offload on the queue. + """ + self._set_offload(port_id, is_rx, offload, on, queue_id, verify) + + def is_port_offload_configured( + self, port_id: int, is_rx: bool, offload: OffloadCapability + ) -> bool: + """Verify whether or not an Rx/Tx offload is currently configured on a port. + + Args: + port_id: The ID of the port to check the configuration of. + is_rx: If :data:`True` the Rx offloads of the port will be checked, otherwise the Tx + offloads will be checked. + offload: The offload to search for on the port. + + Returns: + :data:`True` if the offload is configured on the port, :data:`False` otherwise. + """ + offload_config: OffloadConfiguration = ( + self.show_port_rx_offload_configuration(port_id) + if is_rx + else self.show_port_tx_offload_configuration(port_id) + ) + # Cast to the generic type for mypy + port_capabilities = cast(OffloadCapability, offload_config.port) + return offload in port_capabilities + def flow_create(self, cmd: FlowRule, verify: bool = True) -> None: """Creates a flow rule in the testpmd session. From patchwork Tue Sep 3 19:46:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Spewock X-Patchwork-Id: 143582 X-Patchwork-Delegate: paul.szczepanek@arm.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 516D5458F4; Tue, 3 Sep 2024 21:47:49 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 281224113D; Tue, 3 Sep 2024 21:47:33 +0200 (CEST) Received: from mail-io1-f97.google.com (mail-io1-f97.google.com [209.85.166.97]) by mails.dpdk.org (Postfix) with ESMTP id DF68041132 for ; Tue, 3 Sep 2024 21:47:30 +0200 (CEST) Received: by mail-io1-f97.google.com with SMTP id ca18e2360f4ac-81f9339e534so220079739f.3 for ; Tue, 03 Sep 2024 12:47:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1725392850; x=1725997650; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cpcUKUUE1rz9YMiIYObSry7MZnRGRS438l/vjfBcWug=; b=DIT/XfbgIthn5234AJO04j63y4HvpKw8zHhII2A5Onl7q4kRue2KpeK2mYww6HLVHo 43dZuCYrZOgOhD+9TVPFNMfph0yq7Fr2Xm0a0afDgjDUsW5EJCVCzS4Zu6vnHIoa9dX+ +XGoaySGAlvJBic/Dkzi7/hO5W0wcRi6ciDK8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725392850; x=1725997650; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cpcUKUUE1rz9YMiIYObSry7MZnRGRS438l/vjfBcWug=; b=Chk7Ybq0tH52nYUfO+mFspk6kIcIBo3QUh5Dgm9Y0WEJxVOYGxXT0qqYGUbSK5IOmH YUsANpYxQQVheSs1+5paPtLMLIcJE863z9cRqQo/yMySVQ/62hqU52m0YkaZpKTQAYRa Es+Agb7keyKXfSzF+B3tzdVCf6rDK0EPfepjGLbzzwBmFJteMJRF5DU5Z4Fg2CdVn3QX MoJB9RGmHuNPCrnnHPgM0ETfXN/+i+FbZo8yy3ZiTLk6WPoXnzGz6CQsrjs4XbniAGGE h9Ws3pbT0gOm34ZadtmfchYQsgIs0NIJQF5552Wy+L/K+a+UzRsDFr6771rsTiAhCYdW ojww== X-Gm-Message-State: AOJu0Ywb4Xd0cpkf/Aeka4Or8oDT2B/J+2f57oJnPYzdOKBNE53OvvDO +x/cuUsD1n2JFnSdYXMKGS6pXP15/N8oXRj9jbh74zvtny590w9aFDMWsyBKIcXHt6Vo+H4X93y x0ngdNXIeF/CjexiiqY6owH9Ob2gFgpsgQFMztQYK/LZfI3BF X-Google-Smtp-Source: AGHT+IF3lECjU98ieqwnO4ox8hCb/l8mipJlRYDQXvYyqTjgm/WuTyqHT0RELbs4p1BuihXl7nCpL6EFa5Dg X-Received: by 2002:a05:6e02:1a01:b0:39f:36f3:1959 with SMTP id e9e14a558f8ab-39f377d827emr214969675ab.3.1725392850114; Tue, 03 Sep 2024 12:47:30 -0700 (PDT) Received: from postal.iol.unh.edu (postal.iol.unh.edu. [2606:4100:3880:1234::84]) by smtp-relay.gmail.com with ESMTPS id 8926c6da1cb9f-4ced2dcc547sm432522173.11.2024.09.03.12.47.29 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Sep 2024 12:47:30 -0700 (PDT) X-Relaying-Domain: iol.unh.edu Received: from iol.unh.edu (unknown [IPv6:2606:4100:3880:1257::1083]) by postal.iol.unh.edu (Postfix) with ESMTP id 6D039605C380; Tue, 3 Sep 2024 15:47:27 -0400 (EDT) From: jspewock@iol.unh.edu To: yoan.picchi@foss.arm.com, npratte@iol.unh.edu, juraj.linkes@pantheon.tech, probb@iol.unh.edu, thomas@monjalon.net, paul.szczepanek@arm.com, wathsala.vithanage@arm.com, alex.chapman@arm.com, Luca.Vizzarro@arm.com, Honnappa.Nagarahalli@arm.com Cc: dev@dpdk.org, Jeremy Spewock Subject: [PATCH v2 5/5] dts: add test suite for RX and TX offloads Date: Tue, 3 Sep 2024 15:46:28 -0400 Message-ID: <20240903194642.24458-6-jspewock@iol.unh.edu> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240903194642.24458-1-jspewock@iol.unh.edu> References: <20240831000058.23009-1-jspewock@iol.unh.edu> <20240903194642.24458-1-jspewock@iol.unh.edu> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Jeremy Spewock This patch adds a test sutie that ports over and expands upon functionality provided in the RxTx test sutie in Old DTS. This test suite provides convenience methods and decorators in an attempt to reduce code duplication when developers are tasked with testing the same offloaded functionality through 3 different mediums (passed on the command-line, configured on a port at runtime, and configured on queues at runtime). Signed-off-by: Jeremy Spewock --- dts/framework/config/conf_yaml_schema.json | 3 +- dts/tests/TestSuite_rxtx_offload.py | 627 +++++++++++++++++++++ 2 files changed, 629 insertions(+), 1 deletion(-) create mode 100644 dts/tests/TestSuite_rxtx_offload.py diff --git a/dts/framework/config/conf_yaml_schema.json b/dts/framework/config/conf_yaml_schema.json index f02a310bb5..c1243ea5d8 100644 --- a/dts/framework/config/conf_yaml_schema.json +++ b/dts/framework/config/conf_yaml_schema.json @@ -187,7 +187,8 @@ "enum": [ "hello_world", "os_udp", - "pmd_buffer_scatter" + "pmd_buffer_scatter", + "rxtx_offload" ] }, "test_target": { diff --git a/dts/tests/TestSuite_rxtx_offload.py b/dts/tests/TestSuite_rxtx_offload.py new file mode 100644 index 0000000000..d994b44fc1 --- /dev/null +++ b/dts/tests/TestSuite_rxtx_offload.py @@ -0,0 +1,627 @@ +"""Rx/Tx offload configuration suite. + +The goal of this suite is to test the support for three different methods of offloading different +capabilities using testpmd: On a queue, on a port, and on the command-line. Support for configuring +the capability through different means is testing alongside verifying the functionality of the +capability when offloaded. Each of the three methods of setting the capability should be tested +using the same criteria to monitor for differences between the methods. + +Testing consists of enabling the capability if it wasn't passed in through the command-line, +verifying that the capability performs it's expected task, then, in the general case, disabling the +capability and verifying that the same result is not achieved in a default state. Some cases do not +check the base-case since their functionality is enabled by default without offloading the +capability (like invalid checksum verification, for example). + +There should be test cases for each of the 3 configuration strategies for every offload that is +tested. Additionally, there are two additional test cases that validates the ability to enable +every offload that a device supports on its port without actually testing the functionality of the +offload for both Rx and Tx. +""" + +import random +from typing import Callable, ClassVar, Protocol, TypeVar + +from scapy.layers.inet import IP, TCP, UDP # type: ignore[import-untyped] +from scapy.layers.l2 import Dot1Q, Ether # type: ignore[import-untyped] +from scapy.packet import Packet, Raw # type: ignore[import-untyped] +from typing_extensions import Unpack + +from framework.exception import InteractiveCommandExecutionError, TestCaseVerifyError +from framework.params.types import TestPmdParamsDict +from framework.remote_session.testpmd_shell import ( + FlowRule, + NicCapability, + OffloadCapability, + OLFlag, + RxOffloadCapability, + SimpleForwardingModes, + TestPmdShell, + TestPmdVerbosePacket, + TxOffloadCapability, +) +from framework.test_suite import TestSuite, func_test +from framework.testbed_model.capability import requires + +T = TypeVar("T") + + +class DecoratedFuncType(Protocol): + """Protocol used to provide a useful typehint for methods that are decorated. + + Methods decorated by :meth:`TestRxtxOffload.setup_testpmd` are able to pass kwargs into the + a :class:`TestPmdShell` upon creation and therefore have many non-obvious arguments. This type + allows static type checkers the ability to unpack and expose all of those non-obvious + arguments. + """ + + def __call__( + self: T, + port_id: int, + no_set: bool = False, + modify_queues: bool = False, + no_invert: bool = False, + **kwargs: Unpack[TestPmdParamsDict], + ) -> None: + """Function stub to create callable type. + + Args: + test: Instance of the test suite class that the methods belong to. + port_id: ID of the port to set the offloads on. + no_set: Whether to enable the offload before testing or not. When :data:`True`, + the method will validate that the offload is already configured rather than + enabling it. This is used in test cases that enable the offload using the + command-line. Defaults to :data:`False`. + modify_queues: Whether to add offloads to individual queues or the entire port. + If :data:`True`, individual queues will be modified, otherwise the whole + port will. Defaults to :data:`False`. + no_invert: If :data:`True` skip testing behavior of testpmd without the offload + enabled. Defaults to :data:`False`. + """ + ... + + +def set_offload( + offload: OffloadCapability, + testpmd: TestPmdShell, + is_rx: bool, + port_id: int, + queues_to_modify: set[int], + on: bool, +) -> None: + """Set offload on a port/queue using testpmd. + + This helper method allows you to reach both the :meth:`TestPmdShell.set_queue_offload` and + :meth:`TestPmdShell.set_port_offload` through a single method, and update the offloads on + multiple queues at once. + + Args: + offload: Offload to configure. + testpmd: Testpmd shell to use for modifying the offload configuration. This shell is + expected to be running before being passed into this method. + is_rx: If :data:`True` the offload will be configured on an Rx port/queue, otherwise it + will be configured on a Tx port/queue. + port_id: ID of the port to make configuration changes on. + queues_to_modify: IDs of queues to make configuration changes on. If this set is empty then + changes will only be made to the port configuration. + on: If :data:`True`, then enable the offload, otherwise disable it. + """ + if len(queues_to_modify) > 0: + for queue_id in queues_to_modify: + testpmd.set_queue_offload(port_id, queue_id, is_rx, offload, on, verify=True) + else: + testpmd.set_port_offload(port_id, is_rx, offload, on, verify=True) + + +class TestRxtxOffload(TestSuite): + """Rx/Tx offload testing suite. + + There are three ways to configure offloads in testpmd: Through the command line, at runtime on + a port, or at runtime on individual queues. Each of these configuration methods should be + tested for each of the offloads that are tested in this suite. Methods for testing each of the + offloads functionalities should be designed to be decorated by :func:`setup_testpmd`, meaning + their first parameter must be a :class:`TestPmdShell` (which will be running once the method + receives it) and the second parameter must be a bool signifying whether testing is to be done + on an entire port, or individual queues (:data:`True` for testing on a port, otherwise testing + on a queue). This decorator allows for testpmd to be configured with the proper offloads before + being passed to the method for testing. + """ + + #: + rx_port_for_testing: ClassVar[int] = 0 + #: + tx_port_for_testing: ClassVar[int] = 1 + #: Specify the number of queues to use for test cases the set offloads on queues. This should + #: generally be an odd integer since the test cases will apply offloads to the majority of + #: queues. + number_of_queues: ClassVar[int] = 5 + #: Common testpmd parameters for all tests to use. + common_testpmd_params: ClassVar[dict] = { + "forward_mode": SimpleForwardingModes.mac, + "rx_queues": number_of_queues, + "tx_queues": number_of_queues, + } + #: + relevant_checksum_errors: ClassVar[OLFlag] = ( + OLFlag.RTE_MBUF_F_RX_IP_CKSUM_BAD + | OLFlag.RTE_MBUF_F_RX_L4_CKSUM_BAD + | OLFlag.RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD + ) + + @staticmethod + def setup_testpmd( + offloads: OffloadCapability, is_rx: bool + ) -> Callable[[Callable[["TestRxtxOffload", TestPmdShell, bool], bool]], DecoratedFuncType]: + """Decorator function that initializes testpmd before running a test. + + All offloads in `offloads` are either enabled if they weren't passed in on the + command-line, or verified to be enabled on the port before running the decorated method. + The decorated method must return a boolean that represents whether or not the expected + behavior took place while the offload was enabled which will be used for verification that + the test functioned as expected. By default, this decorator will also disable all of the + offloads in `offloads` and verify that the decorated method instead returns :data:`False` + where it was expected to return :data:`True` with them enabled. This functionality can be + overridden, however, for cases where the opposite functionality cannot be easily tested + (like invalid checksums, for example). + + The decorated method additionally can be used for both setting offloads across the entire + port or on individual queues using the `modify_queues` parameter. If individual queues are + being modified then the majority of queues ((x / 2) + 1 where x is the number of queues) + will have the offload enabled rather than all of them. All decorated functions must be a + method of :class:`TestRxtxOffload` and take a testpmd shell for testing along with a + boolean that signifies whether it is a port being tested or individual queues. + + Args: + offloads: Offloads to set in testpmd prior to running decorated function. + is_rx: Whether to set Rx or Tx offloads when testing. + + Returns: + Decorator function that enables all offloads, runs the decorated method, then optionally + disables offloads and runs the test method again. + """ + + def wrap( + func: Callable[["TestRxtxOffload", TestPmdShell, bool], bool] + ) -> DecoratedFuncType: + def wrapper( + test: "TestRxtxOffload", + port_id: int, + no_set: bool = False, + modify_queues: bool = False, + no_invert: bool = False, + **kwargs: Unpack[TestPmdParamsDict], + ) -> None: + """Function that wraps the decorated method. + + Refer to :class:`DecoratedFuncType` for information about parameters of this + method. + """ + queues_to_modify: set[int] = set() + if modify_queues: + while len(queues_to_modify) < int(test.number_of_queues / 2 + 1): + queues_to_modify.add(random.randint(0, test.number_of_queues - 1)) + with TestPmdShell(test.sut_node, **test.common_testpmd_params, **kwargs) as testpmd: + # If no_set then it should have been passed on the command-line and already + # be configured, else we need to set them ourselves. + if no_set: + testpmd.is_port_offload_configured(port_id, is_rx, offloads) + else: + set_offload(offloads, testpmd, is_rx, port_id, queues_to_modify, on=True) + + test.verify( + func(test, testpmd, not modify_queues), + f"Offloaded capabilities ({offloads}) failed.", + ) + + set_offload(offloads, testpmd, is_rx, port_id, queues_to_modify, on=False) + if not no_invert: + test.verify( + not func(test, testpmd, not modify_queues), + f"After disabling capabilities ({offloads}) the " + "result was the same.", + ) + + # This type ignore is required to ignore the mismatch in types between the protocol + # and the wrapper function. Mypy complains that these two are not the same type since + # the type produced by the protocol does not include a parameter for "TestRxtxOffload". + # However, if you add this parameter, it makes it so that you have to explicitly pass + # the value of `self` into the method when you call it, so you cannot simply call + # methods with the standard syntax of "self." without mypy complaining. + return wrapper # type: ignore[return-value] + + return wrap + + """ ========== Verify methods ========== + All verify methods must match the type + Callable[[list[Packet], list[TestPmdVerbosePacket]], bool] where their + first parameter is a list of packets that were forwarded back to the TG in the test and the + second parameter is the verbose information gathered by testpmd while packets were being + forwarded. These methods are meant to return a boolean that represents whether or not a + packet that matches their expected behavior can be found among any of their parameters in + order to be used by :meth:`send_packets_and_verify` for testing functionality. + """ + + @staticmethod + def _packet_is_relevant(pakt: Packet) -> bool: + """Helper method to test whether or not a packet was sent by a method in this test suite. + + All packets in this test suite are sent with a payload of 20 "X" characters, so this method + checks to see if `pakt` has a matching payload. + + Args: + pakt: The packet to validate. + + Returns: + :data:`True` if the packet has a valid payload, :data:`False` otherwise. + """ + return hasattr(pakt, "load") and pakt.load == bytes("X" * 20, "utf-8") + + @staticmethod + def verify_insertion(packets: list[Packet], *_) -> bool: + """Method to verify VLAN headers were inserted into sent packets. + + Checks to make sure that there is at least one packet in `packets` that is relevant to the + test suite with a VLAN header in it. This method consumes all arguments after `packets` to + conform to the type + Callable[[list[Packet], list[TestPmdVerbosePacket]], bool] even though + it does not need the verbose packet information. + + Args: + packets: Packets to scan for a valid result. + + Returns: + :data:`True` if there is at least one packet in `packets` that is relevant to the test + suite with a VLAN header in it, :data:`False` otherwise. + """ + return any(TestRxtxOffload._packet_is_relevant(pakt) and Dot1Q in pakt for pakt in packets) + + @staticmethod + def verify_stripping(packets: list[Packet], *_) -> bool: + """Method to verify VLAN headers were stripped from sent packets. + + Checks to make sure there is at least one packet in `packets` that is relevant to the suite + which does not contain a VLAN header. This method consumes all arguments after `packets` to + conform to the type + Callable[[list[Packet], list[TestPmdVerbosePacket]], bool] even though + it does not need the verbose packets. + + Args: + packets: The list of packets to scan for a valid result. + + Returns: + :data:`True` if there is at least one packet that is relevant to the suite in `packets` + without a VLAN header, :data:`False` otherwise. + """ + return any( + TestRxtxOffload._packet_is_relevant(pakt) and Dot1Q not in pakt for pakt in packets + ) + + @classmethod + def verify_chksum( + cls, expected_errors: OLFlag | None = None + ) -> Callable[[list[Packet], list[TestPmdVerbosePacket]], bool]: + """Verify that the expected checksum errors appear in the forwarding statistics. + + Provides a closure for the wrapped function that stores the errors to expect in the + output. The wrapped function then accepts a list of packets received from forwarding as + well as forwarding statistics to validate with. The list of received packets are unused. + + Args: + expected_error: Errors to search for in the forwarding statistics. If flag is + :data:`None`, verify that none of the :attr:`relevant_checksum_errors` appear in + the forwarding status. Defaults to :data:`None`. + + Returns: + A function that searches for the expected errors in the forwarding statistics and + returns :data:`True` if they are all present or if `expected_errors` is :data:`None` + and there are no errors present. The function will return :data:`False` otherwise. + """ + + def wrap(_, fwd_stats: list[TestPmdVerbosePacket]) -> bool: + """Method that fits the expected type of verify methods.""" + if expected_errors is None: + return all( + cls.relevant_checksum_errors & pakt.ol_flags == OLFlag(0) for pakt in fwd_stats + ) + else: + return any(expected_errors in pakt.ol_flags for pakt in fwd_stats) + + return wrap + + """ ========== End verify methods ========= """ + + def send_packets_and_verify( + self, + testpmd: TestPmdShell, + packets: list[Packet], + verify_meth: Callable[[list[Packet], list[TestPmdVerbosePacket]], bool], + is_port: bool, + ) -> bool: + """Send packets and verify the result using `verify_meth`. + + If testing is being done on queues, this method makes flow rules that make it so that + anything that has the source address 192.168.1.X will be handled by queue X in testpmd. + Then, before sending packets in all cases, this method will adjust the source IP addresses + of the packets in `packets` to ensure they are all different and processed by different, + start testpmd, send all of the packets in `packets`, and captures the resulting received + traffic and forwarding stats. The received traffic and forwarding stats are then passed + into `verify_meth` to test if the expected result took place. + + In the case of testing the results of queues, it is expected that the majority of queues + (but not all) have the offload enabled and, therefore, only the majority of packets in + `packets` need to return :data:`True` from `verify_meth` to get a positive + result. + + Args: + testpmd: Testpmd shell that is handling the packet forwarding. This shell is expected + to already be started before being passed into this method. + packets: List of packets to send to the SUT during testing. + verify_meth: Method used to verify that the packet matches the expected results. + is_port: Flag to differentiate testing results from an offload set on a port from an + offload set on a queue. + + Returns: + :data:`True` if `verify_meth` returned :data:`True` for every packet in `packets` if + testing offloads on a port, or the majority of packets if testing offloads on queues. + :data:`False` otherwise. + """ + majority = int(self.number_of_queues / 2 + 1) + dst_ip_addr = "192.168.1.{}" + verify_results: list[bool] = [] + base_pattern = f"eth / {'vlan /' if packets[0].haslayer(Dot1Q) else ''} " "ipv4 dst is {}" + base_action = "queue index {}" + if not is_port: + rule = FlowRule(self.rx_port_for_testing, True, "", "") + for queue_id in range(self.number_of_queues): + rule.pattern = base_pattern.format(dst_ip_addr.format(queue_id)) + rule.actions = base_action.format(queue_id) + testpmd.flow_create(rule) + + for ind, pakt in enumerate(packets): + testpmd.start() + pakt.getlayer(IP).dst = dst_ip_addr.format(ind % self.number_of_queues) + recv = self.send_packet_and_capture(pakt) + stats = TestPmdShell.extract_verbose_output(testpmd.stop()) + verify_results.append(verify_meth(recv, stats)) + return all(verify_results) if is_port else verify_results.count(True) == majority + + """ ========== Functionality testing methods ========== + Functionality testing methods are the methods that test, assuming the offloads are already + configured in the environment, Rx/Tx offloads perform their expected behavior. These + methods must conform to the type Callable[["TestRxtxOffload", TestPmdShell, bool], bool] + so that they can be decorated by :func:`setup_testpmd`. + """ + + @setup_testpmd(TxOffloadCapability.VLAN_INSERT, False) + def tx_vlan_insertion_test(self, testpmd: TestPmdShell, is_port: bool) -> bool: + """Testing method for VLAN insertion on a Tx port/queue. + + Testing is done by sending one packet without a VLAN header for as many queues as there are + configured and verifying with :meth:`verify_insertion`. + + Args: + testpmd: Testpmd shell to use for testing. It is expected that this shell is already + running. + is_port: If :data:`True`, do testing on a port, otherwise do testing on individual + queues. + + Returns: + :data:`True` if the received traffic contained a VLAN header when expected with the + offload enabled. + """ + return self.send_packets_and_verify( + testpmd, + [Ether() / IP() / Raw("X" * 20)] * self.number_of_queues, + TestRxtxOffload.verify_insertion, + is_port, + ) + + @setup_testpmd(RxOffloadCapability.VLAN_STRIP, True) + def rx_vlan_stripping(self, testpmd: TestPmdShell, is_port: bool) -> bool: + """Testing method for VLAN stripping on an Rx port/queue. + + Testing is done by sending one packet with a VLAN header for every configured queue and + verifying using :func:`verify_stripping` that the received packets had their VLAN header + stripped. + + Args: + testpmd: Testpmd shell to use for testing. This shell is expected to already be + running when passed into this method. + is_port: If :data:`True`, do testing on a port, otherwise do testing on individual + queues. + + Returns: + :data:`True` if the expected amount of received packets had their VLAN headers stripped + when the offload is enabled, :data:`False` otherwise. + """ + return self.send_packets_and_verify( + testpmd, + [Ether() / Dot1Q() / IP() / Raw("X" * 20)] * self.number_of_queues, + TestRxtxOffload.verify_stripping, + is_port, + ) + + @setup_testpmd( + RxOffloadCapability.UDP_CKSUM + | RxOffloadCapability.TCP_CKSUM + | RxOffloadCapability.IPV4_CKSUM, + True, + ) + def rx_cksum_test(self, testpmd: TestPmdShell, is_port: bool) -> bool: + """Test for verifying invalid checksum reporting. + + Testing is done in multiple stages for checksum test cases. Testpmd must first be set to + Rx-only verbose mode to capture the checksum errors reported by testpmd when receiving + packets with a bad checksum. There are then 4 main cases to test: + + * Valid packets do not display any checksum errors. + * Packets with a bad IP checksum and a bad layer 4 checksum report both errors properly. + * Packets with only a bad layer 4 checksum report only that error properly. + * Packets with only a bad IP checksum report only that error properly. + + All of these cases must pass for this method to return :data:`True`. + + Args: + testpmd: Testpmd shell to use for testing. It is expected that this shell is already + running when it is passed into this method. + is_port: If :data:`True`, do testing on a port, otherwise do testing on individual + queues. + + Returns: + :data:`True` if all 4 cases pass, :data:`False` otherwise. + """ + testpmd.set_verbose(1) + results = [ + self.send_packets_and_verify( + testpmd, [Ether() / IP() / TCP() / ("X" * 20)], self.verify_chksum(), is_port + ), + self.send_packets_and_verify( + testpmd, + [Ether() / IP(chksum=0x0) / TCP(chksum=0xF) / ("X" * 20)], + TestRxtxOffload.verify_chksum( + OLFlag.RTE_MBUF_F_RX_IP_CKSUM_BAD | OLFlag.RTE_MBUF_F_RX_L4_CKSUM_BAD + ), + is_port, + ), + self.send_packets_and_verify( + testpmd, + [Ether() / IP() / UDP(chksum=0xF) / ("X" * 20)], + TestRxtxOffload.verify_chksum(OLFlag.RTE_MBUF_F_RX_L4_CKSUM_BAD), + is_port, + ), + self.send_packets_and_verify( + testpmd, + [Ether() / IP(chksum=0x0) / UDP() / ("X" * 20)], + TestRxtxOffload.verify_chksum(OLFlag.RTE_MBUF_F_RX_IP_CKSUM_BAD), + is_port, + ), + ] + return all(results) + + """ ========== End functionality testing methods ========== """ + + @requires(NicCapability.PORT_TX_OFFLOAD_VLAN_INSERT) + @func_test + def test_tx_port_vlan_insertion(self) -> None: + """Run :meth:`tx_vlan_insertion_test` with common testpmd parameters.""" + self.tx_vlan_insertion_test(self.tx_port_for_testing) + + @requires(NicCapability.PORT_TX_OFFLOAD_VLAN_INSERT) + @func_test + def test_tx_cmdline_vlan_insertion(self) -> None: + """Run :meth:`tx_vlan_insertion_test` with insertion offload passed on the command-line. + + This requires specifying that the offload should not be set at runtime when calling the + method. + """ + self.tx_vlan_insertion_test(self.tx_port_for_testing, no_set=True, tx_offloads=0x0001) + + @requires(NicCapability.QUEUE_TX_OFFLOAD_VLAN_INSERT) + @func_test + def test_tx_queue_vlan_insertion(self) -> None: + """Run :meth:`tx_vlan_insertion_test` specifying queues should be modified.""" + self.tx_vlan_insertion_test(self.tx_port_for_testing, modify_queues=True) + + @requires(NicCapability.PORT_RX_OFFLOAD_VLAN_STRIP) + @func_test + def test_rx_port_vlan_strip(self) -> None: + """Run :meth:`rx_vlan_stripping` with common testpmd parameters.""" + self.rx_vlan_stripping(self.rx_port_for_testing) + + @requires(NicCapability.PORT_RX_OFFLOAD_VLAN_STRIP) + @func_test + def test_rx_cmdline_vlan_strip(self) -> None: + """Run :meth:`rx_vlan_stripping` with stripping offload passed on the command-line. + + This requires specifying that the offload should not be set at runtime when calling the + method. + """ + self.rx_vlan_stripping(self.rx_port_for_testing, no_set=True, enable_hw_vlan_strip=True) + + @requires(NicCapability.QUEUE_RX_OFFLOAD_VLAN_STRIP) + @func_test + def test_rx_queue_vlan_strip(self) -> None: + """Run :meth:`rx_vlan_stripping` specifying queues should be modified.""" + self.rx_vlan_stripping(self.rx_port_for_testing, modify_queues=True) + + @requires( + NicCapability.PORT_RX_OFFLOAD_UDP_CKSUM, + NicCapability.PORT_RX_OFFLOAD_TCP_CKSUM, + NicCapability.PORT_RX_OFFLOAD_IPV4_CKSUM, + ) + @func_test + def test_rx_port_chksum(self) -> None: + """Run :meth:`rx_cksum_test` with common testpmd parameters. + + Since checksum errors will be thrown even when the offload is disabled, specify not to + invert testing. + """ + self.rx_cksum_test(self.rx_port_for_testing, no_invert=True) + + @requires( + NicCapability.PORT_RX_OFFLOAD_UDP_CKSUM, + NicCapability.PORT_RX_OFFLOAD_TCP_CKSUM, + NicCapability.PORT_RX_OFFLOAD_IPV4_CKSUM, + ) + @func_test + def test_rx_cmdline_chksum(self) -> None: + """Run :meth:`rx_cksum_test` with checksum offloads enabled through the command-line. + + Since checksum errors will be thrown even when the offload is disabled, specify not to + invert testing. Additionally, specify that the offload should not be set at runtime. + """ + self.rx_cksum_test( + self.rx_port_for_testing, + no_set=True, + no_invert=True, + enable_rx_cksum=True, + ) + + @requires( + NicCapability.QUEUE_RX_OFFLOAD_UDP_CKSUM, + NicCapability.QUEUE_RX_OFFLOAD_TCP_CKSUM, + NicCapability.QUEUE_RX_OFFLOAD_IPV4_CKSUM, + ) + @func_test + def test_rx_queue_chksum(self) -> None: + """Run :meth:`rx_cksum_test` specifying testing should be run on queues. + + Since checksum errors will be thrown even when the offload is disabled, specify not to + invert testing. + """ + self.rx_cksum_test( + self.rx_port_for_testing, + modify_queues=True, + no_invert=True, + ) + + @func_test + def test_rx_all_port_offloads(self) -> None: + """Verify that testpmd is able to set all Rx offloads the port is capable of at runtime.""" + with TestPmdShell(self.sut_node) as testpmd: + supported_capabilities = testpmd.show_port_rx_offload_capabilities( + self.rx_port_for_testing + ).per_port + try: + testpmd.set_port_offload( + self.rx_port_for_testing, True, supported_capabilities, True, verify=True + ) + except InteractiveCommandExecutionError as e: + raise TestCaseVerifyError( + f"Failed to set all Rx offloads on port {self.rx_port_for_testing}" + ) from e + + @func_test + def test_tx_all_port_offloads(self) -> None: + """Verify that testpmd is able to set all Tx offloads the port is capable of at runtime.""" + with TestPmdShell(self.sut_node) as testpmd: + supported_capabilities = testpmd.show_port_tx_offload_capabilities( + self.tx_port_for_testing + ).per_port + try: + testpmd.set_port_offload( + self.tx_port_for_testing, False, supported_capabilities, True, verify=True + ) + except InteractiveCommandExecutionError as e: + raise TestCaseVerifyError( + f"Failed to set all Tx offloads on port {self.tx_port_for_testing}" + ) from e