diff options
| author | Nataliia Solomko <natalirs1985@gmail.com> | 2025-09-01 14:08:21 +0300 |
|---|---|---|
| committer | Nataliia Solomko <natalirs1985@gmail.com> | 2025-09-05 10:57:51 +0300 |
| commit | 5c6e25f50ddac493ab6c61726fb4a1f96b9bf55c (patch) | |
| tree | c5d03433c6a7347b5ae8443110e091e4f4f7c7c7 | |
| parent | 133cb0c65d5aa2ca5a96feba6ab7adc3a8f1de58 (diff) | |
| download | vyos-1x-5c6e25f50ddac493ab6c61726fb4a1f96b9bf55c.tar.gz vyos-1x-5c6e25f50ddac493ab6c61726fb4a1f96b9bf55c.zip | |
T7757: VPP Verify buffers for rx/tx queues
| -rw-r--r-- | interface-definitions/vpp.xml.in | 5 | ||||
| -rw-r--r-- | python/vyos/vpp/config_resource_checks/memory.py | 34 | ||||
| -rw-r--r-- | python/vyos/vpp/config_verify.py | 12 | ||||
| -rwxr-xr-x | src/conf_mode/vpp.py | 17 |
4 files changed, 58 insertions, 10 deletions
diff --git a/interface-definitions/vpp.xml.in b/interface-definitions/vpp.xml.in index f69e05168..356345f84 100644 --- a/interface-definitions/vpp.xml.in +++ b/interface-definitions/vpp.xml.in @@ -367,6 +367,7 @@ <validator name="numeric" argument="--range 0-4294967295"/> </constraint> </properties> + <defaultValue>16384</defaultValue> </leafNode> <leafNode name="data-size"> <properties> @@ -379,12 +380,14 @@ <validator name="numeric" argument="--range 0-4294967295"/> </constraint> </properties> + <defaultValue>2048</defaultValue> </leafNode> <leafNode name="page-size"> <properties> <help>Set the page-size for buffer allocation</help> #include <include/unformat_log2_page_size.xml.i> </properties> + <defaultValue>default</defaultValue> </leafNode> </children> </node> @@ -501,6 +504,7 @@ <validator name="numeric" argument="--range 256-8192"/> </constraint> </properties> + <defaultValue>1024</defaultValue> </leafNode> <leafNode name="num-tx-desc"> <properties> @@ -513,6 +517,7 @@ <validator name="numeric" argument="--range 256-8192"/> </constraint> </properties> + <defaultValue>1024</defaultValue> </leafNode> <leafNode name="num-rx-queues"> <properties> diff --git a/python/vyos/vpp/config_resource_checks/memory.py b/python/vyos/vpp/config_resource_checks/memory.py index 9391e21e1..8b201ef87 100644 --- a/python/vyos/vpp/config_resource_checks/memory.py +++ b/python/vyos/vpp/config_resource_checks/memory.py @@ -28,6 +28,10 @@ from vyos.vpp.utils import ( from vyos.vpp.config_resource_checks.resource_defaults import default_resource_map +# VPP buffers default per NUMA node +MIN_BUFFERS = 16_384 + + def classify_page_size(page_size_bytes: int) -> str: """ Returns one of: '4K', '2M', '1G' based on page size. @@ -187,3 +191,33 @@ def total_memory_required(settings: dict) -> dict: memory[classify_page_size(page_size)] += memory_size return memory + + +def buffers_required(settings: dict, workers) -> int: + """ + Calculate total VPP buffer requirements based on interface settings and workers. + """ + buffers_total = 0 + for ifname, iface_config in settings.get('interface', {}).items(): + 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')) + tx_queues = int(dpdk_options.get('num_tx_queues', workers + 1)) + tx_desc = int(dpdk_options.get('num_tx_desc')) + + # buffers for RX/TX queues for interface + buffers_total += rx_queues * rx_desc + tx_queues * tx_desc + + # per-thread buffer caches (approx. 256 buffers per worker) + buffers_total += workers * 256 + + # Safety margin for buffer calculations: + # traffic bursts, alignment/metadata overhead etc. + # The factor 2.5 is derived from VPP’s own calculations: + # https://github.com/FDio/vpp/blob/stable/2506/extras/vpp_config/vpplib/AutoConfig.py#L609 + buffers_total = int(buffers_total * 2.5) + + # Enforce minimum required by VPP (16K buffers) + return max(buffers_total, MIN_BUFFERS) diff --git a/python/vyos/vpp/config_verify.py b/python/vyos/vpp/config_verify.py index cf0b923bb..78c5d420b 100644 --- a/python/vyos/vpp/config_verify.py +++ b/python/vyos/vpp/config_verify.py @@ -442,3 +442,15 @@ def verify_routes_count(settings: dict, workers: int): 'Extensive use of features like ACLs, NAT and others may reduce the numbers above. ' 'Please read the documentation for details: https://docs.vyos.io/' ) + + +def verify_vpp_buffers(settings: dict, workers: int): + buffers_configured = int(settings['buffers']['buffers_per_numa']) + + buffers_required = mem_checks.buffers_required(settings, workers) + + if buffers_required > buffers_configured: + raise ConfigError( + 'Not enough buffers to initialize RX/TX queues for interfaces. ' + f'Set "vpp settings buffers buffers-per-numa" to {buffers_required} or higher' + ) diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py index 9517f85f3..b205291f2 100755 --- a/src/conf_mode/vpp.py +++ b/src/conf_mode/vpp.py @@ -58,6 +58,7 @@ from vyos.vpp.config_verify import ( verify_vpp_interfaces_dpdk_num_queues, verify_routes_count, verify_vpp_main_heap_size, + verify_vpp_buffers, ) from vyos.vpp.config_filter import iface_filter_eth from vyos.vpp.utils import EthtoolGDrvinfo @@ -223,10 +224,12 @@ def get_config(config=None): # dictionary retrieved. default_values = conf.get_config_defaults(**config.kwargs, recursive=True) - # delete 'xdp-options' from defaults if driver is DPDK + # delete driver-incompatible defaults for iface, iface_config in config.get('settings', {}).get('interface', {}).items(): if iface_config.get('driver') == 'dpdk': del default_values['settings']['interface'][iface]['xdp_options'] + elif iface_config.get('driver') == 'xdp': + del default_values['settings']['interface'][iface]['dpdk_options'] config = config_dict_merge(default_values, config) @@ -342,15 +345,6 @@ def get_config(config=None): eth_ifaces_persist[iface]['bus_id'] = control_host.get_bus_name(iface) eth_ifaces_persist[iface]['dev_id'] = control_host.get_dev_id(iface) - # Get kernel settings for hugepages - kernel_memory_settings = conf.get_config_dict( - ['system', 'option', 'kernel', 'memory'], - key_mangling=('-', '_'), - get_first_key=True, - no_tag_node_value_mangle=True, - ) - config['kernel_memory_settings'] = kernel_memory_settings - # Return to config dictionary config['persist_config'] = eth_ifaces_persist @@ -411,6 +405,9 @@ def verify(config): verify_vpp_main_heap_size(config['settings']) verify_vpp_statseg_size(config['settings']) + # Check buffers + verify_vpp_buffers(config['settings'], workers) + # Check if available memory is enough for current VPP config verify_vpp_memory(config) |
