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_size Meson option sets RTE_MBUF_DYNFIELD3_SIZE
in rte_build_config.h. A non-zero value enables the extra area. The
storage is represented as uint64_t elements for 32-bit and 64-bit
build consistency.

When enabled, dynfield3 is made available to the mbuf dynamic field
allocator. The mbuf_dynfield3_copy option controls whether the area is
copied by the generic mbuf dynamic-field copy helper, and defaults to
false.

Validate that the configured size is non-negative, is a multiple of
sizeof(uint64_t), and reserves a multiple of the cache line size.

Signed-off-by: Randy L Tice <[email protected]>
---
 app/test/test_mbuf.c                   |  5 +++--
 config/meson.build                     | 16 ++++++++++++++++
 doc/guides/rel_notes/release_26_11.rst | 15 +++++++++++++++
 lib/mbuf/rte_mbuf.h                    |  6 ++++++
 lib/mbuf/rte_mbuf_core.h               | 17 +++++++++++++++++
 lib/mbuf/rte_mbuf_dyn.c                |  3 +++
 meson_options.txt                      |  4 ++++
 7 files changed, 64 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..dd857e065f 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -384,6 +384,19 @@ 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_size = get_option('mbuf_dynfield3_size')
+if mbuf_dynfield3_size < 0
+    error('mbuf_dynfield3_size must be greater than or equal to 0')
+endif
+if mbuf_dynfield3_size % cc.sizeof('uint64_t', prefix: '#include <stdint.h>') 
!= 0
+    error('mbuf_dynfield3_size must be a multiple of sizeof(uint64_t)')
+endif
+mbuf_dynfield3_copy = get_option('mbuf_dynfield3_copy')
+if mbuf_dynfield3_copy and mbuf_dynfield3_size == 0
+    error('mbuf_dynfield3_copy requires mbuf_dynfield3_size greater than 0')
+endif
+dpdk_conf.set('RTE_MBUF_DYNFIELD3_SIZE', mbuf_dynfield3_size)
+dpdk_conf.set10('RTE_MBUF_DYNFIELD3_COPY', mbuf_dynfield3_copy)
 # 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 +408,9 @@ dpdk_conf.set10('RTE_IOVA_IN_MBUF', 
get_option('enable_iova_as_pa'))
 
 compile_time_cpuflags = []
 subdir(arch_subdir)
+if mbuf_dynfield3_size % dpdk_conf.get('RTE_CACHE_LINE_SIZE') != 0
+    error('mbuf_dynfield3_size must be 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..2d0fb6660c 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -60,6 +60,15 @@ 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_size`` build option to enable a
+  cache-line-aligned ``dynfield3`` area in ``struct rte_mbuf``.
+  The configured size is defined as ``RTE_MBUF_DYNFIELD3_SIZE``
+  in ``rte_build_config.h``.
+  The area is not copied by generic mbuf copy or clone operations
+  unless ``mbuf_dynfield3_copy`` is enabled.
+
 * **Added TPID support to VLAN tag insertion.**
 
   Added ``rte_vlan_insert_tpid()`` to the net library.
@@ -338,6 +347,12 @@ Known Issues
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* **Some drivers may require changes for enlarged mbufs.**
+
+  Enabling ``mbuf_dynfield3_size`` with a non-zero value increases
+  ``sizeof(struct rte_mbuf)``. Drivers or applications that assume a
+  fixed mbuf size may require follow-up changes.
+
 
 Tested Platforms
 ----------------
diff --git a/lib/mbuf/rte_mbuf.h b/lib/mbuf/rte_mbuf.h
index 60ec8158cd..97360d6549 100644
--- a/lib/mbuf/rte_mbuf.h
+++ b/lib/mbuf/rte_mbuf.h
@@ -1231,6 +1231,12 @@ 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_SIZE > 0
+       if (RTE_MBUF_DYNFIELD3_COPY)
+               memcpy(RTE_PTR_ADD(mdst, RTE_MBUF_DYNFIELD3_OFFSET),
+                       RTE_PTR_ADD(msrc, RTE_MBUF_DYNFIELD3_OFFSET),
+                       RTE_MBUF_DYNFIELD3_SIZE);
+#endif
 }
 
 /* internal */
diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
index 98b0bd9ca7..5069984269 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>
@@ -26,6 +27,9 @@
 extern "C" {
 #endif
 
+#define RTE_MBUF_DYNFIELD3_CNT \
+       (RTE_MBUF_DYNFIELD3_SIZE / sizeof(uint64_t))
+
 /*
  * Packet Offload Features Flags. It also carry packet type information.
  * Critical resources. Both rx/tx shared these bits. Be cautious on any change
@@ -686,8 +690,21 @@ struct __rte_cache_aligned rte_mbuf {
        uint16_t timesync;
 
        uint32_t dynfield1[9]; /**< Reserved for dynamic fields. */
+
+#if RTE_MBUF_DYNFIELD3_SIZE > 0
+       alignas(RTE_CACHE_LINE_SIZE)
+       uint64_t dynfield3[RTE_MBUF_DYNFIELD3_CNT];
+       /**< Reserved cache-line-aligned space for dynamic fields. */
+#endif /* RTE_MBUF_DYNFIELD3_SIZE > 0 */
 };
 
+#if RTE_MBUF_DYNFIELD3_SIZE > 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..b42fe6377d 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_SIZE > 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..579c434b9a 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -44,6 +44,10 @@ 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_size', type: 'integer', value: 0, description:
+       'Size of optional extra mbuf dynamic field area, in bytes.')
+option('mbuf_dynfield3_copy', type: 'boolean', value: false, description:
+       'Copy optional extra mbuf dynamic field area during mbuf copy/clone.')
 option('mbuf_refcnt_atomic', type: 'boolean', value: true, description:
        'Atomically access the mbuf refcnt.')
 option('platform', type: 'string', value: 'native', description:
-- 
2.35.6

Reply via email to