+ @staticmethod
+ def get_affinity_nf(
+ nodes, node, nf_chains=1, nf_nodes=1, nf_chain=1, nf_node=1,
+ vs_dtc=1, nf_dtc=1, nf_mtcr=2, nf_dtcr=1):
+
+ """Get affinity of NF (network function). Result will be used to compute
+ the amount of CPUs and also affinity.
+
+ :param nodes: Physical topology nodes.
+ :param node: SUT node.
+ :param nf_chains: Number of NF chains.
+ :param nf_nodes: Number of NF nodes in chain.
+ :param nf_chain: Chain number indexed from 1.
+ :param nf_node: Node number indexed from 1.
+ :param vs_dtc: Amount of physical cores for vswitch data plane.
+ :param nf_dtc: Amount of physical cores for NF data plane.
+ :param nf_mtcr: NF main thread per core ratio.
+ :param nf_dtcr: NF data plane thread per core ratio.
+ :type nodes: dict
+ :type node: dict
+ :type nf_chains: int
+ :type nf_nodes: int
+ :type nf_chain: int
+ :type nf_node: int
+ :type vs_dtc: int
+ :type nf_dtc: int or float
+ :type nf_mtcr: int
+ :type nf_dtcr: int
+ :returns: List of CPUs allocated to NF.
+ :rtype: list
+ """
+ skip_cnt = Constants.CPU_CNT_SYSTEM + Constants.CPU_CNT_MAIN + vs_dtc
+
+ interface_list = list()
+ interface_list.append(BuiltIn().get_variable_value(f"${{{node}_if1}}"))
+ interface_list.append(BuiltIn().get_variable_value(f"${{{node}_if2}}"))
+
+ cpu_node = Topology.get_interfaces_numa_node(
+ nodes[node], *interface_list)
+
+ return CpuUtils.cpu_slice_of_list_for_nf(
+ node=nodes[node], cpu_node=cpu_node, nf_chains=nf_chains,
+ nf_nodes=nf_nodes, nf_chain=nf_chain, nf_node=nf_node,
+ nf_mtcr=nf_mtcr, nf_dtcr=nf_dtcr, nf_dtc=nf_dtc, skip_cnt=skip_cnt
+ )
+
+ @staticmethod
+ def get_affinity_trex(
+ node, if1_pci, if2_pci, tg_mtc=1, tg_dtc=1, tg_ltc=1):
+ """Get affinity for T-Rex. Result will be used to pin T-Rex threads.
+
+ :param node: TG node.
+ :param if1_pci: TG first interface.
+ :param if2_pci: TG second interface.
+ :param tg_mtc: TG main thread count.
+ :param tg_dtc: TG dataplane thread count.
+ :param tg_ltc: TG latency thread count.
+ :type node: dict
+ :type if1_pci: str
+ :type if2_pci: str
+ :type tg_mtc: int
+ :type tg_dtc: int
+ :type tg_ltc: int
+ :returns: List of CPUs allocated to T-Rex including numa node.
+ :rtype: int, int, int, list
+ """
+ interface_list = [if1_pci, if2_pci]
+ cpu_node = Topology.get_interfaces_numa_node(node, *interface_list)
+
+ master_thread_id = CpuUtils.cpu_slice_of_list_per_node(
+ node, cpu_node, skip_cnt=0, cpu_cnt=tg_mtc,
+ 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)
+
+ 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)
+
+ return master_thread_id[0], latency_thread_id[0], cpu_node, threads
+
+ @staticmethod
+ def get_affinity_iperf(
+ node, pf_key, cpu_skip_cnt=0, cpu_cnt=1):
+ """Get affinity for iPerf3. Result will be used to pin iPerf3 threads.
+
+ :param node: Topology node.
+ :param pf_key: Topology interface.
+ :param cpu_skip_cnt: Amount of CPU cores to skip.
+ :param cpu_cnt: CPU threads count.
+ :type node: dict
+ :type pf_key: str
+ :type cpu_skip_cnt: int
+ :type cpu_cnt: int
+ :returns: List of CPUs allocated to iPerf3.
+ :rtype: str
+ """
+ if pf_key:
+ cpu_node = Topology.get_interface_numa_node(node, pf_key)
+ else:
+ cpu_node = 0
+
+ return CpuUtils.cpu_range_per_node_str(
+ node, cpu_node, skip_cnt=cpu_skip_cnt, cpu_cnt=cpu_cnt,
+ smt_used=False)
+
+ @staticmethod
+ def get_affinity_vhost(
+ node, pf_key, skip_cnt=0, cpu_cnt=1):
+ """Get affinity for vhost. Result will be used to pin vhost threads.
+
+ :param node: Topology node.
+ :param pf_key: Topology interface.
+ :param skip_cnt: Amount of CPU cores to skip.
+ :param cpu_cnt: CPU threads count.
+ :type node: dict
+ :type pf_key: str
+ :type skip_cnt: int
+ :type cpu_cnt: int
+ :returns: List of CPUs allocated to vhost process.
+ :rtype: str
+ """
+ if pf_key:
+ cpu_node = Topology.get_interface_numa_node(node, pf_key)
+ else:
+ cpu_node = 0
+
+ smt_used = CpuUtils.is_smt_enabled(node[u"cpuinfo"])
+ if smt_used:
+ cpu_cnt = cpu_cnt // CpuUtils.NR_OF_THREADS
+
+ return CpuUtils.cpu_slice_of_list_per_node(
+ node, cpu_node=cpu_node, skip_cnt=skip_cnt, cpu_cnt=cpu_cnt,
+ smt_used=False)
+
+ @staticmethod
+ def get_cpu_idle_list(node, cpu_node, smt_used, cpu_alloc_str, sep=u","):
+ """
+ Get idle CPU List
+ :param node: Node dictionary with cpuinfo.
+ :param cpu_node: Numa node number.
+ :param smt_used: True - we want to use SMT, otherwise false.
+ :param cpu_alloc_str: vpp used cores.
+ :param sep: Separator, default: ",".
+ :type node: dict
+ :type cpu_node: int
+ :type smt_used: bool
+ :type cpu_alloc_str: str
+ :type smt_used: bool
+ :type sep: str
+ :rtype: list
+ """
+ cpu_list = CpuUtils.cpu_list_per_node(node, cpu_node, smt_used)
+ cpu_idle_list = [i for i in cpu_list
+ if str(i) not in cpu_alloc_str.split(sep)]
+ return cpu_idle_list