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 54FD3A034F; Wed, 31 Mar 2021 21:07:23 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D470C140ED9; Wed, 31 Mar 2021 21:07:22 +0200 (CEST) Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by mails.dpdk.org (Postfix) with ESMTP id C8A6B140ED8 for ; Wed, 31 Mar 2021 21:07:20 +0200 (CEST) Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 12VJ3vvg006175 for ; Wed, 31 Mar 2021 15:07:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=subject : to : references : from : message-id : date : mime-version : in-reply-to : content-type; s=pp1; bh=wSJqR5HwbMCjLasulnb2Iite7zLh3gOxrTPixu6rPoE=; b=Zu9QCvUK06Zn4gdGMDOQOzNQIcH2GcgxTn3nauBWluEu30VY9X4KyrRFvIftl+JnLnei weOZql1H7yFDl/wf2y1S+uhI/pRd3PcPxoB/z6N7a3X2cpwsEvCFGEZl5JLb1Zdo/2pP /RDKxC3eqRWbxli3aAqAaeGRVpnIsl4/nadSqgYJj0IUHApezrCV6iqu7zhKdypZikSZ jCe3y5/UmJQv3ap7BMp3VMc6ANyS/zoCPEFEYpb+y9Jb7tXOaCCwrDi6UVhFvsXRIspn wCx8/b15AbIR3PMhgRaHBoLduhSPRJnFe9Ga60MqduTaNR0wQrRTe0C6eDzTDL9DoNzy 8g== Received: from ppma01dal.us.ibm.com (83.d6.3fa9.ip4.static.sl-reverse.com [169.63.214.131]) by mx0b-001b2d01.pphosted.com with ESMTP id 37mvhhwnmh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 31 Mar 2021 15:07:19 -0400 Received: from pps.filterd (ppma01dal.us.ibm.com [127.0.0.1]) by ppma01dal.us.ibm.com (8.16.0.43/8.16.0.43) with SMTP id 12VIwEFv003036 for ; Wed, 31 Mar 2021 19:07:19 GMT Received: from b01cxnp22034.gho.pok.ibm.com (b01cxnp22034.gho.pok.ibm.com [9.57.198.24]) by ppma01dal.us.ibm.com with ESMTP id 37maawh9v6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 31 Mar 2021 19:07:19 +0000 Received: from b01ledav002.gho.pok.ibm.com (b01ledav002.gho.pok.ibm.com [9.57.199.107]) by b01cxnp22034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 12VJ7IOq32702894 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 31 Mar 2021 19:07:18 GMT Received: from b01ledav002.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 54EF0124052 for ; Wed, 31 Mar 2021 19:07:18 +0000 (GMT) Received: from b01ledav002.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 00048124054 for ; Wed, 31 Mar 2021 19:07:17 +0000 (GMT) Received: from Davids-MBP.randomparity.org (unknown [9.163.0.90]) by b01ledav002.gho.pok.ibm.com (Postfix) with ESMTP for ; Wed, 31 Mar 2021 19:07:17 +0000 (GMT) To: dev@dpdk.org References: <1605876920-31394-1-git-send-email-juraj.linkes@pantheon.tech> <1617181602-18293-1-git-send-email-juraj.linkes@pantheon.tech> From: David Christensen Message-ID: Date: Wed, 31 Mar 2021 12:07:17 -0700 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: <1617181602-18293-1-git-send-email-juraj.linkes@pantheon.tech> Content-Type: multipart/mixed; boundary="------------FE20DFDD39AA77C52206DE37" Content-Language: en-US X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 4C-0kbOTI9x8l-AEIm8Nko5S0KSRHQE_ X-Proofpoint-ORIG-GUID: 4C-0kbOTI9x8l-AEIm8Nko5S0KSRHQE_ X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.369, 18.0.761 definitions=2021-03-31_10:2021-03-31, 2021-03-31 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 adultscore=0 spamscore=0 clxscore=1015 suspectscore=0 bulkscore=0 mlxlogscore=999 mlxscore=0 malwarescore=0 priorityscore=1501 phishscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2103300000 definitions=main-2103310129 Subject: Re: [dpdk-dev] [PATCH v2] build: optional NUMA and cpu counts detection 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 Sender: "dev" This is a multi-part message in MIME format. --------------FE20DFDD39AA77C52206DE37 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit On 3/31/21 2:06 AM, Juraj Linkeš wrote: > Add an option to automatically discover the host's numa and cpu counts > and use those values for a non cross-build. > Give users the option to override the per-arch default values or values > from cross files by specifying them on the command line with -Dmax_lcores > and -Dmax_numa_nodes. > > Signed-off-by: Juraj Linkeš > Reviewed-by: Honnappa Nagarahalli > --- > MAINTAINERS | 2 ++ > buildtools/get-cpu-count.py | 7 ++++++ > buildtools/get-numa-count.py | 22 +++++++++++++++++ > buildtools/meson.build | 2 ++ > config/meson.build | 47 ++++++++++++++++++++++++++++++++++-- > config/x86/meson.build | 2 ++ > meson_options.txt | 8 +++--- > 7 files changed, 84 insertions(+), 6 deletions(-) > create mode 100644 buildtools/get-cpu-count.py > create mode 100644 buildtools/get-numa-count.py > > diff --git a/MAINTAINERS b/MAINTAINERS > index 0ec5588540..7270f33cf5 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -99,6 +99,8 @@ F: meson_options.txt > F: config/ > F: buildtools/chkincs/ > F: buildtools/call-sphinx-build.py > +F: buildtools/get-cpu-count.py > +F: buildtools/get-numa-count.py > F: buildtools/list-dir-globs.py > F: buildtools/pkg-config/ > F: buildtools/symlink-drivers-solibs.sh > diff --git a/buildtools/get-cpu-count.py b/buildtools/get-cpu-count.py > new file mode 100644 > index 0000000000..317b32088f > --- /dev/null > +++ b/buildtools/get-cpu-count.py > @@ -0,0 +1,7 @@ > +#!/usr/bin/env python3 > +# SPDX-License-Identifier: BSD-3-Clause > +# Copyright (c) 2021 PANTHEON.tech s.r.o. > + > +import os > + > +print(os.cpu_count()) Returns the expected value on a P9 system. > diff --git a/buildtools/get-numa-count.py b/buildtools/get-numa-count.py > new file mode 100644 > index 0000000000..77ef2b9f24 > --- /dev/null > +++ b/buildtools/get-numa-count.py > @@ -0,0 +1,22 @@ > +#!/usr/bin/env python3 > +# SPDX-License-Identifier: BSD-3-Clause > +# Copyright (c) 2021 PANTHEON.tech s.r.o. > + > +import ctypes > +import glob > +import os > +import subprocess > + > +if os.name == 'posix': > + if os.path.isdir('/sys/devices/system/node'): > + print(len(glob.glob('/sys/devices/system/node/node*'))) > + else: > + subprocess.run(['sysctl', '-n', 'vm.ndomains']) > + > +elif os.name == 'nt': > + libkernel32 = ctypes.windll.kernel32 > + > + count = ctypes.c_ulong() > + > + libkernel32.GetNumaHighestNodeNumber(ctypes.pointer(count)) > + print(count.value + 1) Does not return the expected value on my P9 system (NUMA nodes are not contiguous). Got 6, expect to see at least 8 otherwise I can't use lcores on NUMA node 8. $ python3 ./get-numa-count.py 6 $ lscpu Architecture: ppc64le Byte Order: Little Endian CPU(s): 128 On-line CPU(s) list: 0-127 Thread(s) per core: 4 Core(s) per socket: 16 Socket(s): 2 NUMA node(s): 6 Model: 2.3 (pvr 004e 1203) Model name: POWER9, altivec supported CPU max MHz: 3800.0000 CPU min MHz: 2300.0000 L1d cache: 32K L1i cache: 32K L2 cache: 512K L3 cache: 10240K NUMA node0 CPU(s): 0-63 NUMA node8 CPU(s): 64-127 NUMA node252 CPU(s): NUMA node253 CPU(s): NUMA node254 CPU(s): NUMA node255 CPU(s): See attached ls-node.txt.gz for full directory structure on a P9 system. Dave --------------FE20DFDD39AA77C52206DE37 Content-Type: application/x-gzip; x-mac-type="0"; x-mac-creator="0"; name="ls-node.txt.gz" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="ls-node.txt.gz" H4sICMnHZGAAA2xzLW5vZGUudHh0AO3cXVIcSbYE4HdWwQYQyvNTUHq4Gxi7a2ijRU2PzATI BEi3d38ha6anU1HuhLu1Wb9ojOn5KeKQlRwH6sRXcfH14uL48e58Of/68PB0/Meu/nH+vzdf z3M5X+LD+/fnl4+/P17eHr59+nh4fP3vT4e7y/uH28Plv24ef/n45fns4i+pdHe4e/j6+19U 7P7h693N57+u5sP950/3h7+g0JeHx8dPv35+LfWdllp2Lx8flsKlng/fDvdPZ2fwE17/8f7D 2dPD083n8/dnt1+//9/Xi9ePd+f1p694fv5++xXfbT51Tz/13dnFxfeL47/euCcfH+6+3Hx8 Ovv8Wnz92C74oXifv/TW+/OL/3n5IpcvHy//6/Xf76X1y7B+0daPF7CIV3DiEsRriLFCaBVy rJBahRorlFahxwqtVdiNFXZahauxwpVW4XqscK1V2I8V9lKFsR20boixp0Pr6Rh7OrSejhNP QnwWY0+H1tMx9nRoPR1jT4fW0zH2dGg9HWNPh9bTMfZ0aD0dY0+H1tPjN1P7XubY06n1dI49 nVpP59jTqfV0nrgN4n0Yezq1ns6xp1Pr6Rx7OrWezrGnU+vpHHs6tZ7OsadT6+nxW6F9J2rs 6dJ6usaeLq2na+zp0nq6xp4urafrxI0U7+TY06X1dI09XVpP19jTpfV0jT1dWk/X2NOl9fR4 I7X72GNPt9bTPfZ0az3dY0+31tM99nRrPd1jT7fW033iWyF+L8aebq2ne+zp1nq6x55urad7 7OnWenq8Ddpd2I09vdN6ejf29E7r6d3Y0zutp3djT++0nh6bQeuFsRW0ThgbYf/mwObl9dwS H17+7nr57M+fHp/eXvCfycfLgrubL5Of//IH8u1L9Zv7j4fZMUyf/+v5t8OXm98Oj/MXdXe4 +3T/z4c3b9sfM5njgOxPDXz8P/79H2938Q+FFlDo7Wb+sRC6pInpy1AK1zKKwaf43niSAYu9 Hd6hWMJib+d4KFaw2Nu/poZiDYu9/RtrKLaDxd7+sT0Uu4LF3v7ZNRS7hsXe/kE2FNvDYm// dvuxGOxZvWVxMI1kkgszrgyGaWJaOhSDYZoYnA7FYJgmZqhDMRimiXHqUAyGaWKyOhSDYZoY sg7FYJgm5q1DMRimidHrj8Vgm+ldFjBMEwPZoRgM08RsdiiGn6XxNGGYJia2QzEYponh7VAM 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 ++tUSZKemd2wUyVJemY2x06VJOmZ2Ss7VZKkZ2br7FRJkp6ZnbRTJUl6ZjbWTpSEb808PmiV ZOnR36O5rmLp0Q+9Xlex9OhHX6+rWHr0A7DXVSw9+jHY6yqWHv0w7HUVS49+JPa6iqVHPxh7 XcXSox+P/boKHmt9fNAqydKjn2+9rmLp0U+5Xlex9OhnXa+rWHr0E6/XVSw9+rnX6yqWHv30 63UVS49+Bva6iqVHPwl7XcXSo5+H/boKnmN9fNAqydKjH2i9rmLp0Y+1Xlex9OiHW6+rWHr0 I67XVSw9+kHX6yqWHv2463UVS49+6PW6iqVHP/p6XcXSox+A/boKHlx9fNAqydKjn2C9rmLp 0c+xXlex9OinWa+rWHr0M63XVSw9+tHK6yqWHv2A2XUVS49+zOa6iqVHP2xwXcXSox+59roK nhV1fNAqydKjn5qzrmLp0c+oWVex9Ohn1ayrWHr0M2vWVSw9+tk16yqWHv0Mm3UVS49+ls26 iqVHP9NmXcXSo59t87oKHktzfNAqydKjH1GzrmLp0Y+qWVex9OhH1qyrWHr0o2vWVSw9+hE2 6yqWHv0om3UVS49+pM26iqVHP9pmXcXSox9x87oKnk5zfNAqydKjn1SzrmLpsazBwqzBYlmD hVmDxbIGC7MGi2UNFmYNFssaLMwaLJY1WJg1WCxrsDBrsFjWYGHWYLGswcKswWJZg4VZg8Wy BguzBotlDRZmDRbLGizMGiyWNViYNVgsa7Awa7BY1mBh1mCxrMHCrMFiWYOFWYPFsgYLswaL ZQ0WZg0WyxoszBosljVYmDVYLGuwMGuwWNZgYdZgsazBwqzBYlmDhVmDxbIGC7MGi2UNglmD sKxBMGsQljUIZg3CsgbBrEFY1iCYNQjLGgSzBmFZg2DWICxrEMwahGUNglmDsKxBMGsQljUI Zg3CsgbBrEFY1iCYNQjLGgSzBmFZg2DWICxrEMwahGUNglmDsKxBMGsQljUIZg3CsgbBrEFY 1iCYNQjLGgSzBmFZg2DWICxrEMwahGUNglmDsKxBMGsQljUIZg3CsgbBrEFY1iCYNQjLGgSz BmFZg2DWICxrEMwahGUNglmDsKxBMGsQljUIZg3CsgbBrEFY1iCYNQjLGgSzBmFZg2DWICxr EMwahGUNglmDsKxBMGsQljUIZg3CsgbBrEFY1iCYNQjLGgSzBmFZg2DWICxrEMwahGUNglmD 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 --------------FE20DFDD39AA77C52206DE37--