On Fri, Oct 23, 2020 at 04:48:05PM +0200, 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š <juraj.lin...@pantheon.tech>
> ---
>  buildtools/get_cpu_count.py  |  7 ++++++
>  buildtools/get_numa_count.py | 22 +++++++++++++++++
>  buildtools/meson.build       |  2 ++
>  config/meson.build           | 48 ++++++++++++++++++++++++++++++++++--
>  meson_options.txt            |  8 +++---
>  5 files changed, 81 insertions(+), 6 deletions(-)
>  create mode 100644 buildtools/get_cpu_count.py
>  create mode 100644 buildtools/get_numa_count.py
> 
> diff --git a/buildtools/get_cpu_count.py b/buildtools/get_cpu_count.py
> new file mode 100644
> index 000000000..386f85f8b
> --- /dev/null
> +++ b/buildtools/get_cpu_count.py
> @@ -0,0 +1,7 @@
> +#!/usr/bin/python3
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright (c) 2020 PANTHEON.tech s.r.o.
> +
> +import os
> +
> +print(os.cpu_count())
> diff --git a/buildtools/get_numa_count.py b/buildtools/get_numa_count.py
> new file mode 100644
> index 000000000..f0c49973a
> --- /dev/null
> +++ b/buildtools/get_numa_count.py
> @@ -0,0 +1,22 @@
> +#!/usr/bin/python3
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright (c) 2020 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:
> +        print(subprocess.run(['sysctl', 'vm.ndomains'], 
> capture_output=True).stdout)

I think you can shorten this, by just calling subprocess.run and not
capturing anything, in which case the stdout will be printed as normal.

        subprocess.run(['sysctl', 'vm.ndomains'])

> +
> +elif os.name == 'nt':
> +    libkernel32 = ctypes.windll.kernel32
> +
> +    count = ctypes.c_ulong()
> +
> +    libkernel32.GetNumaHighestNodeNumber(ctypes.pointer(count))
> +    print(count.value + 1)
> diff --git a/buildtools/meson.build b/buildtools/meson.build
> index 04808dabc..925e733b1 100644
> --- a/buildtools/meson.build
> +++ b/buildtools/meson.build
> @@ -17,3 +17,5 @@ else
>  endif
>  map_to_win_cmd = py3 + files('map_to_win.py')
>  sphinx_wrapper = py3 + files('call-sphinx-build.py')
> +get_cpu_count_cmd = py3 + files('get_cpu_count.py')
> +get_numa_count_cmd = py3 + files('get_numa_count.py')
> diff --git a/config/meson.build b/config/meson.build
> index 918ca2dfb..5c6fdcc7d 100644
> --- a/config/meson.build
> +++ b/config/meson.build
> @@ -230,8 +230,14 @@ foreach arg: warning_flags
>  endforeach
>  
>  # set other values pulled from the build options
> -dpdk_conf.set('RTE_MAX_LCORE', get_option('max_lcores'))
> -dpdk_conf.set('RTE_MAX_NUMA_NODES', get_option('max_numa_nodes'))
> +if not meson.is_cross_build()
> +     # set default values
> +     # these defaults may be overwritten by meson.build in an arch subdir
> +     # or later overwritten if a user specifies a value on the command line
> +     # or the user chooses to use values discovered from the build machine
> +     dpdk_conf.set('RTE_MAX_LCORE', 128)
> +     dpdk_conf.set('RTE_MAX_NUMA_NODES', 4)
> +endif

I think it might be better to remove this block, and instead set the values
below where you do the additional checks. It's confusing having these
settings managed in multiple places.

>  dpdk_conf.set('RTE_MAX_ETHPORTS', get_option('max_ethports'))
>  dpdk_conf.set('RTE_LIBEAL_USE_HPET', get_option('use_hpet'))
>  dpdk_conf.set('RTE_ENABLE_TRACE_FP', get_option('enable_trace_fp'))
> @@ -250,6 +256,44 @@ compile_time_cpuflags = []
>  subdir(arch_subdir)
>  dpdk_conf.set('RTE_COMPILE_TIME_CPUFLAGS', ','.join(compile_time_cpuflags))
>  
> +max_lcores = get_option('max_lcores')
> +max_numa_nodes = get_option('max_numa_nodes')
> +if max_lcores > 0
> +     dpdk_conf.set('RTE_MAX_LCORE', max_lcores)
> +elif max_lcores == -1
> +     if not meson.is_cross_build()
> +             max_lcores = run_command(get_cpu_count_cmd).stdout().to_int()
> +             min_lcores = 2
> +             if max_lcores < min_lcores
> +                     message('Found less than @0@ cores, building for @0@ 
> cores'.format(min_lcores))
> +                     max_lcores = min_lcores
> +             else
> +                     message('Found @0@ cores'.format(max_lcores))
> +             endif
> +             dpdk_conf.set('RTE_MAX_LCORE', max_lcores)
> +     endif
> +endif
> +
> +if max_numa_nodes > 0
> +     dpdk_conf.set('RTE_MAX_NUMA_NODES', max_numa_nodes)
> +elif max_numa_nodes == -1
> +     if not meson.is_cross_build()
> +             max_numa_nodes = 
> run_command(get_numa_count_cmd).stdout().to_int()
> +             message('Found @0@ numa nodes'.format(max_numa_nodes))
> +             dpdk_conf.set('RTE_MAX_NUMA_NODES', max_numa_nodes)
> +     endif
> +endif
> +
> +# check that cpu and numa count is set in cross builds
> +if meson.is_cross_build()
> +     if not dpdk_conf.has('RTE_MAX_LCORE')
> +             error('Number of cores for cross build not specified in @0@ 
> subdir (e.g. in a cross-file) nor on the cmdline'.format(arch_subdir))
> +     endif
> +     if not dpdk_conf.has('RTE_MAX_NUMA_NODES')
> +             error('Number of numa nodes for cross build not specified in 
> @0@ subdir (e.g. in a cross-file) nor on the cmdline'.format(arch_subdir))
> +     endif
> +endif
> +

I think we need some comments explaining all the logic here, and probably
some documentation updates.

>  # set the install path for the drivers
>  dpdk_conf.set_quoted('RTE_EAL_PMD_PATH', eal_pmd_path)
>  
> diff --git a/meson_options.txt b/meson_options.txt
> index 9bf18ab6b..a78c21b0d 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -26,10 +26,10 @@ option('machine', type: 'string', value: 'native',
>       description: 'set the target machine type')
>  option('max_ethports', type: 'integer', value: 32,
>       description: 'maximum number of Ethernet devices')
> -option('max_lcores', type: 'integer', value: 128,
> -     description: 'maximum number of cores/threads supported by EAL')
> -option('max_numa_nodes', type: 'integer', value: 4,
> -     description: 'maximum number of NUMA nodes supported by EAL')
> +option('max_lcores', type: 'integer', value: 0,
> +     description: 'maximum number of cores/threads supported by EAL. Set to 
> positive integer to overwrite per-arch or cross-compilation defaults. Set to 
> -1 to use number of cores on the build machine.')
> +option('max_numa_nodes', type: 'integer', value: 0,
> +     description: 'maximum number of NUMA nodes supported by EAL. Set to 
> positive integer to overwrite per-arch or cross-compilation defaults. Set to 
> -1 to use number of numa nodes on the build machine.')
>  option('enable_trace_fp', type: 'boolean', value: false,
>       description: 'enable fast path trace points.')
>  option('tests', type: 'boolean', value: true,
> -- 
> 2.20.1
> 

Reply via email to