Cloning mbufs requires allocations and iteration and therefore should not be an inline.
Signed-off-by: Stephen Hemminger <step...@networkplumber.org> --- lib/librte_mbuf/rte_mbuf.c | 39 ++++++++++++++++++++++++++++ lib/librte_mbuf/rte_mbuf.h | 38 ++------------------------- lib/librte_mbuf/rte_mbuf_version.map | 1 + 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c index 922bce6f0f93..12d0258a120d 100644 --- a/lib/librte_mbuf/rte_mbuf.c +++ b/lib/librte_mbuf/rte_mbuf.c @@ -245,6 +245,45 @@ int rte_mbuf_check(const struct rte_mbuf *m, int is_header, return 0; } +/* Creates a shallow copy of mbuf */ +struct rte_mbuf * +rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp) +{ + struct rte_mbuf *mc, *mi, **prev; + uint32_t pktlen; + uint16_t nseg; + + mc = rte_pktmbuf_alloc(mp); + if (unlikely(mc == NULL)) + return NULL; + + mi = mc; + prev = &mi->next; + pktlen = md->pkt_len; + nseg = 0; + + do { + nseg++; + rte_pktmbuf_attach(mi, md); + *prev = mi; + prev = &mi->next; + } while ((md = md->next) != NULL && + (mi = rte_pktmbuf_alloc(mp)) != NULL); + + *prev = NULL; + mc->nb_segs = nseg; + mc->pkt_len = pktlen; + + /* Allocation of new indirect segment failed */ + if (unlikely(mi == NULL)) { + rte_pktmbuf_free(mc); + return NULL; + } + + __rte_mbuf_sanity_check(mc, 1); + return mc; +} + /* convert multi-segment mbuf to single mbuf */ int rte_pktmbuf_linearize(struct rte_mbuf *mbuf) diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index d25356b58cba..a6e78e4ea7a6 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -1924,42 +1924,8 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m) * - The pointer to the new "clone" mbuf on success. * - NULL if allocation fails. */ -static inline struct rte_mbuf *rte_pktmbuf_clone(struct rte_mbuf *md, - struct rte_mempool *mp) -{ - struct rte_mbuf *mc, *mi, **prev; - uint32_t pktlen; - uint16_t nseg; - - if (unlikely ((mc = rte_pktmbuf_alloc(mp)) == NULL)) - return NULL; - - mi = mc; - prev = &mi->next; - pktlen = md->pkt_len; - nseg = 0; - - do { - nseg++; - rte_pktmbuf_attach(mi, md); - *prev = mi; - prev = &mi->next; - } while ((md = md->next) != NULL && - (mi = rte_pktmbuf_alloc(mp)) != NULL); - - *prev = NULL; - mc->nb_segs = nseg; - mc->pkt_len = pktlen; - - /* Allocation of new indirect segment failed */ - if (unlikely (mi == NULL)) { - rte_pktmbuf_free(mc); - return NULL; - } - - __rte_mbuf_sanity_check(mc, 1); - return mc; -} +struct rte_mbuf * +rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp); /** * Adds given value to the refcnt of all packet mbuf segments. diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map index 528681ba263a..aeec3f90f3fe 100644 --- a/lib/librte_mbuf/rte_mbuf_version.map +++ b/lib/librte_mbuf/rte_mbuf_version.map @@ -49,6 +49,7 @@ DPDK_18.08 { DPDK_19.11 { global: + rte_pktmbuf_clone; rte_pktmbuf_linearize; } DPDK_18.08; -- 2.20.1