From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 16FB045813; Mon, 19 Aug 2024 13:23:07 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9B39E4028A; Mon, 19 Aug 2024 13:23:06 +0200 (CEST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mails.dpdk.org (Postfix) with ESMTP id DC68740267 for ; Mon, 19 Aug 2024 13:23:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1724066584; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5U6QEVAtUlnOYaBa3njxnlKKMjA10Sy7xMK8OniydiE=; b=I1t7KmyhAmg1kVTF3EgA8ozF9Tyhy6PwIgdXz+xR4JKALxmnTUI8ogSzeV/aSCmlM6ceLz CGOMQz3GXoGIESieqDwnZfZ4JbCNe1mCxIEejHFVHUZCIKC8u+T1JT6yCTatRfNaqajs1G kbzJDtp5NbVubpp2V1g2SVeldFbuVy8= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-561-tAW84di0PNq-AKfdO0dJoQ-1; Mon, 19 Aug 2024 07:23:03 -0400 X-MC-Unique: tAW84di0PNq-AKfdO0dJoQ-1 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-428ea5b1479so34236395e9.0 for ; Mon, 19 Aug 2024 04:23:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724066582; x=1724671382; h=in-reply-to:references:user-agent:to:from:cc:subject:message-id :date:content-transfer-encoding:mime-version:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=5U6QEVAtUlnOYaBa3njxnlKKMjA10Sy7xMK8OniydiE=; b=koUBs10dvm5snCkckPJjByfw2nVSl84htN4kzEO/XBwsUtNnQdmsJV0rVvW4ZJZtt2 yVOxJfRwfRbnRV+jfi89cFEA9539k6zN0my//dBCntxY7V5RWmJ8qVXhw8w3zXx6TQ8y 7C3rdJONe/lquRkfqEY0k546Cz9drd86m90H63dCM1w3oObz+zq/y0VLHWowfkU0LBfD zZ6yGPAzWEEA4J9wjleNmkdIzkwxsVNV/WM3Oe9cHaHt0G9k1pqk4c0+FccOAnwHIc4+ qeLUvSF7hA64t++tnjWf4JCBfVf8aoT7MOsulg5eraSJbiWqeIziGW60PM3cRPesPBQc CrGw== X-Forwarded-Encrypted: i=1; AJvYcCWHmJgrEjerovWKUPY0Pkp/Ef7mEmUp8nbu///4PDktRv3LPIij6kw1Kh/7j4aNcqVUcwn/+SvgxFb1UHI= X-Gm-Message-State: AOJu0YxOxpo5LFZzgFHsu3JIQBMfeUBdGUio2fkkdDh3j1YjtAPq0T9U iw34ZaJg92iUqwTa4ZISZEbGx6AYbKW5i8cEEzz19OwxlpKbW+kJy3DLtxEoWIr5Jq+3PtDrmsF YPakpxtVRe4V7wUCKFUF+xJaNT3a9eRHmdnMVOSaN X-Received: by 2002:a05:600c:474e:b0:426:6b85:bafb with SMTP id 5b1f17b1804b1-429ed7b8a14mr81325245e9.20.1724066581922; Mon, 19 Aug 2024 04:23:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHmExY7nfR5olJbfXkTpdX46Mlq9fIj2m9XjpQZiwPua2oEWZ5H3BLlCahRE2tkqSghcTLXvw== X-Received: by 2002:a05:600c:474e:b0:426:6b85:bafb with SMTP id 5b1f17b1804b1-429ed7b8a14mr81325045e9.20.1724066581426; Mon, 19 Aug 2024 04:23:01 -0700 (PDT) Received: from localhost (2a01cb00025433006239e1f47a0b2371.ipv6.abo.wanadoo.fr. [2a01:cb00:254:3300:6239:e1f4:7a0b:2371]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-429ed648f00sm106799185e9.7.2024.08.19.04.23.00 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 19 Aug 2024 04:23:01 -0700 (PDT) Mime-Version: 1.0 Date: Mon, 19 Aug 2024 13:23:00 +0200 Message-Id: Subject: Re: [PATCH v2 2/4] usertools/cpu_layout: print out NUMA nodes Cc: From: "Robin Jarry" To: "Anatoly Burakov" , User-Agent: aerc/0.18.2-23-g4abdbd4014f5-dirty References: <79418ee26f32ad7d850360fb2060b7a9d6d391f9.1723810613.git.anatoly.burakov@intel.com> In-Reply-To: <79418ee26f32ad7d850360fb2060b7a9d6d391f9.1723810613.git.anatoly.burakov@intel.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8; format=Flowed X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Anatoly Burakov, Aug 16, 2024 at 14:16: > In traditional NUMA case, NUMA nodes and physical sockets were used > interchangeably, but there are cases where there can be multiple NUMA > nodes per socket, as well as all CPU's being assigned NUMA node 0 even in > cases of multiple sockets. Use sysfs to print out NUMA information. > > Signed-off-by: Anatoly Burakov > --- > usertools/cpu_layout.py | 35 ++++++++++++++++++++++++++++++----- > 1 file changed, 30 insertions(+), 5 deletions(-) > > diff --git a/usertools/cpu_layout.py b/usertools/cpu_layout.py > index be86f06938..e43bdbf343 100755 > --- a/usertools/cpu_layout.py > +++ b/usertools/cpu_layout.py > @@ -4,6 +4,7 @@ > # Copyright(c) 2017 Cavium, Inc. All rights reserved. > =20 > from typing import List, Set, Dict, Tuple > +import glob Can you keep the import sorted alphabetically? > =20 > =20 > def _range_expand(rstr: str) -> List[int]: > @@ -26,11 +27,19 @@ def _read_sysfs(path: str) -> str: > return fd.read().strip() > =20 > =20 > +def _read_numa_node(base: str) -> int: > + node_glob =3D f"{base}/node*" > + node_dirs =3D glob.glob(node_glob) > + if not node_dirs: > + return 0 # default to node 0 > + return int(node_dirs[0].split("node")[1]) Maybe you could make this safer and more "python"-ic as follows: def read_numa_node(base: str) -> int: for node in glob.iglob(f"{base}/node*"): match =3D re.match(r"^.*/node(\d+)$", node) if match: return int(match.group(1)) return 0 # default to node 0 > + > + > def _print_row(row: Tuple[str, ...], col_widths: List[int]) -> None: > first, *rest =3D row > w_first, *w_rest =3D col_widths > first_end =3D " " * 4 > - rest_end =3D " " * 10 > + rest_end =3D " " * 4 > =20 > print(first.ljust(w_first), end=3Dfirst_end) > for cell, width in zip(rest, w_rest): > @@ -50,6 +59,7 @@ def _main() -> None: > sockets_s: Set[int] =3D set() > cores_s: Set[int] =3D set() > core_map: Dict[Tuple[int, int], List[int]] =3D {} > + numa_map: Dict[int, int] =3D {} > base_path =3D "/sys/devices/system/cpu" > =20 > cpus =3D _range_expand(_read_sysfs(f"{base_path}/online")) > @@ -58,12 +68,14 @@ def _main() -> None: > lcore_base =3D f"{base_path}/cpu{cpu}" > core =3D int(_read_sysfs(f"{lcore_base}/topology/core_id")) > socket =3D int(_read_sysfs(f"{lcore_base}/topology/physical_pack= age_id")) > + node =3D _read_numa_node(lcore_base) > =20 > cores_s.add(core) > sockets_s.add(socket) > key =3D (socket, core) > core_map.setdefault(key, []) > core_map[key].append(cpu) > + numa_map[cpu] =3D node > =20 > cores =3D sorted(cores_s) > sockets =3D sorted(sockets_s) > @@ -73,24 +85,37 @@ def _main() -> None: > =20 > print("cores =3D ", cores) > print("sockets =3D ", sockets) > + print("numa =3D ", sorted(set(numa_map.values()))) > print() > =20 > - # Core, [Socket, Socket, ...] > - heading_strs =3D "", *[f"Socket {s}" for s in sockets] > + # Core, [NUMA, Socket, NUMA, Socket, ...] > + heading_strs =3D "", *[v for s in sockets for v in ("", f"Socket {s}= ")] > sep_strs =3D tuple("-" * len(hstr) for hstr in heading_strs) > rows: List[Tuple[str, ...]] =3D [] > =20 > + prev_numa =3D None > for c in cores: > # Core, > row: Tuple[str, ...] =3D (f"Core {c}",) > =20 > - # [lcores, lcores, ...] > + # assume NUMA changes symmetrically > + first_lcore =3D core_map[(0, c)][0] > + cur_numa =3D numa_map[first_lcore] > + numa_changed =3D prev_numa !=3D cur_numa > + prev_numa =3D cur_numa > + > + # [NUMA, lcores, NUMA, lcores, ...] > for s in sockets: > try: > lcores =3D core_map[(s, c)] > + numa =3D numa_map[lcores[0]] > + if numa_changed: > + row +=3D (f"NUMA {numa}",) > + else: > + row +=3D ("",) > row +=3D (str(lcores),) > except KeyError: > - row +=3D ("",) > + row +=3D ("", "") > rows +=3D [row] > =20 > # find max widths for each column, including header and rows > --=20 > 2.43.5