feat(trex): Multilink 16/39616/8
authorpmikus <peter.mikus@protonmail.ch>
Thu, 5 Oct 2023 12:27:08 +0000 (12:27 +0000)
committerPeter Mikus <peter.mikus@protonmail.ch>
Mon, 9 Oct 2023 12:09:10 +0000 (12:09 +0000)
Signed-off-by: Peter Mikus <peter.mikus@protonmail.ch>
Change-Id: I36c5d175a34555ad9ce88d69a824f366b54dbc81

resources/libraries/python/Constants.py
resources/libraries/python/CpuUtils.py
resources/libraries/python/TRexConfigGenerator.py
resources/libraries/python/TrafficGenerator.py

index 93f0b22..a25cd6a 100644 (file)
@@ -188,37 +188,46 @@ class Constants:
     # Docker container arm SUT image
     DOCKER_SUT_IMAGE_UBUNTU_ARM = u"csit_sut-ubuntu2204:local"
 
-    # TRex install directory
+    # TRex install directory.
     TREX_INSTALL_DIR = u"/opt/trex-core-3.03"
 
-    # TRex pcap files directory
+    # TRex pcap files directory.
     TREX_PCAP_DIR = f"{TREX_INSTALL_DIR}/scripts/avl"
 
     # TRex limit memory.
-    TREX_LIMIT_MEMORY = get_int_from_env(u"TREX_LIMIT_MEMORY", 8192)
+    TREX_LIMIT_MEMORY = get_int_from_env("TREX_LIMIT_MEMORY", 8192)
 
-    # TRex number of cores
-    TREX_CORE_COUNT = get_int_from_env(u"TREX_CORE_COUNT", 16)
+    # TRex limit memory in case multiple dual interfaces configurations.
+    TREX_LIMIT_MEMORY_MULTI = get_int_from_env("TREX_LIMIT_MEMORY_MULTI", 16384)
 
-    # TRex set number of RX/TX descriptors
-    # Set to 0 to use default values
+    # TRex number of cores.
+    TREX_CORE_COUNT = get_int_from_env("TREX_CORE_COUNT", 16)
+
+    # TRex number of cores in case multiple dual interface configurations.
+    TREX_CORE_COUNT_MULTI = get_int_from_env("TREX_CORE_COUNT_MULTI", 8)
+
+    # TRex set number of RX/TX descriptors.
+    # Set to 0 to use default values.
     TREX_TX_DESCRIPTORS_COUNT = get_int_from_env(
-        u"TREX_TX_DESCRIPTORS_COUNT", 0
+        "TREX_TX_DESCRIPTORS_COUNT", 0
     )
+
     TREX_RX_DESCRIPTORS_COUNT = get_int_from_env(
-        u"TREX_RX_DESCRIPTORS_COUNT", 0
+        "TREX_RX_DESCRIPTORS_COUNT", 0
     )
 
-    # Trex force start regardless ports state
-    TREX_SEND_FORCE = get_pessimistic_bool_from_env(u"TREX_SEND_FORCE")
+    # Trex force start regardless ports state.
+    TREX_SEND_FORCE = get_pessimistic_bool_from_env("TREX_SEND_FORCE")
 
-    # TRex extra commandline arguments
+    # TRex extra commandline arguments.
     TREX_EXTRA_CMDLINE = get_str_from_env(
-        u"TREX_EXTRA_CMDLINE", u"--mbuf-factor 32")
+        "TREX_EXTRA_CMDLINE", "--mbuf-factor 32"
+    )
 
-    # TRex port driver default vfio-pci or set to igb_uio
+    # TRex port driver default vfio-pci or set to igb_uio.
     TREX_PORT_DRIVER = get_str_from_env(
-        u"TREX_PORT_DRIVER", u"vfio-pci")
+        "TREX_PORT_DRIVER", "vfio-pci"
+    )
 
     # Graph node variant value
     GRAPH_NODE_VARIANT = get_str_from_env(u"GRAPH_NODE_VARIANT", u"")
index 5f43e21..8871a5b 100644 (file)
@@ -388,7 +388,7 @@ class CpuUtils:
 
     @staticmethod
     def get_affinity_trex(
-            node, if_key, tg_mtc=1, tg_dtc=1, tg_ltc=1):
+            node, if_key, tg_mtc=1, tg_dtc=1, tg_ltc=1, tg_dtc_offset=0):
         """Get affinity for T-Rex. Result will be used to pin T-Rex threads.
 
         :param node: TG node.
@@ -396,11 +396,13 @@ class CpuUtils:
         :param tg_mtc: TG main thread count.
         :param tg_dtc: TG dataplane thread count.
         :param tg_ltc: TG latency thread count.
+        :param tg_dtc_offset: TG dataplane thread offset.
         :type node: dict
         :type if_key: str
         :type tg_mtc: int
         :type tg_dtc: int
         :type tg_ltc: int
+        :type tg_dtc_offset: int
         :returns: List of CPUs allocated to T-Rex including numa node.
         :rtype: int, int, int, list
         """
@@ -412,12 +414,11 @@ class CpuUtils:
             smt_used=False)
 
         threads = CpuUtils.cpu_slice_of_list_per_node(
-            node, cpu_node, skip_cnt=tg_mtc, cpu_cnt=tg_dtc,
-            smt_used=False)
+            node, cpu_node, skip_cnt=tg_mtc + tg_ltc + tg_dtc_offset,
+            cpu_cnt=tg_dtc, smt_used=False)
 
         latency_thread_id = CpuUtils.cpu_slice_of_list_per_node(
-            node, cpu_node, skip_cnt=tg_mtc + tg_dtc, cpu_cnt=tg_ltc,
-            smt_used=False)
+            node, cpu_node, skip_cnt=tg_mtc, cpu_cnt=tg_ltc, smt_used=False)
 
         return master_thread_id[0], latency_thread_id[0], cpu_node, threads
 
index e5ac196..c73e249 100644 (file)
@@ -225,12 +225,12 @@ class TrexConfigGenerator:
         exec_cmd_no_error(self._node, command, message=message)
 
 
-class TrexInitConfig:
-    """TRex Initial Configuration.
+class TrexConfig:
+    """TRex Configuration Class.
     """
     @staticmethod
-    def init_trex_startup_configuration(node, tg_topology):
-        """Apply initial TRex startup configuration.
+    def add_startup_configuration(node, tg_topology):
+        """Apply TRex startup configuration.
 
         :param node: TRex node in the topology.
         :param tg_topology: Ordered TRex links.
@@ -243,16 +243,24 @@ class TrexInitConfig:
         master_thread_id = None
         latency_thread_id = None
         cores = None
-        limit_memory = f"{Constants.TREX_LIMIT_MEMORY}"
         sockets = list()
 
-        for link in tg_topology:
+        for idx, link in enumerate(tg_topology):
             pci_addresses.append(
                 Topology().get_interface_pci_addr(node, link["interface"])
             )
+            if len(tg_topology) > 2:
+                # Multiple dual_ifs must not share the cores.
+                tg_dtc = Constants.TREX_CORE_COUNT_MULTI
+                tg_dtc_offset = Constants.TREX_CORE_COUNT_MULTI * (idx // 2)
+            else:
+                # Single dual_if can share cores.
+                tg_dtc = Constants.TREX_CORE_COUNT
+                tg_dtc_offset = 0
             master_thread_id, latency_thread_id, socket, threads = \
                 CpuUtils.get_affinity_trex(
-                    node, link["interface"], tg_dtc=Constants.TREX_CORE_COUNT
+                    node, link["interface"], tg_dtc=tg_dtc, 
+                    tg_dtc_offset=tg_dtc_offset
                 )
             dual_if.append(dict(socket=socket, threads=threads))
             cores = len(threads)
@@ -265,10 +273,16 @@ class TrexInitConfig:
                 )
             )
             sockets.append(socket)
-        if 0 in sockets and 1 in sockets:
+
+        limit_memory = f"{Constants.TREX_LIMIT_MEMORY}"
+        if len(tg_topology) <= 2 and 0 in sockets and 1 in sockets:
             limit_memory = (
                 f"{Constants.TREX_LIMIT_MEMORY},{Constants.TREX_LIMIT_MEMORY}"
             )
+        if len(tg_topology) > 2:
+            limit_memory = (
+                f"{Constants.TREX_LIMIT_MEMORY_MULTI}"
+            )
 
         trex_config = TrexConfigGenerator()
         trex_config.set_node(node)
index f759f52..6f4483b 100644 (file)
@@ -30,7 +30,7 @@ from .ssh import exec_cmd_no_error, exec_cmd
 from .topology import NodeType
 from .topology import NodeSubTypeTG
 from .topology import Topology
-from .TRexConfigGenerator import TrexInitConfig
+from .TRexConfigGenerator import TrexConfig
 from .DUTSetup import DUTSetup as DS
 
 __all__ = [u"TGDropRateSearchImpl", u"TrafficGenerator", u"OptimizedSearch"]
@@ -335,7 +335,7 @@ class TrafficGenerator(AbstractMeasurer):
                     self._ifaces_reordered = True
                     trex_topology.reverse()
 
-            TrexInitConfig.init_trex_startup_configuration(
+            TrexConfig.add_startup_configuration(
                 self._node, trex_topology
             )
             TrafficGenerator.startup_trex(