diff options
| author | Daniil Baturin <daniil@vyos.io> | 2025-08-19 16:00:34 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-19 16:00:34 +0100 |
| commit | 4ad89d66634b7aa1464ae3e44bce179be48cc2bf (patch) | |
| tree | ba18ed6d8f6e17ab2d34c457e8c05638fd23dab3 | |
| parent | 41c9b0427b123041b0df5a2739468befb2f4e2db (diff) | |
| parent | 5fa2ba9bae1f3f86ad9aa5c13eefa0aff49fd7f4 (diff) | |
| download | vyos-1x-4ad89d66634b7aa1464ae3e44bce179be48cc2bf.tar.gz vyos-1x-4ad89d66634b7aa1464ae3e44bce179be48cc2bf.zip | |
Merge pull request #4647 from natali-rs1985/T7678
T7678: Move "vpp settings host-resources" to "system option resource-limits"
| -rw-r--r-- | interface-definitions/include/vpp_host_resources.xml.i | 35 | ||||
| -rw-r--r-- | interface-definitions/system_option.xml.in | 43 | ||||
| -rw-r--r-- | interface-definitions/vpp.xml.in | 1 | ||||
| -rw-r--r-- | python/vyos/vpp/config_resource_checks/memory.py | 8 | ||||
| -rw-r--r-- | python/vyos/vpp/config_verify.py | 15 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_vpp.py | 28 | ||||
| -rwxr-xr-x | src/conf_mode/system_option.py | 36 | ||||
| -rwxr-xr-x | src/conf_mode/vpp.py | 26 |
8 files changed, 107 insertions, 85 deletions
diff --git a/interface-definitions/include/vpp_host_resources.xml.i b/interface-definitions/include/vpp_host_resources.xml.i deleted file mode 100644 index 1706c8c87..000000000 --- a/interface-definitions/include/vpp_host_resources.xml.i +++ /dev/null @@ -1,35 +0,0 @@ -<!-- include start from vpp_host_resources.xml.i --> -<node name="host-resources"> - <properties> - <help>Host resources control</help> - </properties> - <children> - <leafNode name="max-map-count"> - <properties> - <help>Maximum number of memory map areas a process may have</help> - <valueHelp> - <format>u32:65535-2147483647</format> - <description>Areas count</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 65535-2147483647"/> - </constraint> - </properties> - <defaultValue>65535</defaultValue> - </leafNode> - <leafNode name="shmmax"> - <properties> - <help>Maximum shared memory segment size that can be created</help> - <valueHelp> - <format>u32:0-18446744073709551612</format> - <description>Size in bytes</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-18446744073709551612"/> - </constraint> - </properties> - <defaultValue>2147483648</defaultValue> - </leafNode> - </children> -</node> -<!-- include end --> diff --git a/interface-definitions/system_option.xml.in b/interface-definitions/system_option.xml.in index 5d385e3d0..e6a2b0b65 100644 --- a/interface-definitions/system_option.xml.in +++ b/interface-definitions/system_option.xml.in @@ -32,6 +32,49 @@ <constraintErrorMessage>Must be ignore, reboot, or poweroff</constraintErrorMessage> </properties> </leafNode> + <node name="resource-limits"> + <properties> + <help>Resource limits</help> + </properties> + <children> + <leafNode name="max-map-count"> + <properties> + <help>Maximum number of memory map areas a process may have</help> + <valueHelp> + <format>u32:65530-2147483647</format> + <description>Areas count</description> + </valueHelp> + <valueHelp> + <format>auto</format> + <description>Auto calculate areas count based on number of hugepages</description> + </valueHelp> + <constraint> + <regex>(auto)</regex> + <validator name="numeric" argument="--range 65530-2147483647"/> + </constraint> + </properties> + <defaultValue>auto</defaultValue> + </leafNode> + <leafNode name="shmmax"> + <properties> + <help>Maximum shared memory segment size that can be created</help> + <valueHelp> + <format>u64:8589934592-18446744073709551615</format> + <description>Size in bytes</description> + </valueHelp> + <valueHelp> + <format>auto</format> + <description>Auto calculate shared memory based on number of hugepages</description> + </valueHelp> + <constraint> + <regex>(auto)</regex> + <validator name="numeric" argument="--range 8589934592-18446744073709551615"/> + </constraint> + </properties> + <defaultValue>auto</defaultValue> + </leafNode> + </children> + </node> <node name="kernel"> <properties> <help>Kernel boot parameters</help> diff --git a/interface-definitions/vpp.xml.in b/interface-definitions/vpp.xml.in index 2443cebc3..f69e05168 100644 --- a/interface-definitions/vpp.xml.in +++ b/interface-definitions/vpp.xml.in @@ -449,7 +449,6 @@ </leafNode> </children> </node> - #include <include/vpp_host_resources.xml.i> <tagNode name="interface"> <properties> <help>Interface</help> diff --git a/python/vyos/vpp/config_resource_checks/memory.py b/python/vyos/vpp/config_resource_checks/memory.py index bce2df2bb..66b9fd9a3 100644 --- a/python/vyos/vpp/config_resource_checks/memory.py +++ b/python/vyos/vpp/config_resource_checks/memory.py @@ -51,14 +51,6 @@ def get_total_hugepages_memory() -> int: return hugepage_size * hugepages_total -def get_total_hugepages_count() -> int: - """ - Returns the total count of hugepages - """ - info = get_hugepages_info() - return info.get('HugePages_Total') - - def get_numa_count(): """ Run `numactl --hardware` and parse the 'available:' line. diff --git a/python/vyos/vpp/config_verify.py b/python/vyos/vpp/config_verify.py index 8902cdccb..c6f43e340 100644 --- a/python/vyos/vpp/config_verify.py +++ b/python/vyos/vpp/config_verify.py @@ -19,7 +19,6 @@ import psutil from vyos import ConfigError -from vyos.base import Warning from vyos.utils.cpu import get_core_count as total_core_count from vyos.vpp.control_host import get_eth_driver @@ -393,20 +392,6 @@ def verify_vpp_interfaces_dpdk_num_queues(qtype: str, num_queues: int, workers: ) -def verify_vpp_host_resources(config: dict): - max_map_count = int(config['settings']['host_resources']['max_map_count']) - - # Get HugePages total count - hugepages = mem_checks.get_total_hugepages_count() - - if max_map_count < 2 * hugepages: - Warning( - 'The max-map-count should be greater than or equal to (2 * HugePages_Total) ' - 'or VPP could work not properly. Please set up ' - f'"vpp settings host-resources max-map-count" to {2 * hugepages} or higher' - ) - - def verify_routes_count(settings: dict, workers: int): """ Maximum routes count depending on main heap size, diff --git a/smoketest/scripts/cli/test_vpp.py b/smoketest/scripts/cli/test_vpp.py index 07b4b1b19..b55db9e49 100755 --- a/smoketest/scripts/cli/test_vpp.py +++ b/smoketest/scripts/cli/test_vpp.py @@ -31,6 +31,7 @@ from vyos.configsession import ConfigSessionError from vyos.utils.process import process_named_running from vyos.utils.file import read_file from vyos.utils.process import rc_cmd +from vyos.utils.system import sysctl_read from vyos.vpp.utils import human_page_memory_to_bytes sys.path.append(os.getenv('vyos_completion_dir')) @@ -1417,6 +1418,33 @@ class TestVPP(VyOSUnitTestSHIM.TestCase): self.cli_delete(base_sflow) self.cli_commit() + def test_19_resource_limits(self): + max_map_count = '100000' + shmmax = '55555555555555' + hr_path = ['system', 'option', 'resource-limits'] + + # Check if max-map-count has default auto calculated value + # but not less than '65530' + self.assertEqual(sysctl_read('vm.max_map_count'), '65530') + # The same is with: kernel.shmmax = '8589934592' + self.assertEqual(sysctl_read('kernel.shmmax'), '8589934592') + + # Change max-map-count, shmmax and check + self.cli_set(hr_path + ['max-map-count', max_map_count]) + self.cli_set(hr_path + ['shmmax', shmmax]) + self.cli_commit() + + self.assertEqual(sysctl_read('vm.max_map_count'), max_map_count) + self.assertEqual(sysctl_read('kernel.shmmax'), shmmax) + + # We expect max-map-count and shmmax will return auto calculated values + self.cli_delete(hr_path + ['max-map-count']) + self.cli_delete(hr_path + ['shmmax']) + self.cli_commit() + + self.assertEqual(sysctl_read('vm.max_map_count'), '65530') + self.assertEqual(sysctl_read('kernel.shmmax'), '8589934592') + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/system_option.py b/src/conf_mode/system_option.py index fbe7231df..303557412 100755 --- a/src/conf_mode/system_option.py +++ b/src/conf_mode/system_option.py @@ -33,6 +33,7 @@ from vyos.utils.process import cmd from vyos.utils.process import is_systemd_service_running from vyos.utils.network import is_addr_assigned from vyos.utils.network import is_intf_addr_assigned +from vyos.utils.system import sysctl_write from vyos.configdep import set_dependents from vyos.configdep import call_dependents from vyos import ConfigError @@ -266,6 +267,41 @@ def apply(options): else: write_file(kernel_dynamic_debug, f'module {module} -p') + if 'resource_limits' in options: + unit_map = {'M': 1 << 20, 'G': 1 << 30} + + total_pages = 0 + total_bytes = 0 + + hp_sizes = options.get('kernel', {}).get('memory', {}).get('hugepage_size', {}) + for size_str, hp_config in hp_sizes.items(): + pages = int(hp_config.get('hugepage_count', 0)) + total_pages += pages + total_bytes += pages * int(size_str[:-1]) * unit_map[size_str[-1]] + + # Minimum recommended system values + max_map_count_min = 65530 # ensures large workload compatibility + shmmax_min = 8589934592 # 8 GiB safe default for large allocations + + max_map_count_conf = options['resource_limits'].get('max_map_count', 'auto') + shmmax_conf = options['resource_limits'].get('shmmax', 'auto') + + parameters = { + 'vm.max_map_count': ( + max(total_pages * 2, max_map_count_min) + if max_map_count_conf == 'auto' + else int(max_map_count_conf) + ), + 'kernel.shmmax': ( + max(total_bytes, shmmax_min) + if shmmax_conf == 'auto' + else int(shmmax_conf) + ), + } + + for parameter, value in parameters.items(): + sysctl_write(parameter, value) + if __name__ == '__main__': try: diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py index 90e71e522..966158ab7 100755 --- a/src/conf_mode/vpp.py +++ b/src/conf_mode/vpp.py @@ -35,7 +35,6 @@ from vyos.ifconfig import Section from vyos.template import render from vyos.utils.boot import boot_configuration_complete from vyos.utils.process import call -from vyos.utils.system import sysctl_read, sysctl_apply from vyos.vpp import VPPControl from vyos.vpp import control_host @@ -53,7 +52,6 @@ from vyos.vpp.config_verify import ( verify_vpp_memory, verify_vpp_statseg_size, verify_vpp_interfaces_dpdk_num_queues, - verify_vpp_host_resources, verify_routes_count, ) from vyos.vpp.config_filter import iface_filter_eth @@ -363,9 +361,6 @@ def verify(config): # Check if available memory is enough for current VPP config verify_vpp_memory(config) - if 'max_map_count' in config['settings'].get('host_resources', {}): - verify_vpp_host_resources(config) - if 'statseg' in config['settings']: verify_vpp_statseg_size(config['settings']) @@ -478,27 +473,6 @@ def generate(config): render(service_conf, 'vpp/startup.conf.j2', config['settings']) render(systemd_override, 'vpp/override.conf.j2', config) - # apply sysctl values - # default: https://github.com/FDio/vpp/blob/v23.10/src/vpp/conf/80-vpp.conf - # vm.nr_hugepages are now configured in section - # 'set system option kernel memory hugepage-size 2M hugepage-count <count>' - sysctl_config: dict[str, str] = { - 'vm.max_map_count': config['settings']['host_resources']['max_map_count'], - 'vm.hugetlb_shm_group': '0', - 'kernel.shmmax': config['settings']['host_resources']['shmmax'], - } - # we do not want to lower current values - for sysctl_key, sysctl_value in sysctl_config.items(): - # perform check only for quantitative params - if sysctl_key == 'vm.hugetlb_shm_group': - pass - current_value = sysctl_read(sysctl_key) - if int(current_value) > int(sysctl_value): - sysctl_config[sysctl_key] = current_value - - if not sysctl_apply(sysctl_config): - raise ConfigError('Cannot configure sysctl parameters for VPP') - return None |
