From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from tama50.ecl.ntt.co.jp (tama50.ecl.ntt.co.jp [129.60.39.147]) by dpdk.org (Postfix) with ESMTP id EDCE029D2 for ; Wed, 23 Jan 2019 09:44:14 +0100 (CET) Received: from vc1.ecl.ntt.co.jp (vc1.ecl.ntt.co.jp [129.60.86.153]) by tama50.ecl.ntt.co.jp (8.13.8/8.13.8) with ESMTP id x0N8iDUp003623; Wed, 23 Jan 2019 17:44:13 +0900 Received: from vc1.ecl.ntt.co.jp (localhost [127.0.0.1]) by vc1.ecl.ntt.co.jp (Postfix) with ESMTP id 81F44EA7AD5; Wed, 23 Jan 2019 17:44:13 +0900 (JST) Received: from localhost.localdomain (lobster.nslab.ecl.ntt.co.jp [129.60.13.95]) by vc1.ecl.ntt.co.jp (Postfix) with ESMTP id 73A24EA7AA2; Wed, 23 Jan 2019 17:44:13 +0900 (JST) From: ogawa.yasufumi@lab.ntt.co.jp To: ferruh.yigit@intel.com, spp@dpdk.org, ogawa.yasufumi@lab.ntt.co.jp Date: Wed, 23 Jan 2019 17:41:57 +0900 Message-Id: <1548232917-24539-1-git-send-email-ogawa.yasufumi@lab.ntt.co.jp> X-Mailer: git-send-email 2.7.4 X-TM-AS-MML: disable Subject: [spp] [PATCH] tools: add customized cpu_layout tool X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Jan 2019 08:44:15 -0000 From: Yasufumi Ogawa `cpu_layout.py` is provided as a usertool of DPDK which is used to show layout of sockets, cores and CPUs. This update is to add a customized version of this tool to show the layout in JSON format. It is intended to be used from other programs. To output in JSON format, simply add `--json` option. Signed-off-by: Yasufumi Ogawa --- tools/cpu_layout.py | 144 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100755 tools/cpu_layout.py diff --git a/tools/cpu_layout.py b/tools/cpu_layout.py new file mode 100755 index 0000000..58a2bd6 --- /dev/null +++ b/tools/cpu_layout.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2010-2014 Intel Corporation +# Copyright(c) 2017 Cavium, Inc. All rights reserved. +# Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + +from __future__ import print_function +import argparse +import json +import sys +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + +base_path = "/sys/devices/system/cpu" + + +def parse_args(): + parser = argparse.ArgumentParser( + description="Show CPU layout") + + parser.add_argument( + "--json", action="store_true", + help="Output in JSON format") + return parser.parse_args() + + +def get_max_cpus(): + fd = open("{}/kernel_max".format(base_path)) + max_cpus = int(fd.read()) + fd.close() + return max_cpus + + +def get_resource_info(max_cpus): + """Return a set of sockets, cores and core_map as a tuple.""" + sockets = [] + cores = [] + core_map = {} + + for cpu in xrange(max_cpus + 1): + try: + topo_path = "{}/cpu{}/topology".format(base_path, cpu) + + # Get physical core ID. + fd = open("{}/core_id".format(topo_path)) + core = int(fd.read()) + fd.close() + if core not in cores: + cores.append(core) + + fd = open("{}/physical_package_id".format(topo_path)) + socket = int(fd.read()) + fd.close() + if socket not in sockets: + sockets.append(socket) + + key = (socket, core) + if key not in core_map: + core_map[key] = [] + core_map[key].append(cpu) + + except IOError: + continue + + except Exception as e: + print(e) + break + + return sockets, cores, core_map + + +def print_header(cores, sockets): + print(format("=" * (47 + len(base_path)))) + print("Core and Socket Information (as reported by '{}')".format( + base_path)) + print("{}\n".format("=" * (47 + len(base_path)))) + print("cores = ", cores) + print("sockets = ", sockets) + print("") + + +def print_body(cores, sockets, core_map): + max_processor_len = len(str(len(cores) * len(sockets) * 2 - 1)) + max_thread_count = len(list(core_map.values())[0]) + max_core_map_len = (max_processor_len * max_thread_count) \ + + len(", ") * (max_thread_count - 1) \ + + len('[]') + len('Socket ') + max_core_id_len = len(str(max(cores))) + + output = " ".ljust(max_core_id_len + len('Core ')) + for s in sockets: + output += " Socket %s" % str(s).ljust( + max_core_map_len - len('Socket ')) + print(output) + + output = " ".ljust(max_core_id_len + len('Core ')) + for s in sockets: + output += " --------".ljust(max_core_map_len) + output += " " + print(output) + + for c in cores: + output = "Core %s" % str(c).ljust(max_core_id_len) + for s in sockets: + if (s, c) in core_map: + output += " " + str(core_map[(s, c)]).ljust(max_core_map_len) + else: + output += " " * (max_core_map_len + 1) + print(output) + + +def core_map_to_json(core_map): + cpu_layout = [] + cpu_sockets = {} + for (s, c), cpus in core_map.items(): + if not (s in cpu_sockets): + cpu_sockets[s] = {} + cpu_sockets[s]["cores"] = [] + cpu_sockets[s]["cores"].append({"core_id": c, "cpus": cpus}) + + for sid, val in cpu_sockets.items(): + cpu_layout.append({"socket_id": sid, "cores": val["cores"]}) + + return json.dumps(cpu_layout) + + +def main(): + args = parse_args() + + max_cpus = get_max_cpus() + sockets, cores, core_map = get_resource_info(max_cpus) + + if args.json is True: + print(core_map_to_json(core_map)) + + else: + print_header(cores, sockets) + print_body(cores, sockets, core_map) + + +if __name__ == '__main__': + main() -- 2.17.1