summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/vpp/config_resource_checks/cpu.py76
-rw-r--r--python/vyos/vpp/config_resource_checks/memory.py11
-rw-r--r--python/vyos/vpp/config_verify.py116
3 files changed, 22 insertions, 181 deletions
diff --git a/python/vyos/vpp/config_resource_checks/cpu.py b/python/vyos/vpp/config_resource_checks/cpu.py
deleted file mode 100644
index b319608e4..000000000
--- a/python/vyos/vpp/config_resource_checks/cpu.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Used for validating estimated CPU/physical cores use
-#
-# Copyright (C) VyOS Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-from vyos.utils.cpu import get_available_cpus, get_core_count
-
-from vyos.vpp.config_resource_checks.resource_defaults import default_resource_map
-
-
-# Get default value for reserved cpu cores
-reserved_cpus = default_resource_map.get('reserved_cpu_cores')
-
-
-def available_cores_count(cpu_settings: dict) -> int:
- core_count = get_core_count()
-
- if cpu_settings.get('main_core'):
- core_count -= 1
-
- skip_cores = int(cpu_settings.get('skip_cores', 0))
- # The default settings assume that
- # at least 2 CPU cores should remain reserved for system use
- # (only in case of current runtime is not smoke test)
- if skip_cores < reserved_cpus:
- core_count -= reserved_cpus
- else:
- core_count -= skip_cores
-
- return core_count
-
-
-def available_cores_list(skip_cores: int) -> list:
- # Available cores are all CPU cores without first N skipped cores that will not be used
- # Get all available physical cores - use set to filter out unique values
- cpu_cores = set(map(lambda el: el['cpu'], get_available_cpus()))
- cpu_cores = list(cpu_cores)
-
- return cpu_cores[skip_cores:]
-
-
-def worker_cores_list(iface: str, worker_ranges: list) -> list:
- all_core_numbers = []
- for worker_range in worker_ranges:
- core_numbers = worker_range.split('-')
-
- if int(core_numbers[0]) > int(core_numbers[-1]):
- raise ValueError(
- f'Range for "{iface} workers {worker_range}" is not correct'
- )
-
- all_core_numbers.extend(range(int(core_numbers[0]), int(core_numbers[-1]) + 1))
-
- # Check for duplicates
- duplicates = set(
- [str(x) for n, x in enumerate(all_core_numbers) if x in all_core_numbers[:n]]
- )
- if duplicates:
- raise ValueError(
- f'Some workers in "{iface} workers" are duplicated: #{",".join(list(duplicates))}'
- )
-
- return all_core_numbers
diff --git a/python/vyos/vpp/config_resource_checks/memory.py b/python/vyos/vpp/config_resource_checks/memory.py
index 03fe097e9..f1ae6f7bc 100644
--- a/python/vyos/vpp/config_resource_checks/memory.py
+++ b/python/vyos/vpp/config_resource_checks/memory.py
@@ -174,10 +174,11 @@ def total_memory_required(settings: dict) -> dict:
return memory
-def buffers_required(settings: dict, workers) -> int:
+def buffers_required(settings: dict) -> int:
"""
Calculate total VPP buffer requirements based on interface settings and workers.
"""
+ workers = int(settings['resource_allocation']['cpu_cores'])
buffers_total = 0
for ifname, iface_config in settings.get('interface', {}).items():
# Do not include XDP interfaces in buffer calculations.
@@ -185,14 +186,14 @@ def buffers_required(settings: dict, workers) -> int:
# so buffer requirements cannot be derived from descriptors here.
# Buffers for XDP are handled internally by the kernel/XDP layer,
# not by VPP’s buffer allocator.
- if iface_config.get('driver') == 'xdp':
- continue
+ # if iface_config.get('driver') == 'xdp':
+ # continue
+
dpdk_options = iface_config.get('dpdk_options', {})
rx_queues = int(dpdk_options.get('num_rx_queues', 1))
rx_desc = int(dpdk_options.get('num_rx_desc'))
# default TX queues is equal to number of worker threads
- # plus 1 main thread
- tx_queues = int(dpdk_options.get('num_tx_queues', workers + 1))
+ tx_queues = int(dpdk_options.get('num_tx_queues', workers))
tx_desc = int(dpdk_options.get('num_tx_desc'))
# buffers for RX/TX queues for interface
diff --git a/python/vyos/vpp/config_verify.py b/python/vyos/vpp/config_verify.py
index bcc10257f..f8bfb214a 100644
--- a/python/vyos/vpp/config_verify.py
+++ b/python/vyos/vpp/config_verify.py
@@ -22,7 +22,7 @@ from vyos import ConfigError
from vyos.base import Warning
from vyos.utils.cpu import get_core_count as total_core_count, get_cpus
-from vyos.vpp.config_resource_checks import cpu as cpu_checks, memory as mem_checks
+from vyos.vpp.config_resource_checks import memory as mem_checks
from vyos.vpp.config_resource_checks.resource_defaults import default_resource_map
from vyos.vpp.utils import human_memory_to_bytes, bytes_to_human_memory
@@ -183,17 +183,13 @@ def verify_dev_driver(driver_type: str, driver: str) -> bool:
return False
-def create_cpu_error_message(
- cpus_required: int, cpus_available: int = None, skip_cores: int = 0
-) -> str:
+def create_cpu_error_message(cpus_required: int, cpus_available: int = None) -> str:
cpu_info = get_cpus()
logical_cores = sum(
[int(s.get('siblings')) if 'siblings' in s else 1 for s in cpu_info]
)
reserved_cpus = default_resource_map.get('reserved_cpu_cores')
- if skip_cores > reserved_cpus:
- reserved_cpus = skip_cores
available_str = (
(
@@ -320,100 +316,19 @@ def verify_vpp_memory(config: dict):
)
-def verify_vpp_settings_cpu_skip_cores(skip_cores: int):
- cpu_cores = total_core_count()
-
- # The number of skipped cores must not be greater than
- # available CPU cores in the system - 1 for main thread
- if skip_cores > (cpu_cores - 1):
- raise ConfigError(
- f'The system does not have enough available CPUs to skip '
- f'(reduce "cpu skip-cores" to {cpu_cores} or less)'
- )
-
-
-def verify_vpp_settings_cpu(settings: dict):
- """
- Verify 'cpu main-core' is set if worker-related settings are used.
- `set vpp settings cpu workers` and `set vpp settings cpu corelist-workers`
- are mutually exclusive!
- """
- worker_related = ('corelist_workers', 'workers', 'skip_cores')
-
- if any(key in settings for key in worker_related) and 'main_core' not in settings:
- raise ConfigError('"cpu main-core" is required but not set!')
-
- if 'corelist_workers' in settings and 'workers' in settings:
- raise ConfigError(
- '"cpu corelist-workers" and "cpu workers" cannot be used at the same time!'
- )
-
-
-def verify_vpp_cpu_main_core(cpu_settings: dict) -> None:
- """Check that the main core is available"""
- skip_cores = int(cpu_settings.get('skip_cores', 0))
- available_cores = cpu_checks.available_cores_list(skip_cores)
- main_core = int(cpu_settings['main_core'])
-
- if main_core not in available_cores:
- raise ConfigError(
- 'Cannot set main core for VPP process: '
- f'CPU#{main_core} is not available.'
- )
-
-
-def verify_vpp_settings_cpu_workers(cpu_settings: dict):
+def verify_vpp_cpu_cores(cpu_cores: int):
"""
Verify that the system has enough available CPU cores
to run a given amount of worker processes (1 worker/core)
"""
- workers = int(cpu_settings.get('workers', 0))
- available_cores = cpu_checks.available_cores_count(cpu_settings)
-
- if workers > available_cores:
- raise ConfigError(
- f'Not enough free physical CPU cores for {workers} VPP workers '.ljust(72)
- + create_cpu_error_message(
- workers, available_cores, cpu_settings.get('skip_cores', 0)
- )
- )
-
-
-def verify_vpp_settings_cpu_corelist_workers(cpu_settings: dict):
- """
- Verify that the CPU cores provided to the config are free and can be used by VPP
- """
- workers = cpu_settings.get('corelist_workers')
- main_core = int(cpu_settings.get('main_core'))
- skip_cores = int(cpu_settings.get('skip_cores', 0))
- available_cores = cpu_checks.available_cores_list(skip_cores)
- try:
- all_core_nums = cpu_checks.worker_cores_list(
- iface='cpu corelist', worker_ranges=workers
- )
- except ValueError as e:
- raise ConfigError(str(e))
-
- error_msg = 'Cannot set VPP "cpu corelist-workers": '.ljust(72)
-
- if main_core in all_core_nums:
- raise ConfigError(
- f'CPU#{main_core} is set as main core and should not '
- 'be included to the corelist-workers'
- )
-
- invalid_cores = [str(el) for el in all_core_nums if el not in available_cores]
- if invalid_cores:
- raise ConfigError(error_msg + f'CPU# {",".join(invalid_cores)} not available.')
+ total_cores = total_core_count()
+ reserved_cpus = default_resource_map.get('reserved_cpu_cores')
+ available_cores = total_cores - reserved_cpus
- available_cores_count = cpu_checks.available_cores_count(cpu_settings)
- if len(all_core_nums) > available_cores_count:
+ if cpu_cores > available_cores:
raise ConfigError(
- error_msg
- + 'Not enough free physical CPUs in the system.'.ljust(72)
- + create_cpu_error_message(
- len(all_core_nums), available_cores_count, skip_cores
- )
+ f'Not enough free physical CPU cores for {cpu_cores} "cpu-cores" '.ljust(72)
+ + create_cpu_error_message(cpu_cores, available_cores)
)
@@ -441,12 +356,12 @@ def verify_vpp_interfaces_dpdk_num_queues(qtype: str, num_queues: int, workers:
if num_queues > workers:
raise ConfigError(
- f'The number of {qtype} queues cannot be greater than the number of configured VPP workers: '
- f'workers: {workers}, queues: {num_queues}'
+ f'The number of {qtype} queues cannot be greater than the number of configured VPP "cpu-cores": '
+ f'cpu-cores: {workers}, queues: {num_queues}'
)
-def verify_routes_count(settings: dict, workers: int):
+def verify_routes_count(settings: dict):
"""
Maximum routes count depending on main heap size,
statistics segment size and workers
@@ -454,12 +369,13 @@ def verify_routes_count(settings: dict, workers: int):
counters = 2 # 2 counters for each route
bytes = 16 # each counter consumes 16 bytes
statseg_scale = 2
+ cpu_cores = int(settings['resource_allocation']['cpu_cores'])
statseg_size = settings['statseg']['size']
statseg_size_in_bytes = human_memory_to_bytes(statseg_size)
main_heap = settings['memory']['main_heap_size']
main_heap_in_gb = human_memory_to_bytes(main_heap) >> 30
- formula = (workers + 1) * counters * bytes * statseg_scale
+ formula = cpu_cores * counters * bytes * statseg_scale
routes_count_statseg = statseg_size_in_bytes / formula
routes_count_statseg = round(routes_count_statseg / 1_000_000, 2)
routes_count_mh = main_heap_in_gb * 2
@@ -472,10 +388,10 @@ def verify_routes_count(settings: dict, workers: int):
)
-def verify_vpp_buffers(settings: dict, workers: int):
+def verify_vpp_buffers(settings: dict):
buffers_configured = int(settings['buffers']['buffers_per_numa'])
- buffers_required = mem_checks.buffers_required(settings, workers)
+ buffers_required = mem_checks.buffers_required(settings)
if buffers_required > buffers_configured:
raise ConfigError(