From: Randy L Tice <[email protected]> Date: Thu, 03 Sep 2026 09:13:28 -0400
Add build-time support for optional cache-line-aligned dynamic-field storage at the end of struct rte_mbuf. The mbuf_dynfield3_cnt Meson option sets RTE_MBUF_DYNFIELD3_CNT in rte_build_config.h. A non-zero value enables the extra area. When enabled, dynfield3 is made available to the mbuf dynamic field allocator and is copied by the generic mbuf dynamic-field copy helper. This extends the existing Dynamic Mbuf Fields backing storage without changing the default mbuf layout. Validate that the configured element count is non-negative and that the reserved space is a multiple of the cache line size. Signed-off-by: Randy L Tice <[email protected]> --- app/test/test_mbuf.c | 5 +++-- config/meson.build | 10 ++++++++++ doc/guides/rel_notes/release_26_11.rst | 15 +++++++++++++++ lib/mbuf/rte_mbuf.h | 3 +++ lib/mbuf/rte_mbuf_core.h | 16 ++++++++++++++++ lib/mbuf/rte_mbuf_dyn.c | 3 +++ meson_options.txt | 2 ++ 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c index db23259745..9f3b396a61 100644 --- a/app/test/test_mbuf.c +++ b/app/test/test_mbuf.c @@ -2776,8 +2776,9 @@ test_mbuf(void) struct rte_mempool *pktmbuf_pool = NULL; struct rte_mempool *pktmbuf_pool2 = NULL; - - RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != RTE_CACHE_LINE_MIN_SIZE * 2); + RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != + RTE_CACHE_LINE_MIN_SIZE * 2 + + RTE_MBUF_DYNFIELD3_SIZE); /* create pktmbuf pool if it does not exist */ pktmbuf_pool = rte_pktmbuf_pool_create("test_pktmbuf_pool", diff --git a/config/meson.build b/config/meson.build index 344f68822b..e500a7b075 100644 --- a/config/meson.build +++ b/config/meson.build @@ -384,6 +384,11 @@ dpdk_conf.set('RTE_LIBEAL_USE_HPET', get_option('use_hpet')) dpdk_conf.set('RTE_ENABLE_STDATOMIC', get_option('enable_stdatomic')) dpdk_conf.set('RTE_ENABLE_TRACE_FP', get_option('enable_trace_fp')) dpdk_conf.set('RTE_PKTMBUF_HEADROOM', get_option('pkt_mbuf_headroom')) +mbuf_dynfield3_cnt = get_option('mbuf_dynfield3_cnt') +if mbuf_dynfield3_cnt < 0 + error('mbuf_dynfield3_cnt must be greater than or equal to 0') +endif +dpdk_conf.set('RTE_MBUF_DYNFIELD3_CNT', mbuf_dynfield3_cnt) # values which have defaults which may be overridden dpdk_conf.set('RTE_MAX_VFIO_GROUPS', 64) dpdk_conf.set('RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB', 64) @@ -395,6 +400,11 @@ dpdk_conf.set10('RTE_IOVA_IN_MBUF', get_option('enable_iova_as_pa')) compile_time_cpuflags = [] subdir(arch_subdir) +mbuf_dynfield3_size = mbuf_dynfield3_cnt * cc.sizeof('uintptr_t', + prefix: '#include <stdint.h>') +if mbuf_dynfield3_size % dpdk_conf.get('RTE_CACHE_LINE_SIZE') != 0 + error('mbuf_dynfield3_cnt must reserve a multiple of RTE_CACHE_LINE_SIZE') +endif dpdk_conf.set('RTE_COMPILE_TIME_CPUFLAGS', ','.join(compile_time_cpuflags)) # apply cross-specific options diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst index dec96ccbc7..abe82e7e3f 100644 --- a/doc/guides/rel_notes/release_26_11.rst +++ b/doc/guides/rel_notes/release_26_11.rst @@ -60,6 +60,13 @@ New Features Added the experimental ``rte_cpu_socket_id()`` function to map an OS logical CPU ID to the NUMA socket containing that CPU. +* **Added optional extra mbuf dynamic-field storage.** + + Added ``mbuf_dynfield3_cnt`` build option to reserve a + cache-line-aligned ``dynfield3`` area in ``struct rte_mbuf``. + The value is defined as ``RTE_MBUF_DYNFIELD3_CNT`` in + ``rte_build_config.h``; a non-zero value enables the extra area. + * **Added TPID support to VLAN tag insertion.** Added ``rte_vlan_insert_tpid()`` to the net library. @@ -338,6 +345,14 @@ Known Issues Also, make sure to start the actual text at the margin. ======================================================= +* **Some drivers may require changes for enlarged mbufs.** + + Enabling ``mbuf_dynfield3_cnt`` with a non-zero value increases + ``sizeof(struct rte_mbuf)``. Drivers or applications that assume a + fixed mbuf size may require follow-up changes. The + ``mempool/octeontx`` driver currently asserts that + ``sizeof(struct rte_mbuf)`` does not exceed its fixed buffer offset. + Tested Platforms ---------------- diff --git a/lib/mbuf/rte_mbuf.h b/lib/mbuf/rte_mbuf.h index 60ec8158cd..6a567a9e43 100644 --- a/lib/mbuf/rte_mbuf.h +++ b/lib/mbuf/rte_mbuf.h @@ -1231,6 +1231,9 @@ rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc) mdst->dynfield2 = msrc->dynfield2; #endif memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1)); +#if RTE_MBUF_DYNFIELD3_CNT > 0 + memcpy(&mdst->dynfield3, msrc->dynfield3, sizeof(mdst->dynfield3)); +#endif } /* internal */ diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h index 98b0bd9ca7..bb57397bb6 100644 --- a/lib/mbuf/rte_mbuf_core.h +++ b/lib/mbuf/rte_mbuf_core.h @@ -17,6 +17,7 @@ */ #include <stdalign.h> +#include <stddef.h> #include <stdint.h> #include <rte_byteorder.h> @@ -686,8 +687,23 @@ struct __rte_cache_aligned rte_mbuf { uint16_t timesync; uint32_t dynfield1[9]; /**< Reserved for dynamic fields. */ + +#if RTE_MBUF_DYNFIELD3_CNT > 0 + alignas(RTE_CACHE_LINE_SIZE) + uintptr_t dynfield3[RTE_MBUF_DYNFIELD3_CNT]; + /**< Reserved for dynamic fields. */ +#endif /* RTE_MBUF_DYNFIELD3_CNT > 0 */ }; +#define RTE_MBUF_DYNFIELD3_SIZE \ + (RTE_MBUF_DYNFIELD3_CNT * sizeof(uintptr_t)) +#if RTE_MBUF_DYNFIELD3_CNT > 0 +#define RTE_MBUF_DYNFIELD3_OFFSET \ + offsetof(struct rte_mbuf, dynfield3) +#else +#define RTE_MBUF_DYNFIELD3_OFFSET 0 +#endif + /** * Function typedef of callback to free externally attached buffer. */ diff --git a/lib/mbuf/rte_mbuf_dyn.c b/lib/mbuf/rte_mbuf_dyn.c index 5987c9dee8..dcbe0a8416 100644 --- a/lib/mbuf/rte_mbuf_dyn.c +++ b/lib/mbuf/rte_mbuf_dyn.c @@ -135,6 +135,9 @@ init_shared_mem(void) #if !RTE_IOVA_IN_MBUF mark_free(dynfield2); #endif +#if RTE_MBUF_DYNFIELD3_CNT > 0 + mark_free(dynfield3); +#endif /* init free_flags */ for (mask = RTE_MBUF_F_FIRST_FREE; mask <= RTE_MBUF_F_LAST_FREE; mask <<= 1) diff --git a/meson_options.txt b/meson_options.txt index e28d24054c..337f9e5e49 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -44,6 +44,8 @@ option('max_numa_nodes', type: 'string', value: 'default', description: 'Set the highest NUMA node supported by EAL; "default" is different per-arch, "detect" detects the highest NUMA node on the build machine.') option('enable_iova_as_pa', type: 'boolean', value: true, description: 'Support the use of physical addresses for IO addresses, such as used by UIO or VFIO in no-IOMMU mode. When disabled, DPDK can only run with IOMMU support for address mappings, but will have more space available in the mbuf structure.') +option('mbuf_dynfield3_cnt', type: 'integer', value: 0, description: + 'Size of optional extra mbuf dynamic field area, in uintptr_t units.') option('mbuf_refcnt_atomic', type: 'boolean', value: true, description: 'Atomically access the mbuf refcnt.') option('platform', type: 'string', value: 'native', description: -- 2.35.6

