This function is too big to be put inline. The places it is used are only in special exception paths where a highly fragmented mbuf arrives at a device that can't handle it.
Signed-off-by: Stephen Hemminger <step...@networkplumber.org> --- lib/librte_mbuf/rte_mbuf.c | 40 ++++++++++++++++++++++++++++ lib/librte_mbuf/rte_mbuf.h | 40 ++-------------------------- lib/librte_mbuf/rte_mbuf_version.map | 6 +++++ 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c index 37718d49c148..922bce6f0f93 100644 --- a/lib/librte_mbuf/rte_mbuf.c +++ b/lib/librte_mbuf/rte_mbuf.c @@ -245,6 +245,46 @@ int rte_mbuf_check(const struct rte_mbuf *m, int is_header, return 0; } +/* convert multi-segment mbuf to single mbuf */ +int +rte_pktmbuf_linearize(struct rte_mbuf *mbuf) +{ + size_t seg_len, copy_len; + struct rte_mbuf *m; + struct rte_mbuf *m_next; + char *buffer; + + if (rte_pktmbuf_is_contiguous(mbuf)) + return 0; + + /* Extend first segment to the total packet length */ + copy_len = rte_pktmbuf_pkt_len(mbuf) - rte_pktmbuf_data_len(mbuf); + + if (unlikely(copy_len > rte_pktmbuf_tailroom(mbuf))) + return -1; + + buffer = rte_pktmbuf_mtod_offset(mbuf, char *, mbuf->data_len); + mbuf->data_len = (uint16_t)(mbuf->pkt_len); + + /* Append data from next segments to the first one */ + m = mbuf->next; + while (m != NULL) { + m_next = m->next; + + seg_len = rte_pktmbuf_data_len(m); + rte_memcpy(buffer, rte_pktmbuf_mtod(m, char *), seg_len); + buffer += seg_len; + + rte_pktmbuf_free_seg(m); + m = m_next; + } + + mbuf->next = NULL; + mbuf->nb_segs = 1; + + return 0; +} + /* dump a mbuf on console */ void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len) diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 98225ec80bf1..d25356b58cba 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -2412,44 +2412,8 @@ rte_validate_tx_offload(const struct rte_mbuf *m) * - 0, on success * - -1, on error */ -static inline int -rte_pktmbuf_linearize(struct rte_mbuf *mbuf) -{ - size_t seg_len, copy_len; - struct rte_mbuf *m; - struct rte_mbuf *m_next; - char *buffer; - - if (rte_pktmbuf_is_contiguous(mbuf)) - return 0; - - /* Extend first segment to the total packet length */ - copy_len = rte_pktmbuf_pkt_len(mbuf) - rte_pktmbuf_data_len(mbuf); - - if (unlikely(copy_len > rte_pktmbuf_tailroom(mbuf))) - return -1; - - buffer = rte_pktmbuf_mtod_offset(mbuf, char *, mbuf->data_len); - mbuf->data_len = (uint16_t)(mbuf->pkt_len); - - /* Append data from next segments to the first one */ - m = mbuf->next; - while (m != NULL) { - m_next = m->next; - - seg_len = rte_pktmbuf_data_len(m); - rte_memcpy(buffer, rte_pktmbuf_mtod(m, char *), seg_len); - buffer += seg_len; - - rte_pktmbuf_free_seg(m); - m = m_next; - } - - mbuf->next = NULL; - mbuf->nb_segs = 1; - - return 0; -} +int +rte_pktmbuf_linearize(struct rte_mbuf *mbuf); /** * Dump an mbuf structure to a file. diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map index 2662a37bf674..528681ba263a 100644 --- a/lib/librte_mbuf/rte_mbuf_version.map +++ b/lib/librte_mbuf/rte_mbuf_version.map @@ -46,6 +46,12 @@ DPDK_18.08 { rte_pktmbuf_pool_create_by_ops; } DPDK_16.11; +DPDK_19.11 { + global: + + rte_pktmbuf_linearize; +} DPDK_18.08; + EXPERIMENTAL { global: -- 2.20.1