DPDK 26.11.0-rc1
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 <stdbool.h>
35#include <stdint.h>
36
37#include <rte_common.h>
38#include <rte_config.h>
39#include <rte_mempool.h>
40#include <rte_prefetch.h>
42#include <rte_mbuf_ptype.h>
43#include <rte_mbuf_core.h>
44#include <rte_mbuf_history.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);
114}
115
127static inline void
129{
130#if RTE_CACHE_LINE_SIZE == 64
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#if RTE_IOVA_IN_MBUF
152 return m->buf_iova;
153#else
154 return (rte_iova_t)m->buf_addr;
155#endif
156}
157
166static inline void
168{
169#if RTE_IOVA_IN_MBUF
170 m->buf_iova = iova;
171#else
172 RTE_SET_USED(m);
173 RTE_SET_USED(iova);
174#endif
175}
176
185static inline rte_iova_t
187{
188 return rte_mbuf_iova_get(mb) + mb->data_off;
189}
190
203static inline rte_iova_t
205{
206 return rte_mbuf_iova_get(mb) + RTE_PKTMBUF_HEADROOM;
207}
208
217static inline struct rte_mbuf *
219{
220 RTE_ASSERT(mi != NULL);
221 return (struct rte_mbuf *)RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size);
222}
223
239static inline char *
241{
242 return (char *)mb + sizeof(*mb) + rte_pktmbuf_priv_size(mp);
243}
244
253static inline char *
255{
256 return rte_mbuf_buf_addr(mb, mb->pool) + RTE_PKTMBUF_HEADROOM;
257}
258
272static inline char *
274{
275 return rte_mbuf_buf_addr(md, md->pool);
276}
277
290static inline void *
292{
293 RTE_ASSERT(m != NULL);
294 __rte_assume(m != NULL);
295 return RTE_PTR_ADD(m, sizeof(struct rte_mbuf));
296}
297
306 uint16_t mbuf_priv_size;
307 uint32_t flags;
308};
309
318static inline uint32_t
320{
321 struct rte_pktmbuf_pool_private *mbp_priv;
322
323 mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
324 return mbp_priv->flags;
325}
326
333#define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF (1 << 0)
334
342#define RTE_MBUF_HAS_PINNED_EXTBUF(mb) \
343 (rte_pktmbuf_priv_flags(mb->pool) & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF)
344
345#if defined RTE_LIBRTE_MBUF_DEBUG || defined __DOXYGEN__
346
348#define __rte_mbuf_raw_sanity_check_mp(m, mp) rte_mbuf_raw_sanity_check(m, mp)
350#define __rte_mbuf_sanity_check(m, is_h) rte_mbuf_sanity_check(m, is_h)
351
352#else /* !RTE_LIBRTE_MBUF_DEBUG */
353
354#define __rte_mbuf_raw_sanity_check_mp(m, mp) do { } while (0)
355#define __rte_mbuf_sanity_check(m, is_h) do { } while (0)
356
357#endif /* RTE_LIBRTE_MBUF_DEBUG */
358
359#ifdef RTE_MBUF_REFCNT_ATOMIC
360
368static inline uint16_t
369rte_mbuf_refcnt_read(const struct rte_mbuf *m)
370{
371 return rte_atomic_load_explicit(&m->refcnt, rte_memory_order_relaxed);
372}
373
381static inline void
382rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
383{
384 rte_atomic_store_explicit(&m->refcnt, new_value, rte_memory_order_relaxed);
385}
386
387/* internal */
388static inline uint16_t
389__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
390{
391 return rte_atomic_fetch_add_explicit(&m->refcnt, value,
392 rte_memory_order_acq_rel) + value;
393}
394
404static inline uint16_t
405rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
406{
407 /*
408 * The atomic_add is an expensive operation, so we don't want to
409 * call it in the case where we know we are the unique holder of
410 * this mbuf (i.e. ref_cnt == 1). Otherwise, an atomic
411 * operation has to be used because concurrent accesses on the
412 * reference counter can occur.
413 */
414 if (likely(rte_mbuf_refcnt_read(m) == 1)) {
415 ++value;
416 rte_mbuf_refcnt_set(m, (uint16_t)value);
417 return (uint16_t)value;
418 }
419
420 return __rte_mbuf_refcnt_update(m, value);
421}
422
423#else /* ! RTE_MBUF_REFCNT_ATOMIC */
424
425/* internal */
426static inline uint16_t
427__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
428{
429 m->refcnt = (uint16_t)(m->refcnt + value);
430 return m->refcnt;
431}
432
436static inline uint16_t
437rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
438{
439 return __rte_mbuf_refcnt_update(m, value);
440}
441
445static inline uint16_t
447{
448 return m->refcnt;
449}
450
454static inline void
455rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
456{
457 m->refcnt = new_value;
458}
459
460#endif /* RTE_MBUF_REFCNT_ATOMIC */
461
470static inline uint16_t
472{
473 return rte_atomic_load_explicit(&shinfo->refcnt, rte_memory_order_relaxed);
474}
475
484static inline void
486 uint16_t new_value)
487{
488 rte_atomic_store_explicit(&shinfo->refcnt, new_value, rte_memory_order_relaxed);
489}
490
502static inline uint16_t
504 int16_t value)
505{
506 if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1)) {
507 ++value;
508 rte_mbuf_ext_refcnt_set(shinfo, (uint16_t)value);
509 return (uint16_t)value;
510 }
511
512 return rte_atomic_fetch_add_explicit(&shinfo->refcnt, value,
513 rte_memory_order_acq_rel) + value;
514}
515
517#define RTE_MBUF_PREFETCH_TO_FREE(m) do { \
518 if ((m) != NULL) \
519 rte_prefetch0(m); \
520} while (0)
521
522
538void
539rte_mbuf_raw_sanity_check(const struct rte_mbuf *m, const struct rte_mempool *mp);
540
560int rte_mbuf_raw_check(const struct rte_mbuf *m, const struct rte_mempool *mp,
561 const char **reason);
562
575void
576rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
577
597int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
598 const char **reason);
599
601#define __rte_mbuf_raw_sanity_check(m) __rte_mbuf_raw_sanity_check_mp(m, NULL)
602
604#define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_sanity_check_mp(m, NULL)
605
625static inline struct rte_mbuf *rte_mbuf_raw_alloc(struct rte_mempool *mp)
626{
627 union {
628 void *ptr;
629 struct rte_mbuf *m;
630 } ret;
631
632 if (rte_mempool_get(mp, &ret.ptr) < 0)
633 return NULL;
635
637
638 return ret.m;
639}
640
665static __rte_always_inline int
666rte_mbuf_raw_alloc_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
667{
668 int rc = rte_mempool_get_bulk(mp, (void **)mbufs, count);
669 if (unlikely(rc))
670 return rc;
671 for (unsigned int idx = 0; idx < count; idx++)
672 __rte_mbuf_raw_sanity_check_mp(mbufs[idx], mp);
673
675
676 return 0;
677}
678
693static __rte_always_inline void
695{
698 rte_mempool_put(m->pool, m);
699}
700
721static __rte_always_inline void
722rte_mbuf_raw_free_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
723{
724 for (unsigned int idx = 0; idx < count; idx++)
725 __rte_mbuf_raw_sanity_check_mp(mbufs[idx], mp);
727 rte_mempool_put_bulk(mp, (void **)mbufs, count);
728}
729
752void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
753 void *m, unsigned i);
754
775void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
776
808struct rte_mempool *
809rte_pktmbuf_pool_create(const char *name, unsigned n,
810 unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
811 int socket_id);
812
847struct rte_mempool *
848rte_pktmbuf_pool_create_by_ops(const char *name, unsigned int n,
849 unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
850 int socket_id, const char *ops_name);
851
854 void *buf_ptr;
856 size_t buf_len;
857 uint16_t elt_size;
858};
859
898struct rte_mempool *
899rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n,
900 unsigned int cache_size, uint16_t priv_size,
901 uint16_t data_room_size, int socket_id,
902 const struct rte_pktmbuf_extmem *ext_mem,
903 unsigned int ext_num);
904
916static inline uint16_t
918{
919 struct rte_pktmbuf_pool_private *mbp_priv;
920
921 mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
922 return mbp_priv->mbuf_data_room_size;
923}
924
937static inline uint16_t
939{
940 struct rte_pktmbuf_pool_private *mbp_priv;
941
942 mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
943 return mbp_priv->mbuf_priv_size;
944}
945
954static inline void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
955{
956 m->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM,
957 (uint16_t)m->buf_len);
958}
959
978static inline void
979rte_mbuf_raw_reset_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
980{
983 uint16_t data_off = RTE_MIN_T(RTE_PKTMBUF_HEADROOM, rte_pktmbuf_data_room_size(mp),
984 uint16_t);
985
986 for (unsigned int idx = 0; idx < count; idx++) {
987 struct rte_mbuf *m = mbufs[idx];
988
989 m->pkt_len = 0;
990 m->tx_offload = 0;
991 m->vlan_tci = 0;
992 m->vlan_tci_outer = 0;
994
995 m->ol_flags = ol_flags;
996 m->packet_type = 0;
997 m->data_off = data_off;
998
999 m->data_len = 0;
1001 }
1002}
1003
1012static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
1013{
1014 m->next = NULL;
1015 m->pkt_len = 0;
1016 m->tx_offload = 0;
1017 m->vlan_tci = 0;
1018 m->vlan_tci_outer = 0;
1019 m->nb_segs = 1;
1021
1023 m->packet_type = 0;
1025
1026 m->data_len = 0;
1028}
1029
1043static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
1044{
1045 struct rte_mbuf *m;
1046 if ((m = rte_mbuf_raw_alloc(mp)) != NULL)
1047 rte_mbuf_raw_reset_bulk(mp, &m, 1);
1048 return m;
1049}
1050
1065static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool,
1066 struct rte_mbuf **mbufs, unsigned count)
1067{
1068 int rc;
1069
1070 rc = rte_mbuf_raw_alloc_bulk(pool, mbufs, count);
1071 if (unlikely(rc))
1072 return rc;
1073
1074 rte_mbuf_raw_reset_bulk(pool, mbufs, count);
1075
1076 return 0;
1077}
1078
1111static inline struct rte_mbuf_ext_shared_info *
1112rte_pktmbuf_ext_shinfo_init_helper(void *buf_addr, uint16_t *buf_len,
1114{
1115 struct rte_mbuf_ext_shared_info *shinfo;
1116 void *buf_end = RTE_PTR_ADD(buf_addr, *buf_len);
1117 void *addr;
1118
1119 addr = RTE_PTR_ALIGN_FLOOR(RTE_PTR_SUB(buf_end, sizeof(*shinfo)),
1120 sizeof(uintptr_t));
1121 if (addr <= buf_addr)
1122 return NULL;
1123
1124 shinfo = (struct rte_mbuf_ext_shared_info *)addr;
1125 shinfo->free_cb = free_cb;
1126 shinfo->fcb_opaque = fcb_opaque;
1127 rte_mbuf_ext_refcnt_set(shinfo, 1);
1128
1129 *buf_len = (uint16_t)RTE_PTR_DIFF(shinfo, buf_addr);
1130 return shinfo;
1131}
1132
1193static inline void
1194rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
1195 rte_iova_t buf_iova, uint16_t buf_len,
1196 struct rte_mbuf_ext_shared_info *shinfo)
1197{
1198 /* mbuf should not be read-only */
1199 RTE_ASSERT(RTE_MBUF_DIRECT(m) && rte_mbuf_refcnt_read(m) == 1);
1200 RTE_ASSERT(shinfo->free_cb != NULL);
1201
1202 m->buf_addr = buf_addr;
1203 rte_mbuf_iova_set(m, buf_iova);
1204 m->buf_len = buf_len;
1205
1206 m->data_len = 0;
1207 m->data_off = 0;
1208
1210 m->shinfo = shinfo;
1211}
1212
1220#define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
1221
1230static inline void
1231rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
1232{
1233#if !RTE_IOVA_IN_MBUF
1234 mdst->dynfield2 = msrc->dynfield2;
1235#endif
1236 memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1));
1237}
1238
1239/* internal */
1240static inline void
1241__rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
1242{
1243 mdst->port = msrc->port;
1244 mdst->vlan_tci = msrc->vlan_tci;
1245 mdst->vlan_tci_outer = msrc->vlan_tci_outer;
1246 mdst->tx_offload = msrc->tx_offload;
1247 mdst->hash = msrc->hash;
1248 mdst->packet_type = msrc->packet_type;
1249 rte_mbuf_dynfield_copy(mdst, msrc);
1250}
1251
1273static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
1274{
1275 RTE_ASSERT(RTE_MBUF_DIRECT(mi) &&
1276 rte_mbuf_refcnt_read(mi) == 1);
1277
1278 if (RTE_MBUF_HAS_EXTBUF(m)) {
1280 mi->ol_flags = m->ol_flags;
1281 mi->shinfo = m->shinfo;
1282 } else {
1283 /* if m is not direct, get the mbuf that embeds the data */
1285 mi->priv_size = m->priv_size;
1287 }
1288
1289 __rte_pktmbuf_copy_hdr(mi, m);
1290
1291 mi->data_off = m->data_off;
1292 mi->data_len = m->data_len;
1294 mi->buf_addr = m->buf_addr;
1295 mi->buf_len = m->buf_len;
1296
1297 mi->next = NULL;
1298 mi->pkt_len = mi->data_len;
1299 mi->nb_segs = 1;
1300
1303}
1304
1312static inline void
1313__rte_pktmbuf_free_extbuf(struct rte_mbuf *m)
1314{
1315 RTE_ASSERT(RTE_MBUF_HAS_EXTBUF(m));
1316 RTE_ASSERT(m->shinfo != NULL);
1317
1318 if (rte_mbuf_ext_refcnt_update(m->shinfo, -1) == 0)
1320}
1321
1328static inline void
1329__rte_pktmbuf_free_direct(struct rte_mbuf *m)
1330{
1331 struct rte_mbuf *md;
1332 bool refcnt_not_one;
1333
1334 RTE_ASSERT(RTE_MBUF_CLONED(m));
1335
1336 md = rte_mbuf_from_indirect(m);
1337
1338 refcnt_not_one = unlikely(rte_mbuf_refcnt_read(md) != 1);
1339 if (refcnt_not_one && __rte_mbuf_refcnt_update(md, -1) != 0)
1340 return;
1341
1342 if (refcnt_not_one)
1343 rte_mbuf_refcnt_set(md, 1);
1344 if (md->nb_segs != 1)
1345 md->nb_segs = 1;
1346 if (md->next != NULL)
1347 md->next = NULL;
1349}
1350
1369static inline void rte_pktmbuf_detach(struct rte_mbuf *m)
1370{
1371 struct rte_mempool *mp = m->pool;
1372 uint32_t mbuf_size, buf_len;
1373 uint16_t priv_size;
1374
1375 if (RTE_MBUF_HAS_EXTBUF(m)) {
1376 /*
1377 * The mbuf has the external attached buffer,
1378 * we should check the type of the memory pool where
1379 * the mbuf was allocated from to detect the pinned
1380 * external buffer.
1381 */
1382 uint32_t flags = rte_pktmbuf_priv_flags(mp);
1383
1385 /*
1386 * The pinned external buffer should not be
1387 * detached from its backing mbuf, just exit.
1388 */
1389 return;
1390 }
1391 __rte_pktmbuf_free_extbuf(m);
1392 } else {
1393 __rte_pktmbuf_free_direct(m);
1394 }
1395 priv_size = rte_pktmbuf_priv_size(mp);
1396 mbuf_size = (uint32_t)(sizeof(struct rte_mbuf) + priv_size);
1397 buf_len = rte_pktmbuf_data_room_size(mp);
1398
1399 m->priv_size = priv_size;
1400 m->buf_addr = (char *)m + mbuf_size;
1401 rte_mbuf_iova_set(m, rte_mempool_virt2iova(m) + mbuf_size);
1402 m->buf_len = (uint16_t)buf_len;
1404 m->data_len = 0;
1405 m->ol_flags = 0;
1406}
1407
1421static inline int __rte_pktmbuf_pinned_extbuf_decref(struct rte_mbuf *m)
1422{
1423 struct rte_mbuf_ext_shared_info *shinfo;
1424
1425 /* Clear flags, mbuf is being freed. */
1427 shinfo = m->shinfo;
1428
1429 /* Optimize for performance - do not dec/reinit */
1430 if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1))
1431 return 0;
1432
1433 /*
1434 * Direct usage of add primitive to avoid
1435 * duplication of comparing with one.
1436 */
1437 if (likely(rte_atomic_fetch_add_explicit(&shinfo->refcnt, -1,
1438 rte_memory_order_acq_rel) - 1))
1439 return 1;
1440
1441 /* Reinitialize counter before mbuf freeing. */
1442 rte_mbuf_ext_refcnt_set(shinfo, 1);
1443 return 0;
1444}
1445
1460static __rte_always_inline struct rte_mbuf *
1462{
1463 bool refcnt_not_one;
1464
1466
1467 refcnt_not_one = unlikely(rte_mbuf_refcnt_read(m) != 1);
1468 if (refcnt_not_one && __rte_mbuf_refcnt_update(m, -1) != 0)
1469 return NULL;
1470
1471 if (unlikely(!RTE_MBUF_DIRECT(m))) {
1473 if (RTE_MBUF_HAS_EXTBUF(m) &&
1475 __rte_pktmbuf_pinned_extbuf_decref(m))
1476 return NULL;
1477 }
1478
1479 if (refcnt_not_one)
1480 rte_mbuf_refcnt_set(m, 1);
1481 if (m->nb_segs != 1)
1482 m->nb_segs = 1;
1483 if (m->next != NULL)
1484 m->next = NULL;
1485
1486 return m;
1487}
1488
1498static __rte_always_inline void
1500{
1502 if (likely(m != NULL))
1504}
1505
1515static inline void rte_pktmbuf_free(struct rte_mbuf *m)
1516{
1517 struct rte_mbuf *m_next;
1518
1519 if (m != NULL)
1521
1522 while (m != NULL) {
1523 m_next = m->next;
1525 m = m_next;
1526 }
1527}
1528
1541void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count);
1542
1560struct rte_mbuf *
1562
1584struct rte_mbuf *
1585rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
1586 uint32_t offset, uint32_t length);
1587
1599static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
1600{
1602
1603 do {
1605 } while ((m = m->next) != NULL);
1606}
1607
1616static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
1617{
1619 return m->data_off;
1620}
1621
1630static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
1631{
1633 return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) -
1634 m->data_len);
1635}
1636
1645static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
1646{
1648 while (m->next != NULL)
1649 m = m->next;
1650 return m;
1651}
1652
1661#define rte_pktmbuf_pkt_len(m) ((m)->pkt_len)
1662
1671#define rte_pktmbuf_data_len(m) ((m)->data_len)
1672
1688static inline char *rte_pktmbuf_prepend(struct rte_mbuf *m,
1689 uint16_t len)
1690{
1692
1693 if (unlikely(len > rte_pktmbuf_headroom(m)))
1694 return NULL;
1695
1696 /* NB: elaborating the subtraction like this instead of using
1697 * -= allows us to ensure the result type is uint16_t
1698 * avoiding compiler warnings on gcc 8.1 at least */
1699 m->data_off = (uint16_t)(m->data_off - len);
1700 m->data_len = (uint16_t)(m->data_len + len);
1701 m->pkt_len = (m->pkt_len + len);
1702
1703 return (char *)m->buf_addr + m->data_off;
1704}
1705
1721static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
1722{
1723 void *tail;
1724 struct rte_mbuf *m_last;
1725
1727
1728 m_last = rte_pktmbuf_lastseg(m);
1729 if (unlikely(len > rte_pktmbuf_tailroom(m_last)))
1730 return NULL;
1731
1732 tail = (char *)m_last->buf_addr + m_last->data_off + m_last->data_len;
1733 m_last->data_len = (uint16_t)(m_last->data_len + len);
1734 m->pkt_len = (m->pkt_len + len);
1735 return (char*) tail;
1736}
1737
1752static inline char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
1753{
1755
1756 if (unlikely(len > m->data_len))
1757 return NULL;
1758
1759 /* NB: elaborating the addition like this instead of using
1760 * += allows us to ensure the result type is uint16_t
1761 * avoiding compiler warnings on gcc 8.1 at least */
1762 m->data_len = (uint16_t)(m->data_len - len);
1763 m->data_off = (uint16_t)(m->data_off + len);
1764 m->pkt_len = (m->pkt_len - len);
1765 return (char *)m->buf_addr + m->data_off;
1766}
1767
1782static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
1783{
1784 struct rte_mbuf *m_last;
1785
1787
1788 m_last = rte_pktmbuf_lastseg(m);
1789 if (unlikely(len > m_last->data_len))
1790 return -1;
1791
1792 m_last->data_len = (uint16_t)(m_last->data_len - len);
1793 m->pkt_len = (m->pkt_len - len);
1794 return 0;
1795}
1796
1806static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
1807{
1809 return m->nb_segs == 1;
1810}
1811
1815const void *__rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off,
1816 uint32_t len, void *buf);
1817
1838static inline const void *rte_pktmbuf_read(const struct rte_mbuf *m,
1839 uint32_t off, uint32_t len, void *buf)
1840{
1841 if (likely((uint64_t)off + len <= rte_pktmbuf_data_len(m)))
1842 return rte_pktmbuf_mtod_offset(m, char *, off);
1843 else
1844 return __rte_pktmbuf_read(m, off, len, buf);
1845}
1846
1863static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
1864{
1865 struct rte_mbuf *cur_tail;
1866
1867 /* Check for number-of-segments-overflow */
1868 if (head->nb_segs + tail->nb_segs > RTE_MBUF_MAX_NB_SEGS)
1869 return -EOVERFLOW;
1870
1871 /* Chain 'tail' onto the old tail */
1872 cur_tail = rte_pktmbuf_lastseg(head);
1873 cur_tail->next = tail;
1874
1875 /* accumulate number of segments and total length.
1876 * NB: elaborating the addition like this instead of using
1877 * -= allows us to ensure the result type is uint16_t
1878 * avoiding compiler warnings on gcc 8.1 at least */
1879 head->nb_segs = (uint16_t)(head->nb_segs + tail->nb_segs);
1880 head->pkt_len += tail->pkt_len;
1881
1882 /* pkt_len is only set in the head */
1883 tail->pkt_len = tail->data_len;
1884
1885 return 0;
1886}
1887
1909static __rte_always_inline uint64_t
1910rte_mbuf_tx_offload(uint64_t il2, uint64_t il3, uint64_t il4, uint64_t tso,
1911 uint64_t ol3, uint64_t ol2, uint64_t unused)
1912{
1913 return il2 << RTE_MBUF_L2_LEN_OFS |
1914 il3 << RTE_MBUF_L3_LEN_OFS |
1915 il4 << RTE_MBUF_L4_LEN_OFS |
1916 tso << RTE_MBUF_TSO_SEGSZ_OFS |
1917 ol3 << RTE_MBUF_OUTL3_LEN_OFS |
1918 ol2 << RTE_MBUF_OUTL2_LEN_OFS |
1919 unused << RTE_MBUF_TXOFLD_UNUSED_OFS;
1920}
1921
1932static inline int
1934{
1935 uint64_t ol_flags = m->ol_flags;
1936
1937 /* Does packet set any of available offloads? */
1939 return 0;
1940
1941 /* IP checksum can be counted only for IPv4 packet */
1943 return -EINVAL;
1944
1945 /* IP type not set when required */
1948 return -EINVAL;
1949
1950 /* Check requirements for TSO packet */
1952 if ((m->tso_segsz == 0) ||
1955 return -EINVAL;
1956
1957 /* RTE_MBUF_F_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */
1960 return -EINVAL;
1961
1962 return 0;
1963}
1964
1968int __rte_pktmbuf_linearize(struct rte_mbuf *mbuf);
1969
1982static inline int
1984{
1985 if (rte_pktmbuf_is_contiguous(mbuf))
1986 return 0;
1987 return __rte_pktmbuf_linearize(mbuf);
1988}
1989
2004void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
2005
2009static inline uint32_t
2011{
2012 return m->hash.sched.queue_id;
2013}
2014
2018static inline uint8_t
2020{
2021 return m->hash.sched.traffic_class;
2022}
2023
2027static inline uint8_t
2029{
2030 return m->hash.sched.color;
2031}
2032
2045static inline void
2046rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
2047 uint8_t *traffic_class,
2048 uint8_t *color)
2049{
2050 struct rte_mbuf_sched sched = m->hash.sched;
2051
2052 *queue_id = sched.queue_id;
2054 *color = sched.color;
2055}
2056
2060static inline void
2062{
2063 m->hash.sched.queue_id = queue_id;
2064}
2065
2069static inline void
2071{
2072 m->hash.sched.traffic_class = traffic_class;
2073}
2074
2078static inline void
2080{
2081 m->hash.sched.color = color;
2082}
2083
2096static inline void
2098 uint8_t traffic_class,
2099 uint8_t color)
2100{
2101 m->hash.sched = (struct rte_mbuf_sched){
2102 .queue_id = queue_id,
2103 .traffic_class = traffic_class,
2104 .color = color,
2105 .reserved = 0,
2106 };
2107}
2108
2109#ifdef __cplusplus
2110}
2111#endif
2112
2113#endif /* _RTE_MBUF_H_ */
#define likely(x)
#define unlikely(x)
#define RTE_CACHE_LINE_MIN_SIZE
Definition: rte_common.h:936
#define __rte_assume(condition)
Definition: rte_common.h:595
#define RTE_PTR_ALIGN_FLOOR(ptr, align)
Definition: rte_common.h:759
#define RTE_MIN(a, b)
Definition: rte_common.h:999
#define RTE_PTR_DIFF(ptr1, ptr2)
Definition: rte_common.h:688
#define RTE_PTR_SUB(ptr, x)
Definition: rte_common.h:678
#define RTE_MIN_T(a, b, t)
Definition: rte_common.h:1026
uint64_t rte_iova_t
Definition: rte_common.h:974
#define RTE_PTR_ADD(ptr, x)
Definition: rte_common.h:643
#define RTE_SET_USED(x)
Definition: rte_common.h:292
#define __rte_always_inline
Definition: rte_common.h:534
static __rte_always_inline void rte_pktmbuf_free_seg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1499
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:1910
#define __rte_mbuf_raw_sanity_check_mp(m, mp)
Definition: rte_mbuf.h:348
static void rte_pktmbuf_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:1515
static rte_iova_t rte_mbuf_data_iova_default(const struct rte_mbuf *mb)
Definition: rte_mbuf.h:204
static rte_iova_t rte_mbuf_data_iova(const struct rte_mbuf *mb)
Definition: rte_mbuf.h:186
static uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1630
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:1671
static uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1616
static uint32_t rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:2010
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:1688
static char * rte_mbuf_data_addr_default(struct rte_mbuf *mb)
Definition: rte_mbuf.h:254
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)
void rte_mbuf_raw_sanity_check(const struct rte_mbuf *m, const struct rte_mempool *mp)
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 void rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id, uint8_t traffic_class, uint8_t color)
Definition: rte_mbuf.h:2097
static void rte_mbuf_raw_reset_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
Definition: rte_mbuf.h:979
static __rte_always_inline int rte_mbuf_raw_alloc_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
Definition: rte_mbuf.h:666
static void rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
Definition: rte_mbuf.h:1231
static char * rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1752
static void rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
Definition: rte_mbuf.h:2079
static int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1806
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:1721
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:2046
static void rte_pktmbuf_detach(struct rte_mbuf *m)
Definition: rte_mbuf.h:1369
static char * rte_mbuf_to_baddr(struct rte_mbuf *md)
Definition: rte_mbuf.h:273
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:1112
static uint32_t rte_pktmbuf_priv_flags(struct rte_mempool *mp)
Definition: rte_mbuf.h:319
static __rte_always_inline void rte_mbuf_raw_free_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
Definition: rte_mbuf.h:722
static void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
Definition: rte_mbuf.h:1599
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:455
static struct rte_mbuf * rte_mbuf_raw_alloc(struct rte_mempool *mp)
Definition: rte_mbuf.h:625
static uint16_t rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo, int16_t value)
Definition: rte_mbuf.h:503
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:350
static const void * rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off, uint32_t len, void *buf)
Definition: rte_mbuf.h:1838
int rte_mbuf_raw_check(const struct rte_mbuf *m, const struct rte_mempool *mp, const char **reason)
static uint16_t rte_mbuf_refcnt_read(const struct rte_mbuf *m)
Definition: rte_mbuf.h:446
static int rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
Definition: rte_mbuf.h:1983
static __rte_always_inline void rte_mbuf_raw_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:694
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:1043
static char * rte_mbuf_buf_addr(struct rte_mbuf *mb, struct rte_mempool *mp)
Definition: rte_mbuf.h:240
static void rte_mbuf_ext_refcnt_set(struct rte_mbuf_ext_shared_info *shinfo, uint16_t new_value)
Definition: rte_mbuf.h:485
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:2019
static uint16_t rte_mbuf_ext_refcnt_read(const struct rte_mbuf_ext_shared_info *shinfo)
Definition: rte_mbuf.h:471
static uint16_t rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
Definition: rte_mbuf.h:437
static int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1782
#define RTE_MBUF_HAS_PINNED_EXTBUF(mb)
Definition: rte_mbuf.h:342
static rte_iova_t rte_mbuf_iova_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:149
static void rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
Definition: rte_mbuf.h:2061
static uint16_t rte_pktmbuf_data_room_size(struct rte_mempool *mp)
Definition: rte_mbuf.h:917
static struct rte_mbuf * rte_pktmbuf_lastseg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1645
static void rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
Definition: rte_mbuf.h:2070
#define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF
Definition: rte_mbuf.h:333
static __rte_always_inline struct rte_mbuf * rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1461
static int rte_validate_tx_offload(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1933
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:1194
static struct rte_mbuf * rte_mbuf_from_indirect(struct rte_mbuf *mi)
Definition: rte_mbuf.h:218
static int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool, struct rte_mbuf **mbufs, unsigned count)
Definition: rte_mbuf.h:1065
static void rte_mbuf_iova_set(struct rte_mbuf *m, rte_iova_t iova)
Definition: rte_mbuf.h:167
static void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
Definition: rte_mbuf.h:954
static void * rte_mbuf_to_priv(struct rte_mbuf *m)
Definition: rte_mbuf.h:291
static uint8_t rte_mbuf_sched_color_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:2028
static int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
Definition: rte_mbuf.h:1863
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:938
static void rte_pktmbuf_reset(struct rte_mbuf *m)
Definition: rte_mbuf.h:1012
static void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
Definition: rte_mbuf.h:1273
#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
@ RTE_MBUF_HISTORY_OP_LIB_FREE
@ RTE_MBUF_HISTORY_OP_LIB_ALLOC
static void rte_mbuf_history_mark(struct rte_mbuf *m, enum rte_mbuf_history_op op)
static void rte_mbuf_history_mark_bulk(struct rte_mbuf *const *mbufs, unsigned int count, enum rte_mbuf_history_op op)
static __rte_always_inline int rte_mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned int n)
Definition: rte_mempool.h:1718
static rte_iova_t rte_mempool_virt2iova(const void *elt)
Definition: rte_mempool.h:1872
static __rte_always_inline void rte_mempool_put_bulk(struct rte_mempool *mp, void *const *obj_table, unsigned int n)
Definition: rte_mempool.h:1519
static __rte_always_inline int rte_mempool_get(struct rte_mempool *mp, void **obj_p)
Definition: rte_mempool.h:1747
static __rte_always_inline void rte_mempool_put(struct rte_mempool *mp, void *obj)
Definition: rte_mempool.h:1541
static void * rte_mempool_get_priv(struct rte_mempool *mp)
Definition: rte_mempool.h:1902
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
uint64_t dynfield2
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:240
uint32_t cache_size
Definition: rte_mempool.h:250
unsigned int flags
Definition: rte_mempool.h:247
uint16_t elt_size
Definition: rte_mbuf.h:857
rte_iova_t buf_iova
Definition: rte_mbuf.h:855
uint16_t mbuf_data_room_size
Definition: rte_mbuf.h:305