summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2025-10-10 21:11:35 +0200
committerGitHub <noreply@github.com>2025-10-10 21:11:35 +0200
commita1be2ee22cd058d5e18e6ef4fb3ec6468a38aa37 (patch)
tree5dfecfd6d047b8dd0cfa038cffdd1ef646f0d9fb /src
parent7c1bbdfade7b447a4e6723ea3ba13fc1942cd0e2 (diff)
parentc5cac68ba5a135f80f971e78b97cb9b1c3a0b932 (diff)
downloadvyos-1x-a1be2ee22cd058d5e18e6ef4fb3ec6468a38aa37.tar.gz
vyos-1x-a1be2ee22cd058d5e18e6ef4fb3ec6468a38aa37.zip
Merge pull request #4772 from natali-rs1985/T7887
T7887: system_option: Add validation for memory hugepage-count
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/system_option.py65
1 files changed, 55 insertions, 10 deletions
diff --git a/src/conf_mode/system_option.py b/src/conf_mode/system_option.py
index cb3d6ce9b..a0b3dd72c 100755
--- a/src/conf_mode/system_option.py
+++ b/src/conf_mode/system_option.py
@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import psutil
from sys import exit
from time import sleep
@@ -39,6 +40,8 @@ from vyos.configdep import call_dependents
from vyos import ConfigError
from vyos import airbag
+from vyos.vpp.config_resource_checks import memory as mem_check
+
airbag.enable()
curlrc_config = r'/etc/curlrc'
@@ -56,6 +59,21 @@ tuned_profiles = {
}
+def _get_total_hugepages_and_memory(config):
+ unit_map = {'M': 1 << 20, 'G': 1 << 30}
+
+ total_pages = 0
+ total_bytes = 0
+
+ hp_sizes = config.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]]
+
+ return total_pages, total_bytes
+
+
def get_config(config=None):
if config:
conf = config
@@ -116,6 +134,40 @@ def verify(options):
f'AMD pstate driver cannot be used with "{cpu_vendor}" CPU!'
)
+ _, hp_memory_bytes = _get_total_hugepages_and_memory(
+ options['kernel'].get('memory', {})
+ )
+ if hp_memory_bytes:
+ memory = psutil.virtual_memory()
+ memory_total_bytes = memory.total
+
+ # Exclude hugepage usage from system "used" memory
+ hp_memory_used = sum(
+ p['memory'] for p in mem_check.get_hugepages_info().values()
+ )
+ memory_used_bytes = memory.used - hp_memory_used
+
+ # TODO: need to calculate how much memory is consumed for other services, tmpfs etc.
+ # for now we should leave at least 4 GB for system usage and other processes
+ min_system_reserved_gd = 4
+ memory_margin_gb = 1
+ reserved_bytes = max(
+ min_system_reserved_gd * 1024**3,
+ memory_used_bytes + memory_margin_gb * 1024**3,
+ )
+
+ available_for_hp_bytes = memory_total_bytes - reserved_bytes
+ if available_for_hp_bytes < hp_memory_bytes:
+ # For the error message, convert to GB and round to 1 decimal
+ hp_memory_gb = round(hp_memory_bytes / 1024**3, 1)
+ available_for_hp_gb = max(0, round(available_for_hp_bytes / 1024**3, 1))
+ reserved_gb = round(reserved_bytes / 1024**3, 1)
+ raise ConfigError(
+ f'Configured hugepages require {hp_memory_gb} GB of memory, but only '
+ f'{available_for_hp_gb:.1f} GB is available '
+ f'({reserved_gb} GB is reserved for system usage and services)'
+ )
+
return None
@@ -269,16 +321,9 @@ def apply(options):
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]]
+ total_pages, total_bytes = _get_total_hugepages_and_memory(
+ options.get('kernel', {}).get('memory', {})
+ )
# Minimum recommended system values
max_map_count_min = 65530 # ensures large workload compatibility