DPDK 21.11.9
rte_mbuf.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation.
3 * Copyright 2014 6WIND S.A.
4 */
5
6#ifndef _RTE_MBUF_H_
7#define _RTE_MBUF_H_
8
34#include <stdint.h>
35#include <rte_compat.h>
36#include <rte_common.h>
37#include <rte_config.h>
38#include <rte_mempool.h>
39#include <rte_memory.h>
40#include <rte_prefetch.h>
42#include <rte_byteorder.h>
43#include <rte_mbuf_ptype.h>
44#include <rte_mbuf_core.h>
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
58const char *rte_get_rx_ol_flag_name(uint64_t mask);
59
72int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen);
73
84const char *rte_get_tx_ol_flag_name(uint64_t mask);
85
98int rte_get_tx_ol_flag_list(uint64_t mask, char *buf, size_t buflen);
99
110static inline void
112{
113 rte_prefetch0(&m->cacheline0);
114}
115
127static inline void
129{
130#if RTE_CACHE_LINE_SIZE == 64
131 rte_prefetch0(&m->cacheline1);
132#else
133 RTE_SET_USED(m);
134#endif
135}
136
137
138static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
139
148static inline rte_iova_t
150{
151 return mb->buf_iova + mb->data_off;
152}
153
166static inline rte_iova_t
168{
169 return mb->buf_iova + RTE_PKTMBUF_HEADROOM;
170}
171
180static inline struct rte_mbuf *
182{
183 return (struct rte_mbuf *)RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size);
184}
185
201static inline char *
203{
204 return (char *)mb + sizeof(*mb) + rte_pktmbuf_priv_size(mp);
205}
206
215static inline char *
217{
218 return rte_mbuf_buf_addr(mb, mb->pool) + RTE_PKTMBUF_HEADROOM;
219}
220
234static inline char *
236{
237 return rte_mbuf_buf_addr(md, md->pool);
238}
239
252static inline void *
254{
255 return RTE_PTR_ADD(m, sizeof(struct rte_mbuf));
256}
257
266 uint16_t mbuf_priv_size;
267 uint32_t flags;
268};
269
278static inline uint32_t
280{
281 struct rte_pktmbuf_pool_private *mbp_priv;
282
283 mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
284 return mbp_priv->flags;
285}
286
293#define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF (1 << 0)
294
302#define RTE_MBUF_HAS_PINNED_EXTBUF(mb) \
303 (rte_pktmbuf_priv_flags(mb->pool) & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF)
304
305#ifdef RTE_LIBRTE_MBUF_DEBUG
306
308#define __rte_mbuf_sanity_check(m, is_h) rte_mbuf_sanity_check(m, is_h)
309
310#else /* RTE_LIBRTE_MBUF_DEBUG */
311
313#define __rte_mbuf_sanity_check(m, is_h) do { } while (0)
314
315#endif /* RTE_LIBRTE_MBUF_DEBUG */
316
317#ifdef RTE_MBUF_REFCNT_ATOMIC
318
326static inline uint16_t
327rte_mbuf_refcnt_read(const struct rte_mbuf *m)
328{
329 return __atomic_load_n(&m->refcnt, __ATOMIC_RELAXED);
330}
331
339static inline void
340rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
341{
342 __atomic_store_n(&m->refcnt, new_value, __ATOMIC_RELAXED);
343}
344
345/* internal */
346static inline uint16_t
347__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
348{
349 return __atomic_add_fetch(&m->refcnt, (uint16_t)value,
350 __ATOMIC_ACQ_REL);
351}
352
362static inline uint16_t
363rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
364{
365 /*
366 * The atomic_add is an expensive operation, so we don't want to
367 * call it in the case where we know we are the unique holder of
368 * this mbuf (i.e. ref_cnt == 1). Otherwise, an atomic
369 * operation has to be used because concurrent accesses on the
370 * reference counter can occur.
371 */
372 if (likely(rte_mbuf_refcnt_read(m) == 1)) {
373 ++value;
374 rte_mbuf_refcnt_set(m, (uint16_t)value);
375 return (uint16_t)value;
376 }
377
378 return __rte_mbuf_refcnt_update(m, value);
379}
380
381#else /* ! RTE_MBUF_REFCNT_ATOMIC */
382
383/* internal */
384static inline uint16_t
385__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
386{
387 m->refcnt = (uint16_t)(m->refcnt + value);
388 return m->refcnt;
389}
390
394static inline uint16_t
395rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
396{
397 return __rte_mbuf_refcnt_update(m, value);
398}
399
403static inline uint16_t
405{
406 return m->refcnt;
407}
408
412static inline void
413rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
414{
415 m->refcnt = new_value;
416}
417
418#endif /* RTE_MBUF_REFCNT_ATOMIC */
419
428static inline uint16_t
430{
431 return __atomic_load_n(&shinfo->refcnt, __ATOMIC_RELAXED);
432}
433
442static inline void
444 uint16_t new_value)
445{
446 __atomic_store_n(&shinfo->refcnt, new_value, __ATOMIC_RELAXED);
447}
448
460static inline uint16_t
462 int16_t value)
463{
464 if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1)) {
465 ++value;
466 rte_mbuf_ext_refcnt_set(shinfo, (uint16_t)value);
467 return (uint16_t)value;
468 }
469
470 return __atomic_add_fetch(&shinfo->refcnt, (uint16_t)value,
471 __ATOMIC_ACQ_REL);
472}
473
475#define RTE_MBUF_PREFETCH_TO_FREE(m) do { \
476 if ((m) != NULL) \
477 rte_prefetch0(m); \
478} while (0)
479
480
493void
494rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
495
515int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
516 const char **reason);
517
530static __rte_always_inline void
532{
533 RTE_ASSERT(rte_mbuf_refcnt_read(m) == 1);
534 RTE_ASSERT(m->next == NULL);
535 RTE_ASSERT(m->nb_segs == 1);
537}
538
540#define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_sanity_check(m)
541
561static inline struct rte_mbuf *rte_mbuf_raw_alloc(struct rte_mempool *mp)
562{
563 struct rte_mbuf *m;
564
565 if (rte_mempool_get(mp, (void **)&m) < 0)
566 return NULL;
568 return m;
569}
570
585static __rte_always_inline void
587{
588 RTE_ASSERT(!RTE_MBUF_CLONED(m) &&
591 rte_mempool_put(m->pool, m);
592}
593
616void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
617 void *m, unsigned i);
618
639void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
640
674struct rte_mempool *
675rte_pktmbuf_pool_create(const char *name, unsigned n,
676 unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
677 int socket_id);
678
715struct rte_mempool *
716rte_pktmbuf_pool_create_by_ops(const char *name, unsigned int n,
717 unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
718 int socket_id, const char *ops_name);
719
722 void *buf_ptr;
724 size_t buf_len;
725 uint16_t elt_size;
726};
727
768__rte_experimental
769struct rte_mempool *
770rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n,
771 unsigned int cache_size, uint16_t priv_size,
772 uint16_t data_room_size, int socket_id,
773 const struct rte_pktmbuf_extmem *ext_mem,
774 unsigned int ext_num);
775
787static inline uint16_t
789{
790 struct rte_pktmbuf_pool_private *mbp_priv;
791
792 mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
793 return mbp_priv->mbuf_data_room_size;
794}
795
808static inline uint16_t
810{
811 struct rte_pktmbuf_pool_private *mbp_priv;
812
813 mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
814 return mbp_priv->mbuf_priv_size;
815}
816
825static inline void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
826{
827 m->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM,
828 (uint16_t)m->buf_len);
829}
830
839static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
840{
841 m->next = NULL;
842 m->pkt_len = 0;
843 m->tx_offload = 0;
844 m->vlan_tci = 0;
845 m->vlan_tci_outer = 0;
846 m->nb_segs = 1;
848
850 m->packet_type = 0;
852
853 m->data_len = 0;
855}
856
870static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
871{
872 struct rte_mbuf *m;
873 if ((m = rte_mbuf_raw_alloc(mp)) != NULL)
875 return m;
876}
877
892static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool,
893 struct rte_mbuf **mbufs, unsigned count)
894{
895 unsigned idx = 0;
896 int rc;
897
898 rc = rte_mempool_get_bulk(pool, (void **)mbufs, count);
899 if (unlikely(rc))
900 return rc;
901
902 /* To understand duff's device on loop unwinding optimization, see
903 * https://en.wikipedia.org/wiki/Duff's_device.
904 * Here while() loop is used rather than do() while{} to avoid extra
905 * check if count is zero.
906 */
907 switch (count % 4) {
908 case 0:
909 while (idx != count) {
910 __rte_mbuf_raw_sanity_check(mbufs[idx]);
911 rte_pktmbuf_reset(mbufs[idx]);
912 idx++;
913 /* fall-through */
914 case 3:
915 __rte_mbuf_raw_sanity_check(mbufs[idx]);
916 rte_pktmbuf_reset(mbufs[idx]);
917 idx++;
918 /* fall-through */
919 case 2:
920 __rte_mbuf_raw_sanity_check(mbufs[idx]);
921 rte_pktmbuf_reset(mbufs[idx]);
922 idx++;
923 /* fall-through */
924 case 1:
925 __rte_mbuf_raw_sanity_check(mbufs[idx]);
926 rte_pktmbuf_reset(mbufs[idx]);
927 idx++;
928 /* fall-through */
929 }
930 }
931 return 0;
932}
933
966static inline struct rte_mbuf_ext_shared_info *
967rte_pktmbuf_ext_shinfo_init_helper(void *buf_addr, uint16_t *buf_len,
969{
970 struct rte_mbuf_ext_shared_info *shinfo;
971 void *buf_end = RTE_PTR_ADD(buf_addr, *buf_len);
972 void *addr;
973
974 addr = RTE_PTR_ALIGN_FLOOR(RTE_PTR_SUB(buf_end, sizeof(*shinfo)),
975 sizeof(uintptr_t));
976 if (addr <= buf_addr)
977 return NULL;
978
979 shinfo = (struct rte_mbuf_ext_shared_info *)addr;
980 shinfo->free_cb = free_cb;
981 shinfo->fcb_opaque = fcb_opaque;
982 rte_mbuf_ext_refcnt_set(shinfo, 1);
983
984 *buf_len = (uint16_t)RTE_PTR_DIFF(shinfo, buf_addr);
985 return shinfo;
986}
987
1048static inline void
1049rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
1050 rte_iova_t buf_iova, uint16_t buf_len,
1051 struct rte_mbuf_ext_shared_info *shinfo)
1052{
1053 /* mbuf should not be read-only */
1054 RTE_ASSERT(RTE_MBUF_DIRECT(m) && rte_mbuf_refcnt_read(m) == 1);
1055 RTE_ASSERT(shinfo->free_cb != NULL);
1056
1057 m->buf_addr = buf_addr;
1058 m->buf_iova = buf_iova;
1059 m->buf_len = buf_len;
1060
1061 m->data_len = 0;
1062 m->data_off = 0;
1063
1065 m->shinfo = shinfo;
1066}
1067
1075#define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
1076
1085static inline void
1086rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
1087{
1088 memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1));
1089}
1090
1091/* internal */
1092static inline void
1093__rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
1094{
1095 mdst->port = msrc->port;
1096 mdst->vlan_tci = msrc->vlan_tci;
1097 mdst->vlan_tci_outer = msrc->vlan_tci_outer;
1098 mdst->tx_offload = msrc->tx_offload;
1099 mdst->hash = msrc->hash;
1100 mdst->packet_type = msrc->packet_type;
1101 rte_mbuf_dynfield_copy(mdst, msrc);
1102}
1103
1125static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
1126{
1127 RTE_ASSERT(RTE_MBUF_DIRECT(mi) &&
1128 rte_mbuf_refcnt_read(mi) == 1);
1129
1130 if (RTE_MBUF_HAS_EXTBUF(m)) {
1132 mi->ol_flags = m->ol_flags;
1133 mi->shinfo = m->shinfo;
1134 } else {
1135 /* if m is not direct, get the mbuf that embeds the data */
1137 mi->priv_size = m->priv_size;
1139 }
1140
1141 __rte_pktmbuf_copy_hdr(mi, m);
1142
1143 mi->data_off = m->data_off;
1144 mi->data_len = m->data_len;
1145 mi->buf_iova = m->buf_iova;
1146 mi->buf_addr = m->buf_addr;
1147 mi->buf_len = m->buf_len;
1148
1149 mi->next = NULL;
1150 mi->pkt_len = mi->data_len;
1151 mi->nb_segs = 1;
1152
1155}
1156
1164static inline void
1165__rte_pktmbuf_free_extbuf(struct rte_mbuf *m)
1166{
1167 RTE_ASSERT(RTE_MBUF_HAS_EXTBUF(m));
1168 RTE_ASSERT(m->shinfo != NULL);
1169
1170 if (rte_mbuf_ext_refcnt_update(m->shinfo, -1) == 0)
1172}
1173
1180static inline void
1181__rte_pktmbuf_free_direct(struct rte_mbuf *m)
1182{
1183 struct rte_mbuf *md;
1184
1185 RTE_ASSERT(RTE_MBUF_CLONED(m));
1186
1187 md = rte_mbuf_from_indirect(m);
1188
1189 if (rte_mbuf_refcnt_update(md, -1) == 0) {
1190 md->next = NULL;
1191 md->nb_segs = 1;
1192 rte_mbuf_refcnt_set(md, 1);
1194 }
1195}
1196
1215static inline void rte_pktmbuf_detach(struct rte_mbuf *m)
1216{
1217 struct rte_mempool *mp = m->pool;
1218 uint32_t mbuf_size, buf_len;
1219 uint16_t priv_size;
1220
1221 if (RTE_MBUF_HAS_EXTBUF(m)) {
1222 /*
1223 * The mbuf has the external attached buffer,
1224 * we should check the type of the memory pool where
1225 * the mbuf was allocated from to detect the pinned
1226 * external buffer.
1227 */
1228 uint32_t flags = rte_pktmbuf_priv_flags(mp);
1229
1231 /*
1232 * The pinned external buffer should not be
1233 * detached from its backing mbuf, just exit.
1234 */
1235 return;
1236 }
1237 __rte_pktmbuf_free_extbuf(m);
1238 } else {
1239 __rte_pktmbuf_free_direct(m);
1240 }
1241 priv_size = rte_pktmbuf_priv_size(mp);
1242 mbuf_size = (uint32_t)(sizeof(struct rte_mbuf) + priv_size);
1243 buf_len = rte_pktmbuf_data_room_size(mp);
1244
1245 m->priv_size = priv_size;
1246 m->buf_addr = (char *)m + mbuf_size;
1247 m->buf_iova = rte_mempool_virt2iova(m) + mbuf_size;
1248 m->buf_len = (uint16_t)buf_len;
1250 m->data_len = 0;
1251 m->ol_flags = 0;
1252}
1253
1267static inline int __rte_pktmbuf_pinned_extbuf_decref(struct rte_mbuf *m)
1268{
1269 struct rte_mbuf_ext_shared_info *shinfo;
1270
1271 /* Clear flags, mbuf is being freed. */
1273 shinfo = m->shinfo;
1274
1275 /* Optimize for performance - do not dec/reinit */
1276 if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1))
1277 return 0;
1278
1279 /*
1280 * Direct usage of add primitive to avoid
1281 * duplication of comparing with one.
1282 */
1283 if (likely(__atomic_add_fetch(&shinfo->refcnt, (uint16_t)-1,
1284 __ATOMIC_ACQ_REL)))
1285 return 1;
1286
1287 /* Reinitialize counter before mbuf freeing. */
1288 rte_mbuf_ext_refcnt_set(shinfo, 1);
1289 return 0;
1290}
1291
1306static __rte_always_inline struct rte_mbuf *
1308{
1310
1311 if (likely(rte_mbuf_refcnt_read(m) == 1)) {
1312
1313 if (!RTE_MBUF_DIRECT(m)) {
1315 if (RTE_MBUF_HAS_EXTBUF(m) &&
1317 __rte_pktmbuf_pinned_extbuf_decref(m))
1318 return NULL;
1319 }
1320
1321 if (m->next != NULL)
1322 m->next = NULL;
1323 if (m->nb_segs != 1)
1324 m->nb_segs = 1;
1325
1326 return m;
1327
1328 } else if (__rte_mbuf_refcnt_update(m, -1) == 0) {
1329
1330 if (!RTE_MBUF_DIRECT(m)) {
1332 if (RTE_MBUF_HAS_EXTBUF(m) &&
1334 __rte_pktmbuf_pinned_extbuf_decref(m))
1335 return NULL;
1336 }
1337
1338 if (m->next != NULL)
1339 m->next = NULL;
1340 if (m->nb_segs != 1)
1341 m->nb_segs = 1;
1342 rte_mbuf_refcnt_set(m, 1);
1343
1344 return m;
1345 }
1346 return NULL;
1347}
1348
1358static __rte_always_inline void
1360{
1362 if (likely(m != NULL))
1364}
1365
1375static inline void rte_pktmbuf_free(struct rte_mbuf *m)
1376{
1377 struct rte_mbuf *m_next;
1378
1379 if (m != NULL)
1381
1382 while (m != NULL) {
1383 m_next = m->next;
1385 m = m_next;
1386 }
1387}
1388
1401void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count);
1402
1420struct rte_mbuf *
1422
1444struct rte_mbuf *
1445rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
1446 uint32_t offset, uint32_t length);
1447
1459static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
1460{
1462
1463 do {
1465 } while ((m = m->next) != NULL);
1466}
1467
1476static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
1477{
1479 return m->data_off;
1480}
1481
1490static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
1491{
1493 return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) -
1494 m->data_len);
1495}
1496
1505static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
1506{
1508 while (m->next != NULL)
1509 m = m->next;
1510 return m;
1511}
1512
1521#define rte_pktmbuf_pkt_len(m) ((m)->pkt_len)
1522
1531#define rte_pktmbuf_data_len(m) ((m)->data_len)
1532
1548static inline char *rte_pktmbuf_prepend(struct rte_mbuf *m,
1549 uint16_t len)
1550{
1552
1553 if (unlikely(len > rte_pktmbuf_headroom(m)))
1554 return NULL;
1555
1556 /* NB: elaborating the subtraction like this instead of using
1557 * -= allows us to ensure the result type is uint16_t
1558 * avoiding compiler warnings on gcc 8.1 at least */
1559 m->data_off = (uint16_t)(m->data_off - len);
1560 m->data_len = (uint16_t)(m->data_len + len);
1561 m->pkt_len = (m->pkt_len + len);
1562
1563 return (char *)m->buf_addr + m->data_off;
1564}
1565
1581static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
1582{
1583 void *tail;
1584 struct rte_mbuf *m_last;
1585
1587
1588 m_last = rte_pktmbuf_lastseg(m);
1589 if (unlikely(len > rte_pktmbuf_tailroom(m_last)))
1590 return NULL;
1591
1592 tail = (char *)m_last->buf_addr + m_last->data_off + m_last->data_len;
1593 m_last->data_len = (uint16_t)(m_last->data_len + len);
1594 m->pkt_len = (m->pkt_len + len);
1595 return (char*) tail;
1596}
1597
1612static inline char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
1613{
1615
1616 if (unlikely(len > m->data_len))
1617 return NULL;
1618
1619 /* NB: elaborating the addition like this instead of using
1620 * += allows us to ensure the result type is uint16_t
1621 * avoiding compiler warnings on gcc 8.1 at least */
1622 m->data_len = (uint16_t)(m->data_len - len);
1623 m->data_off = (uint16_t)(m->data_off + len);
1624 m->pkt_len = (m->pkt_len - len);
1625 return (char *)m->buf_addr + m->data_off;
1626}
1627
1642static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
1643{
1644 struct rte_mbuf *m_last;
1645
1647
1648 m_last = rte_pktmbuf_lastseg(m);
1649 if (unlikely(len > m_last->data_len))
1650 return -1;
1651
1652 m_last->data_len = (uint16_t)(m_last->data_len - len);
1653 m->pkt_len = (m->pkt_len - len);
1654 return 0;
1655}
1656
1666static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
1667{
1669 return m->nb_segs == 1;
1670}
1671
1675const void *__rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off,
1676 uint32_t len, void *buf);
1677
1698static inline const void *rte_pktmbuf_read(const struct rte_mbuf *m,
1699 uint32_t off, uint32_t len, void *buf)
1700{
1701 if (likely(off + len <= rte_pktmbuf_data_len(m)))
1702 return rte_pktmbuf_mtod_offset(m, char *, off);
1703 else
1704 return __rte_pktmbuf_read(m, off, len, buf);
1705}
1706
1723static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
1724{
1725 struct rte_mbuf *cur_tail;
1726
1727 /* Check for number-of-segments-overflow */
1728 if (head->nb_segs + tail->nb_segs > RTE_MBUF_MAX_NB_SEGS)
1729 return -EOVERFLOW;
1730
1731 /* Chain 'tail' onto the old tail */
1732 cur_tail = rte_pktmbuf_lastseg(head);
1733 cur_tail->next = tail;
1734
1735 /* accumulate number of segments and total length.
1736 * NB: elaborating the addition like this instead of using
1737 * -= allows us to ensure the result type is uint16_t
1738 * avoiding compiler warnings on gcc 8.1 at least */
1739 head->nb_segs = (uint16_t)(head->nb_segs + tail->nb_segs);
1740 head->pkt_len += tail->pkt_len;
1741
1742 /* pkt_len is only set in the head */
1743 tail->pkt_len = tail->data_len;
1744
1745 return 0;
1746}
1747
1769static __rte_always_inline uint64_t
1770rte_mbuf_tx_offload(uint64_t il2, uint64_t il3, uint64_t il4, uint64_t tso,
1771 uint64_t ol3, uint64_t ol2, uint64_t unused)
1772{
1773 return il2 << RTE_MBUF_L2_LEN_OFS |
1774 il3 << RTE_MBUF_L3_LEN_OFS |
1775 il4 << RTE_MBUF_L4_LEN_OFS |
1776 tso << RTE_MBUF_TSO_SEGSZ_OFS |
1777 ol3 << RTE_MBUF_OUTL3_LEN_OFS |
1778 ol2 << RTE_MBUF_OUTL2_LEN_OFS |
1779 unused << RTE_MBUF_TXOFLD_UNUSED_OFS;
1780}
1781
1792static inline int
1794{
1795 uint64_t ol_flags = m->ol_flags;
1796
1797 /* Does packet set any of available offloads? */
1799 return 0;
1800
1801 /* IP checksum can be counted only for IPv4 packet */
1803 return -EINVAL;
1804
1805 /* IP type not set when required */
1808 return -EINVAL;
1809
1810 /* Check requirements for TSO packet */
1812 if ((m->tso_segsz == 0) ||
1815 return -EINVAL;
1816
1817 /* RTE_MBUF_F_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */
1820 return -EINVAL;
1821
1822 return 0;
1823}
1824
1828int __rte_pktmbuf_linearize(struct rte_mbuf *mbuf);
1829
1842static inline int
1844{
1845 if (rte_pktmbuf_is_contiguous(mbuf))
1846 return 0;
1847 return __rte_pktmbuf_linearize(mbuf);
1848}
1849
1864void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
1865
1869static inline uint32_t
1871{
1872 return m->hash.sched.queue_id;
1873}
1874
1878static inline uint8_t
1880{
1881 return m->hash.sched.traffic_class;
1882}
1883
1887static inline uint8_t
1889{
1890 return m->hash.sched.color;
1891}
1892
1905static inline void
1906rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
1907 uint8_t *traffic_class,
1908 uint8_t *color)
1909{
1910 struct rte_mbuf_sched sched = m->hash.sched;
1911
1912 *queue_id = sched.queue_id;
1914 *color = sched.color;
1915}
1916
1920static inline void
1922{
1923 m->hash.sched.queue_id = queue_id;
1924}
1925
1929static inline void
1931{
1932 m->hash.sched.traffic_class = traffic_class;
1933}
1934
1938static inline void
1940{
1941 m->hash.sched.color = color;
1942}
1943
1956static inline void
1958 uint8_t traffic_class,
1959 uint8_t color)
1960{
1961 m->hash.sched = (struct rte_mbuf_sched){
1962 .queue_id = queue_id,
1963 .traffic_class = traffic_class,
1964 .color = color,
1965 .reserved = 0,
1966 };
1967}
1968
1969#ifdef __cplusplus
1970}
1971#endif
1972
1973#endif /* _RTE_MBUF_H_ */
#define likely(x)
#define unlikely(x)
#define RTE_PTR_ALIGN_FLOOR(ptr, align)
Definition: rte_common.h:297
#define RTE_MIN(a, b)
Definition: rte_common.h:593
#define RTE_PTR_DIFF(ptr1, ptr2)
Definition: rte_common.h:280
#define RTE_PTR_SUB(ptr, x)
Definition: rte_common.h:273
uint64_t rte_iova_t
Definition: rte_common.h:438
#define RTE_PTR_ADD(ptr, x)
Definition: rte_common.h:268
#define RTE_SET_USED(x)
Definition: rte_common.h:138
#define __rte_unused
Definition: rte_common.h:123
#define __rte_always_inline
Definition: rte_common.h:233
static __rte_always_inline void rte_pktmbuf_free_seg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1359
int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen)
static void rte_mbuf_prefetch_part2(struct rte_mbuf *m)
Definition: rte_mbuf.h:128
static __rte_always_inline uint64_t rte_mbuf_tx_offload(uint64_t il2, uint64_t il3, uint64_t il4, uint64_t tso, uint64_t ol3, uint64_t ol2, uint64_t unused)
Definition: rte_mbuf.h:1770
static void rte_pktmbuf_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:1375
static rte_iova_t rte_mbuf_data_iova_default(const struct rte_mbuf *mb)
Definition: rte_mbuf.h:167
static rte_iova_t rte_mbuf_data_iova(const struct rte_mbuf *mb)
Definition: rte_mbuf.h:149
static uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1490
int rte_get_tx_ol_flag_list(uint64_t mask, char *buf, size_t buflen)
struct rte_mbuf * rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp)
#define rte_pktmbuf_data_len(m)
Definition: rte_mbuf.h:1531
static uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1476
static uint32_t rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1870
static void rte_mbuf_prefetch_part1(struct rte_mbuf *m)
Definition: rte_mbuf.h:111
static char * rte_pktmbuf_prepend(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1548
static char * rte_mbuf_data_addr_default(struct rte_mbuf *mb)
Definition: rte_mbuf.h:216
struct rte_mempool * rte_pktmbuf_pool_create_by_ops(const char *name, unsigned int n, unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size, int socket_id, const char *ops_name)
static void rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id, uint8_t traffic_class, uint8_t color)
Definition: rte_mbuf.h:1957
static void rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
Definition: rte_mbuf.h:1086
static char * rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1612
static void rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
Definition: rte_mbuf.h:1939
static int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1666
int rte_mbuf_check(const struct rte_mbuf *m, int is_header, const char **reason)
static char * rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1581
const char * rte_get_tx_ol_flag_name(uint64_t mask)
static void rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id, uint8_t *traffic_class, uint8_t *color)
Definition: rte_mbuf.h:1906
static void rte_pktmbuf_detach(struct rte_mbuf *m)
Definition: rte_mbuf.h:1215
static char * rte_mbuf_to_baddr(struct rte_mbuf *md)
Definition: rte_mbuf.h:235
static struct rte_mbuf_ext_shared_info * rte_pktmbuf_ext_shinfo_init_helper(void *buf_addr, uint16_t *buf_len, rte_mbuf_extbuf_free_callback_t free_cb, void *fcb_opaque)
Definition: rte_mbuf.h:967
static uint32_t rte_pktmbuf_priv_flags(struct rte_mempool *mp)
Definition: rte_mbuf.h:279
static void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
Definition: rte_mbuf.h:1459
void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, void *m, unsigned i)
static void rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
Definition: rte_mbuf.h:413
static struct rte_mbuf * rte_mbuf_raw_alloc(struct rte_mempool *mp)
Definition: rte_mbuf.h:561
static uint16_t rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo, int16_t value)
Definition: rte_mbuf.h:461
struct rte_mempool * rte_pktmbuf_pool_create(const char *name, unsigned n, unsigned cache_size, uint16_t priv_size, uint16_t data_room_size, int socket_id)
void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count)
void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len)
#define __rte_mbuf_sanity_check(m, is_h)
Definition: rte_mbuf.h:313
static const void * rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off, uint32_t len, void *buf)
Definition: rte_mbuf.h:1698
static uint16_t rte_mbuf_refcnt_read(const struct rte_mbuf *m)
Definition: rte_mbuf.h:404
static int rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
Definition: rte_mbuf.h:1843
__rte_experimental struct rte_mempool * rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n, unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size, int socket_id, const struct rte_pktmbuf_extmem *ext_mem, unsigned int ext_num)
static __rte_always_inline void rte_mbuf_raw_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:586
struct rte_mbuf * rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp, uint32_t offset, uint32_t length)
static struct rte_mbuf * rte_pktmbuf_alloc(struct rte_mempool *mp)
Definition: rte_mbuf.h:870
static char * rte_mbuf_buf_addr(struct rte_mbuf *mb, struct rte_mempool *mp)
Definition: rte_mbuf.h:202
static void rte_mbuf_ext_refcnt_set(struct rte_mbuf_ext_shared_info *shinfo, uint16_t new_value)
Definition: rte_mbuf.h:443
void rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
static uint8_t rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1879
static uint16_t rte_mbuf_ext_refcnt_read(const struct rte_mbuf_ext_shared_info *shinfo)
Definition: rte_mbuf.h:429
static uint16_t rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
Definition: rte_mbuf.h:395
static int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1642
#define RTE_MBUF_HAS_PINNED_EXTBUF(mb)
Definition: rte_mbuf.h:302
static void rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
Definition: rte_mbuf.h:1921
static uint16_t rte_pktmbuf_data_room_size(struct rte_mempool *mp)
Definition: rte_mbuf.h:788
static struct rte_mbuf * rte_pktmbuf_lastseg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1505
static void rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
Definition: rte_mbuf.h:1930
#define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF
Definition: rte_mbuf.h:293
static __rte_always_inline struct rte_mbuf * rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1307
static int rte_validate_tx_offload(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1793
static void rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr, rte_iova_t buf_iova, uint16_t buf_len, struct rte_mbuf_ext_shared_info *shinfo)
Definition: rte_mbuf.h:1049
static struct rte_mbuf * rte_mbuf_from_indirect(struct rte_mbuf *mi)
Definition: rte_mbuf.h:181
static int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool, struct rte_mbuf **mbufs, unsigned count)
Definition: rte_mbuf.h:892
static void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
Definition: rte_mbuf.h:825
static void * rte_mbuf_to_priv(struct rte_mbuf *m)
Definition: rte_mbuf.h:253
static uint8_t rte_mbuf_sched_color_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1888
static int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
Definition: rte_mbuf.h:1723
static __rte_always_inline void __rte_mbuf_raw_sanity_check(__rte_unused const struct rte_mbuf *m)
Definition: rte_mbuf.h:531
const char * rte_get_rx_ol_flag_name(uint64_t mask)
void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
static uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp)
Definition: rte_mbuf.h:809
static void rte_pktmbuf_reset(struct rte_mbuf *m)
Definition: rte_mbuf.h:839
static void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
Definition: rte_mbuf.h:1125
#define RTE_MBUF_F_TX_OUTER_IP_CKSUM
#define RTE_MBUF_F_EXTERNAL
#define RTE_MBUF_F_TX_IP_CKSUM
#define RTE_MBUF_MAX_NB_SEGS
#define RTE_MBUF_F_TX_TCP_SEG
#define RTE_MBUF_F_TX_L4_MASK
#define RTE_MBUF_F_TX_OUTER_IPV4
#define RTE_MBUF_HAS_EXTBUF(mb)
#define RTE_MBUF_F_TX_OFFLOAD_MASK
#define RTE_MBUF_CLONED(mb)
#define RTE_MBUF_DIRECT(mb)
#define RTE_MBUF_F_TX_IPV4
void(* rte_mbuf_extbuf_free_callback_t)(void *addr, void *opaque)
#define rte_pktmbuf_mtod_offset(m, t, o)
#define RTE_MBUF_F_TX_IPV6
#define RTE_MBUF_F_INDIRECT
#define RTE_MBUF_PORT_INVALID
static __rte_always_inline int rte_mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned int n)
Definition: rte_mempool.h:1580
static rte_iova_t rte_mempool_virt2iova(const void *elt)
Definition: rte_mempool.h:1734
static __rte_always_inline int rte_mempool_get(struct rte_mempool *mp, void **obj_p)
Definition: rte_mempool.h:1609
static __rte_always_inline void rte_mempool_put(struct rte_mempool *mp, void *obj)
Definition: rte_mempool.h:1444
static void * rte_mempool_get_priv(struct rte_mempool *mp)
Definition: rte_mempool.h:1762
static void rte_prefetch0(const volatile void *p)
rte_mbuf_extbuf_free_callback_t free_cb
uint32_t queue_id
uint8_t traffic_class
uint64_t ol_flags
uint16_t nb_segs
uint16_t vlan_tci
uint16_t priv_size
uint32_t pkt_len
uint16_t buf_len
struct rte_mbuf_ext_shared_info * shinfo
uint32_t packet_type
uint16_t port
void * buf_addr
struct rte_mempool * pool
uint32_t dynfield1[9]
uint16_t vlan_tci_outer
struct rte_mbuf * next
uint64_t tx_offload
uint16_t data_len
uint64_t tso_segsz
uint16_t refcnt
char name[RTE_MEMPOOL_NAMESIZE]
Definition: rte_mempool.h:213
uint32_t cache_size
Definition: rte_mempool.h:224
unsigned int flags
Definition: rte_mempool.h:221
uint16_t elt_size
Definition: rte_mbuf.h:725
rte_iova_t buf_iova
Definition: rte_mbuf.h:723
uint16_t mbuf_data_room_size
Definition: rte_mbuf.h:265