From e3d806ce064bade2ad168c9df03e3cc2ee396cff Mon Sep 17 00:00:00 2001 From: François-Régis MENGUY Date: Tue, 20 Nov 2018 17:49:09 +0100 Subject: NFVBENCH-121 Add TRex parameters to tune performance and allocate ressources Change-Id: I3dd091575cce19a31e8aff3d56ed3ea7e930fe83 Signed-off-by: fmenguy --- nfvbench/cfg.default.yaml | 34 ++++++++++++++++++++++++++++++++++ nfvbench/chaining.py | 2 +- nfvbench/traffic_client.py | 7 ++++++- nfvbench/traffic_gen/trex.py | 3 ++- nfvbench/traffic_server.py | 34 +++++++++++++++++++++++++++++++++- 5 files changed, 76 insertions(+), 4 deletions(-) diff --git a/nfvbench/cfg.default.yaml b/nfvbench/cfg.default.yaml index c2fa29e..5d12e39 100755 --- a/nfvbench/cfg.default.yaml +++ b/nfvbench/cfg.default.yaml @@ -214,6 +214,13 @@ traffic_generator: # software mode, therefore the performance of TRex will be significantly # lower. ONLY applies to trex-local. # Recommended to leave the default value (false) + # `limit_memory`: Specify the memory reserved for running the TRex traffic generator (in MB). Limit the amount + # of packet memory used. (Passed to dpdk as -m arg) + # ONLY applies to trex-local. + # `zmq_pub_port`: Specify the ZMQ pub port number for the TRex traffic generator instance (default value is 4500). + # ONLY applies to trex-local. + # `zmq_rpc_port`: Specify the ZMQ rpc port for the TRex traffic generator instance (default value is 4501). + # ONLY applies to trex-local. # `interfaces`: Configuration of traffic generator interfaces. # `interfaces.port`: The port of the traffic generator to be used (leave as 0 and 1 resp.) # `interfaces.switch_port`: Leave empty (deprecated) @@ -227,12 +234,33 @@ traffic_generator: # Do not use unless you want to override the speed discovered by the # traffic generator. Expected format: 10Gbps # + # `platform`: Optional. Used to tune the performance and allocate the cores to the right NUMA. + # See https://trex-tgn.cisco.com/trex/doc/trex_manual.html (6.2.3. Platform section configuration) + # for more details + # `platform.master_thread_id`: Hardware thread_id for control thread. (Valid value is mandatory if platform property is set) + # `platform.latency_thread_id`: Hardware thread_id for RX thread. (Valid value is mandatory if platform property is set) + # `platform.dual_if`: Section defines info for interface pairs (according to the order in “interfaces” list). (Valid value is mandatory if platform property is set) + # Each section, starting with “- socket” defines info for different interface pair. (Valid value is mandatory if platform property is set) + # `platform.dual_if.socket`: The NUMA node from which memory will be allocated for use by the interface pair. (Valid value is mandatory if platform property is set) + # `platform.dual_if.threads`: Hardware threads to be used for sending packets for the interface pair. (Valid value is mandatory if platform property is set) + # Threads are pinned to cores, so specifying threads actually determines the hardware cores. + # Example of values: + # platform: + # master_thread_id: 0 + # latency_thread_id: 2 + # dual_if: + # - socket: 0 + # threads: [1] + # generator_profile: - name: trex-local tool: TRex ip: 127.0.0.1 cores: 4 software_mode: false + limit_memory: 1024 + zmq_pub_port: 4500 + zmq_rpc_port: 4501 interfaces: - port: 0 pci: @@ -241,6 +269,12 @@ traffic_generator: pci: switch_port: intf_speed: + platform: + master_thread_id: + latency_thread_id: + dual_if: + - socket: + threads: # Simpler override for trex core count and mbuf multilier factor # if empty defaults to the one specified in generator_profile.cores diff --git a/nfvbench/chaining.py b/nfvbench/chaining.py index 1a977da..22f000b 100644 --- a/nfvbench/chaining.py +++ b/nfvbench/chaining.py @@ -890,7 +890,7 @@ class ChainManager(object): # Make sure all instances are active before proceeding self._ensure_instances_active() # network API call do not show VLANS ID if not admin read from config - if not self.is_admin: + if not self.is_admin and config.vlan_tagging: self._get_config_vlans() except Exception: self.delete() diff --git a/nfvbench/traffic_client.py b/nfvbench/traffic_client.py index dbb8206..13ebfb7 100755 --- a/nfvbench/traffic_client.py +++ b/nfvbench/traffic_client.py @@ -340,11 +340,16 @@ class GeneratorConfig(object): else: # interface speed is discovered/provided by the traffic generator self.intf_speed = 0 + self.name = gen_config.name + self.zmq_pub_port = gen_config.get('zmq_pub_port', 4500) + self.zmq_rpc_port = gen_config.get('zmq_rpc_port', 4501) + self.limit_memory = gen_config.get('limit_memory', 1024) self.software_mode = gen_config.get('software_mode', False) self.interfaces = gen_config.interfaces if self.interfaces[0].port != 0 or self.interfaces[1].port != 1: raise TrafficClientException('Invalid port order/id in generator_profile.interfaces') - + if hasattr(gen_config, 'platform'): + self.platform = gen_config.platform self.service_chain = config.service_chain self.service_chain_count = config.service_chain_count self.flow_count = config.flow_count diff --git a/nfvbench/traffic_gen/trex.py b/nfvbench/traffic_gen/trex.py index 1f460f6..32aa576 100644 --- a/nfvbench/traffic_gen/trex.py +++ b/nfvbench/traffic_gen/trex.py @@ -413,7 +413,8 @@ class TRex(AbstractTrafficGenerator): LOG.info("Connecting to TRex (%s)...", server_ip) # Connect to TRex server - self.client = STLClient(server=server_ip) + self.client = STLClient(server=server_ip, sync_port=self.generator_config.zmq_rpc_port, + async_port=self.generator_config.zmq_pub_port) try: self.__connect(self.client) except (TimeoutError, STLError) as e: diff --git a/nfvbench/traffic_server.py b/nfvbench/traffic_server.py index c3d4d14..df0a3be 100644 --- a/nfvbench/traffic_server.py +++ b/nfvbench/traffic_server.py @@ -63,7 +63,39 @@ class TRexTrafficServer(TrafficServer): result = """# Config generated by NFVbench - port_limit : 2 version : 2 - interfaces : [{ifs}]""".format(ifs=ifs) + zmq_pub_port : {zmq_pub_port} + zmq_rpc_port : {zmq_rpc_port} + prefix : {prefix} + limit_memory : {limit_memory} + interfaces : [{ifs}]""".format(zmq_pub_port=generator_config.zmq_pub_port, + zmq_rpc_port=generator_config.zmq_rpc_port, + prefix=generator_config.name, + limit_memory=generator_config.limit_memory, + ifs=ifs) + if hasattr(generator_config, 'platform'): + if generator_config.platform.master_thread_id \ + and generator_config.platform.latency_thread_id: + platform = """ + platform : + master_thread_id : {master_thread_id} + latency_thread_id : {latency_thread_id} + dual_if:""".format(master_thread_id=generator_config.platform.master_thread_id, + latency_thread_id=generator_config.platform.latency_thread_id) + result += platform + + for core in generator_config.platform.dual_if: + threads = "" + try: + threads = ",".join([repr(thread) for thread in core.threads]) + except TypeError: + LOG.warn("No threads defined for socket %s", core.socket) + core_result = """ + - socket : {socket} + threads : [{threads}]""".format(socket=core.socket, threads=threads) + result += core_result + else: + LOG.info("Generator profile 'platform' sub-properties are set but not filled in \ + config file. TRex will use default values.") yaml.safe_load(result) if os.path.exists(filename): -- cgit 1.2.3-korg