DPDK  25.11.3
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>
41 #include <rte_branch_prediction.h>
42 #include <rte_mbuf_ptype.h>
43 #include <rte_mbuf_core.h>
44 #include <rte_mbuf_history.h>
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
58 const char *rte_get_rx_ol_flag_name(uint64_t mask);
59 
72 int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen);
73 
84 const char *rte_get_tx_ol_flag_name(uint64_t mask);
85 
98 int rte_get_tx_ol_flag_list(uint64_t mask, char *buf, size_t buflen);
99 
110 static inline void
112 {
113  rte_prefetch0(m);
114 }
115 
127 static inline void
129 {
130 #if RTE_CACHE_LINE_SIZE == 64
132 #else
133  RTE_SET_USED(m);
134 #endif
135 }
136 
137 
138 static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
139 
148 static inline rte_iova_t
149 rte_mbuf_iova_get(const struct rte_mbuf *m)
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 
166 static 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 
185 static inline rte_iova_t
186 rte_mbuf_data_iova(const struct rte_mbuf *mb)
187 {
188  return rte_mbuf_iova_get(mb) + mb->data_off;
189 }
190 
203 static inline rte_iova_t
205 {
206  return rte_mbuf_iova_get(mb) + RTE_PKTMBUF_HEADROOM;
207 }
208 
217 static inline struct rte_mbuf *
219 {
220  return (struct rte_mbuf *)RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size);
221 }
222 
238 static inline char *
239 rte_mbuf_buf_addr(struct rte_mbuf *mb, struct rte_mempool *mp)
240 {
241  return (char *)mb + sizeof(*mb) + rte_pktmbuf_priv_size(mp);
242 }
243 
252 static inline char *
254 {
255  return rte_mbuf_buf_addr(mb, mb->pool) + RTE_PKTMBUF_HEADROOM;
256 }
257 
271 static inline char *
273 {
274  return rte_mbuf_buf_addr(md, md->pool);
275 }
276 
289 static inline void *
291 {
292  return RTE_PTR_ADD(m, sizeof(struct rte_mbuf));
293 }
294 
303  uint16_t mbuf_priv_size;
304  uint32_t flags;
305 };
306 
315 static inline uint32_t
317 {
318  struct rte_pktmbuf_pool_private *mbp_priv;
319 
320  mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
321  return mbp_priv->flags;
322 }
323 
330 #define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF (1 << 0)
331 
339 #define RTE_MBUF_HAS_PINNED_EXTBUF(mb) \
340  (rte_pktmbuf_priv_flags(mb->pool) & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF)
341 
342 #if defined RTE_LIBRTE_MBUF_DEBUG || defined __DOXYGEN__
343 
345 #define __rte_mbuf_raw_sanity_check_mp(m, mp) rte_mbuf_raw_sanity_check(m, mp)
346 
347 #define __rte_mbuf_sanity_check(m, is_h) rte_mbuf_sanity_check(m, is_h)
348 
349 #else /* !RTE_LIBRTE_MBUF_DEBUG */
350 
351 #define __rte_mbuf_raw_sanity_check_mp(m, mp) do { } while (0)
352 #define __rte_mbuf_sanity_check(m, is_h) do { } while (0)
353 
354 #endif /* RTE_LIBRTE_MBUF_DEBUG */
355 
356 #ifdef RTE_MBUF_REFCNT_ATOMIC
357 
365 static inline uint16_t
366 rte_mbuf_refcnt_read(const struct rte_mbuf *m)
367 {
368  return rte_atomic_load_explicit(&m->refcnt, rte_memory_order_relaxed);
369 }
370 
378 static inline void
379 rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
380 {
381  rte_atomic_store_explicit(&m->refcnt, new_value, rte_memory_order_relaxed);
382 }
383 
384 /* internal */
385 static inline uint16_t
386 __rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
387 {
388  return rte_atomic_fetch_add_explicit(&m->refcnt, value,
389  rte_memory_order_acq_rel) + value;
390 }
391 
401 static inline uint16_t
402 rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
403 {
404  /*
405  * The atomic_add is an expensive operation, so we don't want to
406  * call it in the case where we know we are the unique holder of
407  * this mbuf (i.e. ref_cnt == 1). Otherwise, an atomic
408  * operation has to be used because concurrent accesses on the
409  * reference counter can occur.
410  */
411  if (likely(rte_mbuf_refcnt_read(m) == 1)) {
412  ++value;
413  rte_mbuf_refcnt_set(m, (uint16_t)value);
414  return (uint16_t)value;
415  }
416 
417  return __rte_mbuf_refcnt_update(m, value);
418 }
419 
420 #else /* ! RTE_MBUF_REFCNT_ATOMIC */
421 
422 /* internal */
423 static inline uint16_t
424 __rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
425 {
426  m->refcnt = (uint16_t)(m->refcnt + value);
427  return m->refcnt;
428 }
429 
433 static inline uint16_t
434 rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
435 {
436  return __rte_mbuf_refcnt_update(m, value);
437 }
438 
442 static inline uint16_t
444 {
445  return m->refcnt;
446 }
447 
451 static inline void
452 rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
453 {
454  m->refcnt = new_value;
455 }
456 
457 #endif /* RTE_MBUF_REFCNT_ATOMIC */
458 
467 static inline uint16_t
469 {
470  return rte_atomic_load_explicit(&shinfo->refcnt, rte_memory_order_relaxed);
471 }
472 
481 static inline void
483  uint16_t new_value)
484 {
485  rte_atomic_store_explicit(&shinfo->refcnt, new_value, rte_memory_order_relaxed);
486 }
487 
499 static inline uint16_t
501  int16_t value)
502 {
503  if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1)) {
504  ++value;
505  rte_mbuf_ext_refcnt_set(shinfo, (uint16_t)value);
506  return (uint16_t)value;
507  }
508 
509  return rte_atomic_fetch_add_explicit(&shinfo->refcnt, value,
510  rte_memory_order_acq_rel) + value;
511 }
512 
514 #define RTE_MBUF_PREFETCH_TO_FREE(m) do { \
515  if ((m) != NULL) \
516  rte_prefetch0(m); \
517 } while (0)
518 
519 
535 void
536 rte_mbuf_raw_sanity_check(const struct rte_mbuf *m, const struct rte_mempool *mp);
537 
557 int rte_mbuf_raw_check(const struct rte_mbuf *m, const struct rte_mempool *mp,
558  const char **reason);
559 
572 void
573 rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
574 
594 int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
595  const char **reason);
596 
598 #define __rte_mbuf_raw_sanity_check(m) __rte_mbuf_raw_sanity_check_mp(m, NULL)
599 
601 #define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_sanity_check_mp(m, NULL)
602 
622 static inline struct rte_mbuf *rte_mbuf_raw_alloc(struct rte_mempool *mp)
623 {
624  union {
625  void *ptr;
626  struct rte_mbuf *m;
627  } ret;
628 
629  if (rte_mempool_get(mp, &ret.ptr) < 0)
630  return NULL;
632 
634 
635  return ret.m;
636 }
637 
662 static __rte_always_inline int
663 rte_mbuf_raw_alloc_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
664 {
665  int rc = rte_mempool_get_bulk(mp, (void **)mbufs, count);
666  if (unlikely(rc))
667  return rc;
668  for (unsigned int idx = 0; idx < count; idx++)
669  __rte_mbuf_raw_sanity_check_mp(mbufs[idx], mp);
670 
672 
673  return 0;
674 }
675 
690 static __rte_always_inline void
692 {
695  rte_mempool_put(m->pool, m);
696 }
697 
718 static __rte_always_inline void
719 rte_mbuf_raw_free_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
720 {
721  for (unsigned int idx = 0; idx < count; idx++)
722  __rte_mbuf_raw_sanity_check_mp(mbufs[idx], mp);
724  rte_mempool_put_bulk(mp, (void **)mbufs, count);
725 }
726 
749 void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
750  void *m, unsigned i);
751 
772 void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
773 
807 struct rte_mempool *
808 rte_pktmbuf_pool_create(const char *name, unsigned n,
809  unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
810  int socket_id);
811 
848 struct rte_mempool *
849 rte_pktmbuf_pool_create_by_ops(const char *name, unsigned int n,
850  unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
851  int socket_id, const char *ops_name);
852 
855  void *buf_ptr;
857  size_t buf_len;
858  uint16_t elt_size;
859 };
860 
901 struct rte_mempool *
902 rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n,
903  unsigned int cache_size, uint16_t priv_size,
904  uint16_t data_room_size, int socket_id,
905  const struct rte_pktmbuf_extmem *ext_mem,
906  unsigned int ext_num);
907 
919 static inline uint16_t
921 {
922  struct rte_pktmbuf_pool_private *mbp_priv;
923 
924  mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
925  return mbp_priv->mbuf_data_room_size;
926 }
927 
940 static inline uint16_t
942 {
943  struct rte_pktmbuf_pool_private *mbp_priv;
944 
945  mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
946  return mbp_priv->mbuf_priv_size;
947 }
948 
957 static inline void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
958 {
959  m->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM,
960  (uint16_t)m->buf_len);
961 }
962 
981 static inline void
982 rte_mbuf_raw_reset_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
983 {
984  uint64_t ol_flags = (rte_pktmbuf_priv_flags(mp) & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF) ?
986  uint16_t data_off = RTE_MIN_T(RTE_PKTMBUF_HEADROOM, rte_pktmbuf_data_room_size(mp),
987  uint16_t);
988 
989  for (unsigned int idx = 0; idx < count; idx++) {
990  struct rte_mbuf *m = mbufs[idx];
991 
992  m->pkt_len = 0;
993  m->tx_offload = 0;
994  m->vlan_tci = 0;
995  m->vlan_tci_outer = 0;
997 
998  m->ol_flags = ol_flags;
999  m->packet_type = 0;
1000  m->data_off = data_off;
1001 
1002  m->data_len = 0;
1004  }
1005 }
1006 
1015 static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
1016 {
1017  m->next = NULL;
1018  m->pkt_len = 0;
1019  m->tx_offload = 0;
1020  m->vlan_tci = 0;
1021  m->vlan_tci_outer = 0;
1022  m->nb_segs = 1;
1024 
1026  m->packet_type = 0;
1028 
1029  m->data_len = 0;
1031 }
1032 
1046 static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
1047 {
1048  struct rte_mbuf *m;
1049  if ((m = rte_mbuf_raw_alloc(mp)) != NULL)
1050  rte_mbuf_raw_reset_bulk(mp, &m, 1);
1051  return m;
1052 }
1053 
1068 static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool,
1069  struct rte_mbuf **mbufs, unsigned count)
1070 {
1071  int rc;
1072 
1073  rc = rte_mbuf_raw_alloc_bulk(pool, mbufs, count);
1074  if (unlikely(rc))
1075  return rc;
1076 
1077  rte_mbuf_raw_reset_bulk(pool, mbufs, count);
1078 
1079  return 0;
1080 }
1081 
1114 static inline struct rte_mbuf_ext_shared_info *
1115 rte_pktmbuf_ext_shinfo_init_helper(void *buf_addr, uint16_t *buf_len,
1117 {
1118  struct rte_mbuf_ext_shared_info *shinfo;
1119  void *buf_end = RTE_PTR_ADD(buf_addr, *buf_len);
1120  void *addr;
1121 
1122  addr = RTE_PTR_ALIGN_FLOOR(RTE_PTR_SUB(buf_end, sizeof(*shinfo)),
1123  sizeof(uintptr_t));
1124  if (addr <= buf_addr)
1125  return NULL;
1126 
1127  shinfo = (struct rte_mbuf_ext_shared_info *)addr;
1128  shinfo->free_cb = free_cb;
1129  shinfo->fcb_opaque = fcb_opaque;
1130  rte_mbuf_ext_refcnt_set(shinfo, 1);
1131 
1132  *buf_len = (uint16_t)RTE_PTR_DIFF(shinfo, buf_addr);
1133  return shinfo;
1134 }
1135 
1196 static inline void
1197 rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
1198  rte_iova_t buf_iova, uint16_t buf_len,
1199  struct rte_mbuf_ext_shared_info *shinfo)
1200 {
1201  /* mbuf should not be read-only */
1202  RTE_ASSERT(RTE_MBUF_DIRECT(m) && rte_mbuf_refcnt_read(m) == 1);
1203  RTE_ASSERT(shinfo->free_cb != NULL);
1204 
1205  m->buf_addr = buf_addr;
1206  rte_mbuf_iova_set(m, buf_iova);
1207  m->buf_len = buf_len;
1208 
1209  m->data_len = 0;
1210  m->data_off = 0;
1211 
1213  m->shinfo = shinfo;
1214 }
1215 
1223 #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
1224 
1233 static inline void
1234 rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
1235 {
1236 #if !RTE_IOVA_IN_MBUF
1237  mdst->dynfield2 = msrc->dynfield2;
1238 #endif
1239  memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1));
1240 }
1241 
1242 /* internal */
1243 static inline void
1244 __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
1245 {
1246  mdst->port = msrc->port;
1247  mdst->vlan_tci = msrc->vlan_tci;
1248  mdst->vlan_tci_outer = msrc->vlan_tci_outer;
1249  mdst->tx_offload = msrc->tx_offload;
1250  mdst->hash = msrc->hash;
1251  mdst->packet_type = msrc->packet_type;
1252  rte_mbuf_dynfield_copy(mdst, msrc);
1253 }
1254 
1276 static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
1277 {
1278  RTE_ASSERT(RTE_MBUF_DIRECT(mi) &&
1279  rte_mbuf_refcnt_read(mi) == 1);
1280 
1281  if (RTE_MBUF_HAS_EXTBUF(m)) {
1283  mi->ol_flags = m->ol_flags;
1284  mi->shinfo = m->shinfo;
1285  } else {
1286  /* if m is not direct, get the mbuf that embeds the data */
1288  mi->priv_size = m->priv_size;
1290  }
1291 
1292  __rte_pktmbuf_copy_hdr(mi, m);
1293 
1294  mi->data_off = m->data_off;
1295  mi->data_len = m->data_len;
1297  mi->buf_addr = m->buf_addr;
1298  mi->buf_len = m->buf_len;
1299 
1300  mi->next = NULL;
1301  mi->pkt_len = mi->data_len;
1302  mi->nb_segs = 1;
1303 
1304  __rte_mbuf_sanity_check(mi, 1);
1306 }
1307 
1315 static inline void
1316 __rte_pktmbuf_free_extbuf(struct rte_mbuf *m)
1317 {
1318  RTE_ASSERT(RTE_MBUF_HAS_EXTBUF(m));
1319  RTE_ASSERT(m->shinfo != NULL);
1320 
1321  if (rte_mbuf_ext_refcnt_update(m->shinfo, -1) == 0)
1322  m->shinfo->free_cb(m->buf_addr, m->shinfo->fcb_opaque);
1323 }
1324 
1331 static inline void
1332 __rte_pktmbuf_free_direct(struct rte_mbuf *m)
1333 {
1334  struct rte_mbuf *md;
1335 
1336  RTE_ASSERT(RTE_MBUF_CLONED(m));
1337 
1338  md = rte_mbuf_from_indirect(m);
1339 
1340  if (rte_mbuf_refcnt_update(md, -1) == 0) {
1341  md->next = NULL;
1342  md->nb_segs = 1;
1343  rte_mbuf_refcnt_set(md, 1);
1344  rte_mbuf_raw_free(md);
1345  }
1346 }
1347 
1366 static inline void rte_pktmbuf_detach(struct rte_mbuf *m)
1367 {
1368  struct rte_mempool *mp = m->pool;
1369  uint32_t mbuf_size, buf_len;
1370  uint16_t priv_size;
1371 
1372  if (RTE_MBUF_HAS_EXTBUF(m)) {
1373  /*
1374  * The mbuf has the external attached buffer,
1375  * we should check the type of the memory pool where
1376  * the mbuf was allocated from to detect the pinned
1377  * external buffer.
1378  */
1379  uint32_t flags = rte_pktmbuf_priv_flags(mp);
1380 
1382  /*
1383  * The pinned external buffer should not be
1384  * detached from its backing mbuf, just exit.
1385  */
1386  return;
1387  }
1388  __rte_pktmbuf_free_extbuf(m);
1389  } else {
1390  __rte_pktmbuf_free_direct(m);
1391  }
1392  priv_size = rte_pktmbuf_priv_size(mp);
1393  mbuf_size = (uint32_t)(sizeof(struct rte_mbuf) + priv_size);
1394  buf_len = rte_pktmbuf_data_room_size(mp);
1395 
1396  m->priv_size = priv_size;
1397  m->buf_addr = (char *)m + mbuf_size;
1398  rte_mbuf_iova_set(m, rte_mempool_virt2iova(m) + mbuf_size);
1399  m->buf_len = (uint16_t)buf_len;
1401  m->data_len = 0;
1402  m->ol_flags = 0;
1403 }
1404 
1418 static inline int __rte_pktmbuf_pinned_extbuf_decref(struct rte_mbuf *m)
1419 {
1420  struct rte_mbuf_ext_shared_info *shinfo;
1421 
1422  /* Clear flags, mbuf is being freed. */
1424  shinfo = m->shinfo;
1425 
1426  /* Optimize for performance - do not dec/reinit */
1427  if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1))
1428  return 0;
1429 
1430  /*
1431  * Direct usage of add primitive to avoid
1432  * duplication of comparing with one.
1433  */
1434  if (likely(rte_atomic_fetch_add_explicit(&shinfo->refcnt, -1,
1435  rte_memory_order_acq_rel) - 1))
1436  return 1;
1437 
1438  /* Reinitialize counter before mbuf freeing. */
1439  rte_mbuf_ext_refcnt_set(shinfo, 1);
1440  return 0;
1441 }
1442 
1457 static __rte_always_inline struct rte_mbuf *
1459 {
1460  bool refcnt_not_one;
1461 
1463 
1464  refcnt_not_one = unlikely(rte_mbuf_refcnt_read(m) != 1);
1465  if (refcnt_not_one && __rte_mbuf_refcnt_update(m, -1) != 0)
1466  return NULL;
1467 
1468  if (unlikely(!RTE_MBUF_DIRECT(m))) {
1469  rte_pktmbuf_detach(m);
1470  if (RTE_MBUF_HAS_EXTBUF(m) &&
1472  __rte_pktmbuf_pinned_extbuf_decref(m))
1473  return NULL;
1474  }
1475 
1476  if (refcnt_not_one)
1477  rte_mbuf_refcnt_set(m, 1);
1478  if (m->nb_segs != 1)
1479  m->nb_segs = 1;
1480  if (m->next != NULL)
1481  m->next = NULL;
1482 
1483  return m;
1484 }
1485 
1495 static __rte_always_inline void
1497 {
1498  m = rte_pktmbuf_prefree_seg(m);
1499  if (likely(m != NULL))
1500  rte_mbuf_raw_free(m);
1501 }
1502 
1512 static inline void rte_pktmbuf_free(struct rte_mbuf *m)
1513 {
1514  struct rte_mbuf *m_next;
1515 
1516  if (m != NULL)
1518 
1519  while (m != NULL) {
1520  m_next = m->next;
1522  m = m_next;
1523  }
1524 }
1525 
1538 void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count);
1539 
1557 struct rte_mbuf *
1558 rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp);
1559 
1581 struct rte_mbuf *
1582 rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
1583  uint32_t offset, uint32_t length);
1584 
1596 static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
1597 {
1599 
1600  do {
1601  rte_mbuf_refcnt_update(m, v);
1602  } while ((m = m->next) != NULL);
1603 }
1604 
1613 static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
1614 {
1616  return m->data_off;
1617 }
1618 
1627 static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
1628 {
1630  return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) -
1631  m->data_len);
1632 }
1633 
1642 static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
1643 {
1645  while (m->next != NULL)
1646  m = m->next;
1647  return m;
1648 }
1649 
1658 #define rte_pktmbuf_pkt_len(m) ((m)->pkt_len)
1659 
1668 #define rte_pktmbuf_data_len(m) ((m)->data_len)
1669 
1685 static inline char *rte_pktmbuf_prepend(struct rte_mbuf *m,
1686  uint16_t len)
1687 {
1689 
1690  if (unlikely(len > rte_pktmbuf_headroom(m)))
1691  return NULL;
1692 
1693  /* NB: elaborating the subtraction like this instead of using
1694  * -= allows us to ensure the result type is uint16_t
1695  * avoiding compiler warnings on gcc 8.1 at least */
1696  m->data_off = (uint16_t)(m->data_off - len);
1697  m->data_len = (uint16_t)(m->data_len + len);
1698  m->pkt_len = (m->pkt_len + len);
1699 
1700  return (char *)m->buf_addr + m->data_off;
1701 }
1702 
1718 static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
1719 {
1720  void *tail;
1721  struct rte_mbuf *m_last;
1722 
1724 
1725  m_last = rte_pktmbuf_lastseg(m);
1726  if (unlikely(len > rte_pktmbuf_tailroom(m_last)))
1727  return NULL;
1728 
1729  tail = (char *)m_last->buf_addr + m_last->data_off + m_last->data_len;
1730  m_last->data_len = (uint16_t)(m_last->data_len + len);
1731  m->pkt_len = (m->pkt_len + len);
1732  return (char*) tail;
1733 }
1734 
1749 static inline char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
1750 {
1752 
1753  if (unlikely(len > m->data_len))
1754  return NULL;
1755 
1756  /* NB: elaborating the addition like this instead of using
1757  * += allows us to ensure the result type is uint16_t
1758  * avoiding compiler warnings on gcc 8.1 at least */
1759  m->data_len = (uint16_t)(m->data_len - len);
1760  m->data_off = (uint16_t)(m->data_off + len);
1761  m->pkt_len = (m->pkt_len - len);
1762  return (char *)m->buf_addr + m->data_off;
1763 }
1764 
1779 static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
1780 {
1781  struct rte_mbuf *m_last;
1782 
1784 
1785  m_last = rte_pktmbuf_lastseg(m);
1786  if (unlikely(len > m_last->data_len))
1787  return -1;
1788 
1789  m_last->data_len = (uint16_t)(m_last->data_len - len);
1790  m->pkt_len = (m->pkt_len - len);
1791  return 0;
1792 }
1793 
1803 static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
1804 {
1806  return m->nb_segs == 1;
1807 }
1808 
1812 const void *__rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off,
1813  uint32_t len, void *buf);
1814 
1835 static inline const void *rte_pktmbuf_read(const struct rte_mbuf *m,
1836  uint32_t off, uint32_t len, void *buf)
1837 {
1838  if (likely((uint64_t)off + len <= rte_pktmbuf_data_len(m)))
1839  return rte_pktmbuf_mtod_offset(m, char *, off);
1840  else
1841  return __rte_pktmbuf_read(m, off, len, buf);
1842 }
1843 
1860 static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
1861 {
1862  struct rte_mbuf *cur_tail;
1863 
1864  /* Check for number-of-segments-overflow */
1865  if (head->nb_segs + tail->nb_segs > RTE_MBUF_MAX_NB_SEGS)
1866  return -EOVERFLOW;
1867 
1868  /* Chain 'tail' onto the old tail */
1869  cur_tail = rte_pktmbuf_lastseg(head);
1870  cur_tail->next = tail;
1871 
1872  /* accumulate number of segments and total length.
1873  * NB: elaborating the addition like this instead of using
1874  * -= allows us to ensure the result type is uint16_t
1875  * avoiding compiler warnings on gcc 8.1 at least */
1876  head->nb_segs = (uint16_t)(head->nb_segs + tail->nb_segs);
1877  head->pkt_len += tail->pkt_len;
1878 
1879  /* pkt_len is only set in the head */
1880  tail->pkt_len = tail->data_len;
1881 
1882  return 0;
1883 }
1884 
1906 static __rte_always_inline uint64_t
1907 rte_mbuf_tx_offload(uint64_t il2, uint64_t il3, uint64_t il4, uint64_t tso,
1908  uint64_t ol3, uint64_t ol2, uint64_t unused)
1909 {
1910  return il2 << RTE_MBUF_L2_LEN_OFS |
1911  il3 << RTE_MBUF_L3_LEN_OFS |
1912  il4 << RTE_MBUF_L4_LEN_OFS |
1913  tso << RTE_MBUF_TSO_SEGSZ_OFS |
1914  ol3 << RTE_MBUF_OUTL3_LEN_OFS |
1915  ol2 << RTE_MBUF_OUTL2_LEN_OFS |
1916  unused << RTE_MBUF_TXOFLD_UNUSED_OFS;
1917 }
1918 
1929 static inline int
1931 {
1932  uint64_t ol_flags = m->ol_flags;
1933 
1934  /* Does packet set any of available offloads? */
1936  return 0;
1937 
1938  /* IP checksum can be counted only for IPv4 packet */
1940  return -EINVAL;
1941 
1942  /* IP type not set when required */
1945  return -EINVAL;
1946 
1947  /* Check requirements for TSO packet */
1949  if ((m->tso_segsz == 0) ||
1952  return -EINVAL;
1953 
1954  /* RTE_MBUF_F_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */
1957  return -EINVAL;
1958 
1959  return 0;
1960 }
1961 
1965 int __rte_pktmbuf_linearize(struct rte_mbuf *mbuf);
1966 
1979 static inline int
1981 {
1982  if (rte_pktmbuf_is_contiguous(mbuf))
1983  return 0;
1984  return __rte_pktmbuf_linearize(mbuf);
1985 }
1986 
2001 void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
2002 
2006 static inline uint32_t
2008 {
2009  return m->hash.sched.queue_id;
2010 }
2011 
2015 static inline uint8_t
2017 {
2018  return m->hash.sched.traffic_class;
2019 }
2020 
2024 static inline uint8_t
2026 {
2027  return m->hash.sched.color;
2028 }
2029 
2042 static inline void
2043 rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
2044  uint8_t *traffic_class,
2045  uint8_t *color)
2046 {
2047  struct rte_mbuf_sched sched = m->hash.sched;
2048 
2049  *queue_id = sched.queue_id;
2050  *traffic_class = sched.traffic_class;
2051  *color = sched.color;
2052 }
2053 
2057 static inline void
2059 {
2060  m->hash.sched.queue_id = queue_id;
2061 }
2062 
2066 static inline void
2068 {
2069  m->hash.sched.traffic_class = traffic_class;
2070 }
2071 
2075 static inline void
2077 {
2078  m->hash.sched.color = color;
2079 }
2080 
2093 static inline void
2095  uint8_t traffic_class,
2096  uint8_t color)
2097 {
2098  m->hash.sched = (struct rte_mbuf_sched){
2099  .queue_id = queue_id,
2100  .traffic_class = traffic_class,
2101  .color = color,
2102  .reserved = 0,
2103  };
2104 }
2105 
2106 #ifdef __cplusplus
2107 }
2108 #endif
2109 
2110 #endif /* _RTE_MBUF_H_ */
static void rte_pktmbuf_reset(struct rte_mbuf *m)
Definition: rte_mbuf.h:1015
struct rte_mbuf_ext_shared_info * shinfo
static rte_iova_t rte_mbuf_data_iova(const struct rte_mbuf *mb)
Definition: rte_mbuf.h:186
struct rte_mbuf * next
uint16_t mbuf_data_room_size
Definition: rte_mbuf.h:302
void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count)
uint16_t vlan_tci_outer
#define __rte_always_inline
Definition: rte_common.h:502
#define RTE_MBUF_F_TX_OFFLOAD_MASK
static struct rte_mbuf * rte_pktmbuf_alloc(struct rte_mempool *mp)
Definition: rte_mbuf.h:1046
static void rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
Definition: rte_mbuf.h:2067
static uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp)
Definition: rte_mbuf.h:941
static int rte_validate_tx_offload(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1930
uint32_t queue_id
#define likely(x)
static void rte_pktmbuf_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:1512
static uint32_t rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:2007
#define RTE_PTR_ALIGN_FLOOR(ptr, align)
Definition: rte_common.h:622
void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
uint64_t rte_iova_t
Definition: rte_common.h:786
static __rte_always_inline void rte_mempool_put_bulk(struct rte_mempool *mp, void *const *obj_table, unsigned int n)
Definition: rte_mempool.h:1474
static __rte_always_inline void rte_pktmbuf_free_seg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1496
void * buf_addr
static struct rte_mbuf * rte_mbuf_from_indirect(struct rte_mbuf *mi)
Definition: rte_mbuf.h:218
uint16_t data_len
rte_mbuf_extbuf_free_callback_t free_cb
static int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
Definition: rte_mbuf.h:1860
static uint8_t rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:2016
#define __rte_mbuf_raw_sanity_check_mp(m, mp)
Definition: rte_mbuf.h:345
unsigned int flags
Definition: rte_mempool.h:238
static void rte_mbuf_iova_set(struct rte_mbuf *m, rte_iova_t iova)
Definition: rte_mbuf.h:167
#define RTE_MBUF_F_TX_IPV6
uint64_t tso_segsz
struct rte_mbuf * rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp, uint32_t offset, uint32_t length)
void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len)
static uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1613
static int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool, struct rte_mbuf **mbufs, unsigned count)
Definition: rte_mbuf.h:1068
static void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
Definition: rte_mbuf.h:957
static void * rte_mbuf_to_priv(struct rte_mbuf *m)
Definition: rte_mbuf.h:290
uint32_t cache_size
Definition: rte_mempool.h:241
int rte_mbuf_raw_check(const struct rte_mbuf *m, const struct rte_mempool *mp, const char **reason)
static void rte_mbuf_prefetch_part2(struct rte_mbuf *m)
Definition: rte_mbuf.h:128
char name[RTE_MEMPOOL_NAMESIZE]
Definition: rte_mempool.h:231
static uint16_t rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo, int16_t value)
Definition: rte_mbuf.h:500
uint16_t nb_segs
uint16_t port
int rte_mbuf_check(const struct rte_mbuf *m, int is_header, const char **reason)
#define rte_pktmbuf_mtod_offset(m, t, o)
static __rte_always_inline struct rte_mbuf * rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1458
static int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1803
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)
#define RTE_PTR_ADD(ptr, x)
Definition: rte_common.h:566
static void rte_mbuf_raw_reset_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
Definition: rte_mbuf.h:982
int rte_get_tx_ol_flag_list(uint64_t mask, char *buf, size_t buflen)
#define RTE_MBUF_MAX_NB_SEGS
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:2094
static uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1627
static __rte_always_inline void rte_mbuf_raw_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:691
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:2043
#define unlikely(x)
uint16_t priv_size
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:1907
static void rte_mbuf_history_mark_bulk(struct rte_mbuf *const *mbufs, unsigned int count, enum rte_mbuf_history_op op)
static void rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
Definition: rte_mbuf.h:2058
static char * rte_mbuf_buf_addr(struct rte_mbuf *mb, struct rte_mempool *mp)
Definition: rte_mbuf.h:239
void rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
static void rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
Definition: rte_mbuf.h:2076
void(* rte_mbuf_extbuf_free_callback_t)(void *addr, void *opaque)
#define RTE_MIN(a, b)
Definition: rte_common.h:811
uint64_t dynfield2
#define __rte_mbuf_sanity_check(m, is_h)
Definition: rte_mbuf.h:347
const char * rte_get_tx_ol_flag_name(uint64_t mask)
static uint16_t rte_mbuf_refcnt_read(const struct rte_mbuf *m)
Definition: rte_mbuf.h:443
static int rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
Definition: rte_mbuf.h:1980
static __rte_always_inline int rte_mempool_get(struct rte_mempool *mp, void **obj_p)
Definition: rte_mempool.h:1720
static uint32_t rte_pktmbuf_priv_flags(struct rte_mempool *mp)
Definition: rte_mbuf.h:316
uint16_t elt_size
Definition: rte_mbuf.h:858
uint16_t refcnt
static char * rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1749
#define RTE_MBUF_DIRECT(mb)
#define RTE_MBUF_CLONED(mb)
#define RTE_CACHE_LINE_MIN_SIZE
Definition: rte_common.h:748
static void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
Definition: rte_mbuf.h:1276
static __rte_always_inline int rte_mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned int n)
Definition: rte_mempool.h:1691
#define RTE_MBUF_F_TX_OUTER_IP_CKSUM
uint64_t ol_flags
static void rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
Definition: rte_mbuf.h:1234
static void rte_pktmbuf_detach(struct rte_mbuf *m)
Definition: rte_mbuf.h:1366
static uint16_t rte_mbuf_ext_refcnt_read(const struct rte_mbuf_ext_shared_info *shinfo)
Definition: rte_mbuf.h:468
uint32_t pkt_len
uint16_t buf_len
static void rte_mbuf_history_mark(struct rte_mbuf *m, enum rte_mbuf_history_op op)
#define rte_pktmbuf_data_len(m)
Definition: rte_mbuf.h:1668
#define RTE_MBUF_F_TX_L4_MASK
static uint16_t rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
Definition: rte_mbuf.h:434
uint32_t packet_type
#define RTE_MBUF_F_TX_IP_CKSUM
static uint16_t rte_pktmbuf_data_room_size(struct rte_mempool *mp)
Definition: rte_mbuf.h:920
#define RTE_MBUF_F_TX_TCP_SEG
#define RTE_MBUF_F_INDIRECT
#define RTE_MBUF_PORT_INVALID
const char * rte_get_rx_ol_flag_name(uint64_t mask)
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:1115
#define RTE_MBUF_F_TX_OUTER_IPV4
void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, void *m, unsigned i)
#define RTE_MBUF_HAS_EXTBUF(mb)
struct rte_mempool * pool
static void rte_mbuf_ext_refcnt_set(struct rte_mbuf_ext_shared_info *shinfo, uint16_t new_value)
Definition: rte_mbuf.h:482
static char * rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1718
static void rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
Definition: rte_mbuf.h:452
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 rte_iova_t rte_mbuf_data_iova_default(const struct rte_mbuf *mb)
Definition: rte_mbuf.h:204
static int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1779
static char * rte_mbuf_to_baddr(struct rte_mbuf *md)
Definition: rte_mbuf.h:272
static const void * rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off, uint32_t len, void *buf)
Definition: rte_mbuf.h:1835
static char * rte_pktmbuf_prepend(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1685
static struct rte_mbuf * rte_mbuf_raw_alloc(struct rte_mempool *mp)
Definition: rte_mbuf.h:622
static rte_iova_t rte_mbuf_iova_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:149
static void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
Definition: rte_mbuf.h:1596
#define RTE_PTR_SUB(ptr, x)
Definition: rte_common.h:571
static struct rte_mbuf * rte_pktmbuf_lastseg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1642
static uint8_t rte_mbuf_sched_color_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:2025
#define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF
Definition: rte_mbuf.h:330
static char * rte_mbuf_data_addr_default(struct rte_mbuf *mb)
Definition: rte_mbuf.h:253
static rte_iova_t rte_mempool_virt2iova(const void *elt)
Definition: rte_mempool.h:1845
static __rte_always_inline void rte_mempool_put(struct rte_mempool *mp, void *obj)
Definition: rte_mempool.h:1496
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:719
rte_iova_t buf_iova
Definition: rte_mbuf.h:856
uint8_t traffic_class
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:663
#define RTE_MBUF_F_TX_IPV4
#define RTE_PTR_DIFF(ptr1, ptr2)
Definition: rte_common.h:578
static void rte_mbuf_prefetch_part1(struct rte_mbuf *m)
Definition: rte_mbuf.h:111
#define RTE_MBUF_F_EXTERNAL
static void * rte_mempool_get_priv(struct rte_mempool *mp)
Definition: rte_mempool.h:1873
uint64_t tx_offload
#define RTE_MIN_T(a, b, t)
Definition: rte_common.h:825
uint16_t vlan_tci
#define RTE_MBUF_HAS_PINNED_EXTBUF(mb)
Definition: rte_mbuf.h:339
struct rte_mbuf * rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp)
#define RTE_SET_USED(x)
Definition: rte_common.h:264
int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen)
static void rte_prefetch0(const volatile void *p)
void rte_mbuf_raw_sanity_check(const struct rte_mbuf *m, const struct rte_mempool *mp)
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)
uint32_t dynfield1[9]
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:1197