If all devices are configured to run in IOVA mode as VA, physical address field of mbuf (buf_iova) won't be used. In such cases, buf_iova space is free to use as a dynamic field. So a new dynamic field member (dynfield2) is added in mbuf structure to make use of that space.
A new mbuf flag RTE_MBUF_F_DYNFIELD2 is introduced to help identify the mbuf that can use dynfield2. Signed-off-by: Shijith Thotton <sthot...@marvell.com> --- lib/mbuf/rte_mbuf.c | 8 ++++++++ lib/mbuf/rte_mbuf.h | 16 +++++++++++++--- lib/mbuf/rte_mbuf_core.h | 29 ++++++++++++++++++++++------- lib/mbuf/rte_mbuf_dyn.c | 3 +++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/lib/mbuf/rte_mbuf.c b/lib/mbuf/rte_mbuf.c index a2307cebe6..718b4505c4 100644 --- a/lib/mbuf/rte_mbuf.c +++ b/lib/mbuf/rte_mbuf.c @@ -101,6 +101,10 @@ rte_pktmbuf_init(struct rte_mempool *mp, m->port = RTE_MBUF_PORT_INVALID; rte_mbuf_refcnt_set(m, 1); m->next = NULL; + + /* enable dynfield2 if IOVA mode is VA */ + if (rte_eal_iova_mode() == RTE_IOVA_VA) + m->ol_flags = RTE_MBUF_F_DYNFIELD2; } /* @@ -206,6 +210,10 @@ __rte_pktmbuf_init_extmem(struct rte_mempool *mp, rte_mbuf_refcnt_set(m, 1); m->next = NULL; + /* enable dynfield2 if IOVA mode is VA */ + if (rte_eal_iova_mode() == RTE_IOVA_VA) + m->ol_flags |= RTE_MBUF_F_DYNFIELD2; + /* init external buffer shared info items */ shinfo = RTE_PTR_ADD(m, mbuf_size); m->shinfo = shinfo; diff --git a/lib/mbuf/rte_mbuf.h b/lib/mbuf/rte_mbuf.h index 9811e8c760..59485f04ed 100644 --- a/lib/mbuf/rte_mbuf.h +++ b/lib/mbuf/rte_mbuf.h @@ -1056,9 +1056,11 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr, RTE_ASSERT(shinfo->free_cb != NULL); m->buf_addr = buf_addr; - m->buf_iova = buf_iova; m->buf_len = buf_len; + if (!RTE_MBUF_HAS_DYNFIELD2(m)) + m->buf_iova = buf_iova; + m->data_len = 0; m->data_off = 0; @@ -1087,6 +1089,10 @@ static inline void rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc) { memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1)); + + if (RTE_MBUF_HAS_DYNFIELD2(mdst)) + memcpy(&mdst->dynfield2, &msrc->dynfield2, + sizeof(mdst->dynfield2)); } /* internal */ @@ -1143,10 +1149,12 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m) mi->data_off = m->data_off; mi->data_len = m->data_len; - mi->buf_iova = m->buf_iova; mi->buf_addr = m->buf_addr; mi->buf_len = m->buf_len; + if (!RTE_MBUF_HAS_DYNFIELD2(mi)) + mi->buf_iova = m->buf_iova; + mi->next = NULL; mi->pkt_len = mi->data_len; mi->nb_segs = 1; @@ -1245,11 +1253,13 @@ static inline void rte_pktmbuf_detach(struct rte_mbuf *m) m->priv_size = priv_size; m->buf_addr = (char *)m + mbuf_size; - m->buf_iova = rte_mempool_virt2iova(m) + mbuf_size; m->buf_len = (uint16_t)buf_len; rte_pktmbuf_reset_headroom(m); m->data_len = 0; m->ol_flags = 0; + + if (!RTE_MBUF_HAS_DYNFIELD2(m)) + m->buf_iova = rte_mempool_virt2iova(m) + mbuf_size; } /** diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h index 3d6ddd6773..a549e36464 100644 --- a/lib/mbuf/rte_mbuf_core.h +++ b/lib/mbuf/rte_mbuf_core.h @@ -504,6 +504,8 @@ extern "C" { #define RTE_MBUF_F_INDIRECT (1ULL << 62) /**< Indirect attached mbuf */ #define IND_ATTACHED_MBUF RTE_DEPRECATED(IND_ATTACHED_MBUF) RTE_MBUF_F_INDIRECT +#define RTE_MBUF_F_DYNFIELD2 (1ULL << 63) /**< dynfield2 mbuf field enabled */ + /** Alignment constraint of mbuf private area. */ #define RTE_MBUF_PRIV_ALIGN 8 @@ -579,13 +581,18 @@ struct rte_mbuf { RTE_MARKER cacheline0; void *buf_addr; /**< Virtual address of segment buffer. */ - /** - * Physical address of segment buffer. - * Force alignment to 8-bytes, so as to ensure we have the exact - * same mbuf cacheline0 layout for 32-bit and 64-bit. This makes - * working on vector drivers easier. - */ - rte_iova_t buf_iova __rte_aligned(sizeof(rte_iova_t)); + RTE_STD_C11 + union { + /** + * Physical address of segment buffer if IOVA mode is not VA. + * Force alignment to 8-bytes, so as to ensure we have the exact + * same mbuf cacheline0 layout for 32-bit and 64-bit. This makes + * working on vector drivers easier. + */ + rte_iova_t buf_iova __rte_aligned(sizeof(rte_iova_t)); + /* Reserved for dynamic field if IOVA mode is VA. */ + uint64_t dynfield2; + }; /* next 8 bytes are initialised on RX descriptor rearm */ RTE_MARKER64 rearm_data; @@ -803,6 +810,14 @@ struct rte_mbuf_ext_shared_info { #define RTE_MBUF_DIRECT(mb) \ (!((mb)->ol_flags & (RTE_MBUF_F_INDIRECT | RTE_MBUF_F_EXTERNAL))) +/** + * + * Retrurns TRUE if given mbuf has dynfield2 field enabled, or FALSE otherwise. + * + * dynfield2 field can be enabled if IOVA mode is configured as VA. + */ +#define RTE_MBUF_HAS_DYNFIELD2(mb) (!!((mb)->ol_flags & RTE_MBUF_F_DYNFIELD2)) + /** Uninitialized or unspecified port. */ #define RTE_MBUF_PORT_INVALID UINT16_MAX /** For backwards compatibility. */ diff --git a/lib/mbuf/rte_mbuf_dyn.c b/lib/mbuf/rte_mbuf_dyn.c index 4ae79383b5..7bfe50e0e2 100644 --- a/lib/mbuf/rte_mbuf_dyn.c +++ b/lib/mbuf/rte_mbuf_dyn.c @@ -127,7 +127,10 @@ init_shared_mem(void) * rte_mbuf_dynfield_copy(). */ memset(shm, 0, sizeof(*shm)); + mark_free(dynfield1); + if (rte_eal_iova_mode() == RTE_IOVA_VA) + mark_free(dynfield2); /* init free_flags */ for (mask = RTE_MBUF_F_FIRST_FREE; mask <= RTE_MBUF_F_LAST_FREE; mask <<= 1) -- 2.25.1