From: ogawa.yasufumi@lab.ntt.co.jp
To: ferruh.yigit@intel.com, spp@dpdk.org, ogawa.yasufumi@lab.ntt.co.jp
Subject: [spp] [PATCH] tools: add customized cpu_layout tool
Date: Wed, 23 Jan 2019 17:41:57 +0900 [thread overview]
Message-ID: <1548232917-24539-1-git-send-email-ogawa.yasufumi@lab.ntt.co.jp> (raw)
From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
`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 <ogawa.yasufumi@lab.ntt.co.jp>
---
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
reply other threads:[~2019-01-23 8:44 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1548232917-24539-1-git-send-email-ogawa.yasufumi@lab.ntt.co.jp \
--to=ogawa.yasufumi@lab.ntt.co.jp \
--cc=ferruh.yigit@intel.com \
--cc=spp@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).