X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FCpuUtils.py;h=e23404b1dde6d3166542271db127d5fc19363913;hp=f261f9421e2f6e7c8634c7bf900d449f749c8068;hb=9780b57a9640e9ab40e40ec122ac80e09cd74c79;hpb=44dcb3113c8ade2e44543746abca861a89362c9b diff --git a/resources/libraries/python/CpuUtils.py b/resources/libraries/python/CpuUtils.py index f261f9421e..e23404b1dd 100644 --- a/resources/libraries/python/CpuUtils.py +++ b/resources/libraries/python/CpuUtils.py @@ -84,6 +84,29 @@ class CpuUtils: [CpuUtils.__str2int(x) for x in line.split(u",")] ) + @staticmethod + def worker_count_from_cores_and_smt(phy_cores, smt_used): + """Simple conversion utility, needs smt from caller. + + The implementation assumes we pack 1 or 2 workers per core, + depending on hyperthreading. + + Some keywords use None to indicate no core/worker limit, + so this converts None to None. + + :param phy_cores: How many physical cores to use for workers. + :param smt_used: Whether symmetric multithreading is used. + :type phy_cores: Optional[int] + :type smt_used: bool + :returns: How many VPP workers fit into the given number of cores. + :rtype: Optional[int] + """ + if phy_cores is None: + return None + workers_per_core = CpuUtils.NR_OF_THREADS if smt_used else 1 + workers = phy_cores * workers_per_core + return workers + @staticmethod def cpu_node_count(node): """Return count of numa nodes. @@ -232,7 +255,7 @@ class CpuUtils: cpu_list_0 = cpu_list[:cpu_list_len // CpuUtils.NR_OF_THREADS] cpu_list_1 = cpu_list[cpu_list_len // CpuUtils.NR_OF_THREADS:] cpu_range = f"{cpu_list_0[0]}{sep}{cpu_list_0[-1]}," \ - f"{cpu_list_1[0]}{sep}{cpu_list_1[-1]}" + f"{cpu_list_1[0]}{sep}{cpu_list_1[-1]}" else: cpu_range = f"{cpu_list[0]}{sep}{cpu_list[-1]}" @@ -310,6 +333,36 @@ class CpuUtils: result[0:0] = cpu_list[mt_skip:mt_skip + 1] return result + @staticmethod + def get_affinity_af_xdp( + node, pf_key, cpu_skip_cnt=0, cpu_cnt=1): + """Get affinity for AF_XDP interface. Result will be used to pin IRQs. + + :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 AF_XDP interface. + :rtype: list + """ + 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, skip_cnt=cpu_skip_cnt, cpu_cnt=cpu_cnt, + smt_used=smt_used + ) + @staticmethod def get_affinity_nf( nodes, node, nf_chains=1, nf_nodes=1, nf_chain=1, nf_node=1, @@ -445,4 +498,26 @@ class CpuUtils: return CpuUtils.cpu_slice_of_list_per_node( node, cpu_node=cpu_node, skip_cnt=skip_cnt, cpu_cnt=cpu_cnt, - smt_used=smt_used) + 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