[PATCH 1/1] mbuf: add optional dynfield3 storage
Randy L Tice
rtice at cisco.com
Thu Sep 24 21:37:47 CEST 2026
From: Randy L Tice <rtice at cisco.com>
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 <rtice at cisco.com>
---
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
More information about the dev
mailing list