DPDK  24.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 <stdint.h>
35 
36 #include <rte_common.h>
37 #include <rte_config.h>
38 #include <rte_mempool.h>
39 #include <rte_prefetch.h>
40 #include <rte_branch_prediction.h>
41 #include <rte_mbuf_ptype.h>
42 #include <rte_mbuf_core.h>
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
56 const char *rte_get_rx_ol_flag_name(uint64_t mask);
57 
70 int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen);
71 
82 const char *rte_get_tx_ol_flag_name(uint64_t mask);
83 
96 int rte_get_tx_ol_flag_list(uint64_t mask, char *buf, size_t buflen);
97 
108 static inline void
110 {
111  rte_prefetch0(m);
112 }
113 
125 static inline void
127 {
128 #if RTE_CACHE_LINE_SIZE == 64
130 #else
131  RTE_SET_USED(m);
132 #endif
133 }
134 
135 
136 static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
137 
146 static inline rte_iova_t
147 rte_mbuf_iova_get(const struct rte_mbuf *m)
148 {
149 #if RTE_IOVA_IN_MBUF
150  return m->buf_iova;
151 #else
152  return (rte_iova_t)m->buf_addr;
153 #endif
154 }
155 
164 static inline void
166 {
167 #if RTE_IOVA_IN_MBUF
168  m->buf_iova = iova;
169 #else
170  RTE_SET_USED(m);
171  RTE_SET_USED(iova);
172 #endif
173 }
174 
183 static inline rte_iova_t
184 rte_mbuf_data_iova(const struct rte_mbuf *mb)
185 {
186  return rte_mbuf_iova_get(mb) + mb->data_off;
187 }
188 
201 static inline rte_iova_t
203 {
204  return rte_mbuf_iova_get(mb) + RTE_PKTMBUF_HEADROOM;
205 }
206 
215 static inline struct rte_mbuf *
217 {
218  return (struct rte_mbuf *)RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size);
219 }
220 
236 static inline char *
237 rte_mbuf_buf_addr(struct rte_mbuf *mb, struct rte_mempool *mp)
238 {
239  return (char *)mb + sizeof(*mb) + rte_pktmbuf_priv_size(mp);
240 }
241 
250 static inline char *
252 {
253  return rte_mbuf_buf_addr(mb, mb->pool) + RTE_PKTMBUF_HEADROOM;
254 }
255 
269 static inline char *
271 {
272  return rte_mbuf_buf_addr(md, md->pool);
273 }
274 
287 static inline void *
289 {
290  return RTE_PTR_ADD(m, sizeof(struct rte_mbuf));
291 }
292 
301  uint16_t mbuf_priv_size;
302  uint32_t flags;
303 };
304 
313 static inline uint32_t
315 {
316  struct rte_pktmbuf_pool_private *mbp_priv;
317 
318  mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
319  return mbp_priv->flags;
320 }
321 
328 #define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF (1 << 0)
329 
337 #define RTE_MBUF_HAS_PINNED_EXTBUF(mb) \
338  (rte_pktmbuf_priv_flags(mb->pool) & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF)
339 
340 #ifdef RTE_LIBRTE_MBUF_DEBUG
341 
343 #define __rte_mbuf_sanity_check(m, is_h) rte_mbuf_sanity_check(m, is_h)
344 
345 #else /* RTE_LIBRTE_MBUF_DEBUG */
346 
348 #define __rte_mbuf_sanity_check(m, is_h) do { } while (0)
349 
350 #endif /* RTE_LIBRTE_MBUF_DEBUG */
351 
352 #ifdef RTE_MBUF_REFCNT_ATOMIC
353 
361 static inline uint16_t
362 rte_mbuf_refcnt_read(const struct rte_mbuf *m)
363 {
364  return rte_atomic_load_explicit(&m->refcnt, rte_memory_order_relaxed);
365 }
366 
374 static inline void
375 rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
376 {
377  rte_atomic_store_explicit(&m->refcnt, new_value, rte_memory_order_relaxed);
378 }
379 
380 /* internal */
381 static inline uint16_t
382 __rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
383 {
384  return rte_atomic_fetch_add_explicit(&m->refcnt, value,
385  rte_memory_order_acq_rel) + value;
386 }
387 
397 static inline uint16_t
398 rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
399 {
400  /*
401  * The atomic_add is an expensive operation, so we don't want to
402  * call it in the case where we know we are the unique holder of
403  * this mbuf (i.e. ref_cnt == 1). Otherwise, an atomic
404  * operation has to be used because concurrent accesses on the
405  * reference counter can occur.
406  */
407  if (likely(rte_mbuf_refcnt_read(m) == 1)) {
408  ++value;
409  rte_mbuf_refcnt_set(m, (uint16_t)value);
410  return (uint16_t)value;
411  }
412 
413  return __rte_mbuf_refcnt_update(m, value);
414 }
415 
416 #else /* ! RTE_MBUF_REFCNT_ATOMIC */
417 
418 /* internal */
419 static inline uint16_t
420 __rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
421 {
422  m->refcnt = (uint16_t)(m->refcnt + value);
423  return m->refcnt;
424 }
425 
429 static inline uint16_t
430 rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
431 {
432  return __rte_mbuf_refcnt_update(m, value);
433 }
434 
438 static inline uint16_t
440 {
441  return m->refcnt;
442 }
443 
447 static inline void
448 rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
449 {
450  m->refcnt = new_value;
451 }
452 
453 #endif /* RTE_MBUF_REFCNT_ATOMIC */
454 
463 static inline uint16_t
465 {
466  return rte_atomic_load_explicit(&shinfo->refcnt, rte_memory_order_relaxed);
467 }
468 
477 static inline void
479  uint16_t new_value)
480 {
481  rte_atomic_store_explicit(&shinfo->refcnt, new_value, rte_memory_order_relaxed);
482 }
483 
495 static inline uint16_t
497  int16_t value)
498 {
499  if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1)) {
500  ++value;
501  rte_mbuf_ext_refcnt_set(shinfo, (uint16_t)value);
502  return (uint16_t)value;
503  }
504 
505  return rte_atomic_fetch_add_explicit(&shinfo->refcnt, value,
506  rte_memory_order_acq_rel) + value;
507 }
508 
510 #define RTE_MBUF_PREFETCH_TO_FREE(m) do { \
511  if ((m) != NULL) \
512  rte_prefetch0(m); \
513 } while (0)
514 
515 
528 void
529 rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
530 
550 int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
551  const char **reason);
552 
565 static __rte_always_inline void
567 {
568  RTE_ASSERT(rte_mbuf_refcnt_read(m) == 1);
569  RTE_ASSERT(m->next == NULL);
570  RTE_ASSERT(m->nb_segs == 1);
572 }
573 
575 #define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_sanity_check(m)
576 
596 static inline struct rte_mbuf *rte_mbuf_raw_alloc(struct rte_mempool *mp)
597 {
598  union {
599  void *ptr;
600  struct rte_mbuf *m;
601  } ret;
602 
603  if (rte_mempool_get(mp, &ret.ptr) < 0)
604  return NULL;
606  return ret.m;
607 }
608 
623 static __rte_always_inline void
625 {
626  RTE_ASSERT(!RTE_MBUF_CLONED(m) &&
629  rte_mempool_put(m->pool, m);
630 }
631 
654 void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
655  void *m, unsigned i);
656 
677 void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
678 
712 struct rte_mempool *
713 rte_pktmbuf_pool_create(const char *name, unsigned n,
714  unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
715  int socket_id);
716 
753 struct rte_mempool *
754 rte_pktmbuf_pool_create_by_ops(const char *name, unsigned int n,
755  unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
756  int socket_id, const char *ops_name);
757 
760  void *buf_ptr;
762  size_t buf_len;
763  uint16_t elt_size;
764 };
765 
806 struct rte_mempool *
807 rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n,
808  unsigned int cache_size, uint16_t priv_size,
809  uint16_t data_room_size, int socket_id,
810  const struct rte_pktmbuf_extmem *ext_mem,
811  unsigned int ext_num);
812 
824 static inline uint16_t
826 {
827  struct rte_pktmbuf_pool_private *mbp_priv;
828 
829  mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
830  return mbp_priv->mbuf_data_room_size;
831 }
832 
845 static inline uint16_t
847 {
848  struct rte_pktmbuf_pool_private *mbp_priv;
849 
850  mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
851  return mbp_priv->mbuf_priv_size;
852 }
853 
862 static inline void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
863 {
864  m->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM,
865  (uint16_t)m->buf_len);
866 }
867 
876 static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
877 {
878  m->next = NULL;
879  m->pkt_len = 0;
880  m->tx_offload = 0;
881  m->vlan_tci = 0;
882  m->vlan_tci_outer = 0;
883  m->nb_segs = 1;
885 
887  m->packet_type = 0;
889 
890  m->data_len = 0;
892 }
893 
907 static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
908 {
909  struct rte_mbuf *m;
910  if ((m = rte_mbuf_raw_alloc(mp)) != NULL)
912  return m;
913 }
914 
929 static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool,
930  struct rte_mbuf **mbufs, unsigned count)
931 {
932  unsigned idx = 0;
933  int rc;
934 
935  rc = rte_mempool_get_bulk(pool, (void **)mbufs, count);
936  if (unlikely(rc))
937  return rc;
938 
939  /* To understand duff's device on loop unwinding optimization, see
940  * https://en.wikipedia.org/wiki/Duff's_device.
941  * Here while() loop is used rather than do() while{} to avoid extra
942  * check if count is zero.
943  */
944  switch (count % 4) {
945  case 0:
946  while (idx != count) {
947  __rte_mbuf_raw_sanity_check(mbufs[idx]);
948  rte_pktmbuf_reset(mbufs[idx]);
949  idx++;
950  /* fall-through */
951  case 3:
952  __rte_mbuf_raw_sanity_check(mbufs[idx]);
953  rte_pktmbuf_reset(mbufs[idx]);
954  idx++;
955  /* fall-through */
956  case 2:
957  __rte_mbuf_raw_sanity_check(mbufs[idx]);
958  rte_pktmbuf_reset(mbufs[idx]);
959  idx++;
960  /* fall-through */
961  case 1:
962  __rte_mbuf_raw_sanity_check(mbufs[idx]);
963  rte_pktmbuf_reset(mbufs[idx]);
964  idx++;
965  /* fall-through */
966  }
967  }
968  return 0;
969 }
970 
1003 static inline struct rte_mbuf_ext_shared_info *
1004 rte_pktmbuf_ext_shinfo_init_helper(void *buf_addr, uint16_t *buf_len,
1006 {
1007  struct rte_mbuf_ext_shared_info *shinfo;
1008  void *buf_end = RTE_PTR_ADD(buf_addr, *buf_len);
1009  void *addr;
1010 
1011  addr = RTE_PTR_ALIGN_FLOOR(RTE_PTR_SUB(buf_end, sizeof(*shinfo)),
1012  sizeof(uintptr_t));
1013  if (addr <= buf_addr)
1014  return NULL;
1015 
1016  shinfo = (struct rte_mbuf_ext_shared_info *)addr;
1017  shinfo->free_cb = free_cb;
1018  shinfo->fcb_opaque = fcb_opaque;
1019  rte_mbuf_ext_refcnt_set(shinfo, 1);
1020 
1021  *buf_len = (uint16_t)RTE_PTR_DIFF(shinfo, buf_addr);
1022  return shinfo;
1023 }
1024 
1085 static inline void
1086 rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
1087  rte_iova_t buf_iova, uint16_t buf_len,
1088  struct rte_mbuf_ext_shared_info *shinfo)
1089 {
1090  /* mbuf should not be read-only */
1091  RTE_ASSERT(RTE_MBUF_DIRECT(m) && rte_mbuf_refcnt_read(m) == 1);
1092  RTE_ASSERT(shinfo->free_cb != NULL);
1093 
1094  m->buf_addr = buf_addr;
1095  rte_mbuf_iova_set(m, buf_iova);
1096  m->buf_len = buf_len;
1097 
1098  m->data_len = 0;
1099  m->data_off = 0;
1100 
1102  m->shinfo = shinfo;
1103 }
1104 
1112 #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
1113 
1122 static inline void
1123 rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
1124 {
1125 #if !RTE_IOVA_IN_MBUF
1126  mdst->dynfield2 = msrc->dynfield2;
1127 #endif
1128  memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1));
1129 }
1130 
1131 /* internal */
1132 static inline void
1133 __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
1134 {
1135  mdst->port = msrc->port;
1136  mdst->vlan_tci = msrc->vlan_tci;
1137  mdst->vlan_tci_outer = msrc->vlan_tci_outer;
1138  mdst->tx_offload = msrc->tx_offload;
1139  mdst->hash = msrc->hash;
1140  mdst->packet_type = msrc->packet_type;
1141  rte_mbuf_dynfield_copy(mdst, msrc);
1142 }
1143 
1165 static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
1166 {
1167  RTE_ASSERT(RTE_MBUF_DIRECT(mi) &&
1168  rte_mbuf_refcnt_read(mi) == 1);
1169 
1170  if (RTE_MBUF_HAS_EXTBUF(m)) {
1172  mi->ol_flags = m->ol_flags;
1173  mi->shinfo = m->shinfo;
1174  } else {
1175  /* if m is not direct, get the mbuf that embeds the data */
1177  mi->priv_size = m->priv_size;
1179  }
1180 
1181  __rte_pktmbuf_copy_hdr(mi, m);
1182 
1183  mi->data_off = m->data_off;
1184  mi->data_len = m->data_len;
1186  mi->buf_addr = m->buf_addr;
1187  mi->buf_len = m->buf_len;
1188 
1189  mi->next = NULL;
1190  mi->pkt_len = mi->data_len;
1191  mi->nb_segs = 1;
1192 
1193  __rte_mbuf_sanity_check(mi, 1);
1195 }
1196 
1204 static inline void
1205 __rte_pktmbuf_free_extbuf(struct rte_mbuf *m)
1206 {
1207  RTE_ASSERT(RTE_MBUF_HAS_EXTBUF(m));
1208  RTE_ASSERT(m->shinfo != NULL);
1209 
1210  if (rte_mbuf_ext_refcnt_update(m->shinfo, -1) == 0)
1211  m->shinfo->free_cb(m->buf_addr, m->shinfo->fcb_opaque);
1212 }
1213 
1220 static inline void
1221 __rte_pktmbuf_free_direct(struct rte_mbuf *m)
1222 {
1223  struct rte_mbuf *md;
1224 
1225  RTE_ASSERT(RTE_MBUF_CLONED(m));
1226 
1227  md = rte_mbuf_from_indirect(m);
1228 
1229  if (rte_mbuf_refcnt_update(md, -1) == 0) {
1230  md->next = NULL;
1231  md->nb_segs = 1;
1232  rte_mbuf_refcnt_set(md, 1);
1233  rte_mbuf_raw_free(md);
1234  }
1235 }
1236 
1255 static inline void rte_pktmbuf_detach(struct rte_mbuf *m)
1256 {
1257  struct rte_mempool *mp = m->pool;
1258  uint32_t mbuf_size, buf_len;
1259  uint16_t priv_size;
1260 
1261  if (RTE_MBUF_HAS_EXTBUF(m)) {
1262  /*
1263  * The mbuf has the external attached buffer,
1264  * we should check the type of the memory pool where
1265  * the mbuf was allocated from to detect the pinned
1266  * external buffer.
1267  */
1268  uint32_t flags = rte_pktmbuf_priv_flags(mp);
1269 
1270  if (flags & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF) {
1271  /*
1272  * The pinned external buffer should not be
1273  * detached from its backing mbuf, just exit.
1274  */
1275  return;
1276  }
1277  __rte_pktmbuf_free_extbuf(m);
1278  } else {
1279  __rte_pktmbuf_free_direct(m);
1280  }
1281  priv_size = rte_pktmbuf_priv_size(mp);
1282  mbuf_size = (uint32_t)(sizeof(struct rte_mbuf) + priv_size);
1283  buf_len = rte_pktmbuf_data_room_size(mp);
1284 
1285  m->priv_size = priv_size;
1286  m->buf_addr = (char *)m + mbuf_size;
1287  rte_mbuf_iova_set(m, rte_mempool_virt2iova(m) + mbuf_size);
1288  m->buf_len = (uint16_t)buf_len;
1290  m->data_len = 0;
1291  m->ol_flags = 0;
1292 }
1293 
1307 static inline int __rte_pktmbuf_pinned_extbuf_decref(struct rte_mbuf *m)
1308 {
1309  struct rte_mbuf_ext_shared_info *shinfo;
1310 
1311  /* Clear flags, mbuf is being freed. */
1313  shinfo = m->shinfo;
1314 
1315  /* Optimize for performance - do not dec/reinit */
1316  if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1))
1317  return 0;
1318 
1319  /*
1320  * Direct usage of add primitive to avoid
1321  * duplication of comparing with one.
1322  */
1323  if (likely(rte_atomic_fetch_add_explicit(&shinfo->refcnt, -1,
1324  rte_memory_order_acq_rel) - 1))
1325  return 1;
1326 
1327  /* Reinitialize counter before mbuf freeing. */
1328  rte_mbuf_ext_refcnt_set(shinfo, 1);
1329  return 0;
1330 }
1331 
1346 static __rte_always_inline struct rte_mbuf *
1348 {
1350 
1351  if (likely(rte_mbuf_refcnt_read(m) == 1)) {
1352 
1353  if (!RTE_MBUF_DIRECT(m)) {
1354  rte_pktmbuf_detach(m);
1355  if (RTE_MBUF_HAS_EXTBUF(m) &&
1357  __rte_pktmbuf_pinned_extbuf_decref(m))
1358  return NULL;
1359  }
1360 
1361  if (m->next != NULL)
1362  m->next = NULL;
1363  if (m->nb_segs != 1)
1364  m->nb_segs = 1;
1365 
1366  return m;
1367 
1368  } else if (__rte_mbuf_refcnt_update(m, -1) == 0) {
1369 
1370  if (!RTE_MBUF_DIRECT(m)) {
1371  rte_pktmbuf_detach(m);
1372  if (RTE_MBUF_HAS_EXTBUF(m) &&
1374  __rte_pktmbuf_pinned_extbuf_decref(m))
1375  return NULL;
1376  }
1377 
1378  if (m->next != NULL)
1379  m->next = NULL;
1380  if (m->nb_segs != 1)
1381  m->nb_segs = 1;
1382  rte_mbuf_refcnt_set(m, 1);
1383 
1384  return m;
1385  }
1386  return NULL;
1387 }
1388 
1398 static __rte_always_inline void
1400 {
1401  m = rte_pktmbuf_prefree_seg(m);
1402  if (likely(m != NULL))
1403  rte_mbuf_raw_free(m);
1404 }
1405 
1415 static inline void rte_pktmbuf_free(struct rte_mbuf *m)
1416 {
1417  struct rte_mbuf *m_next;
1418 
1419  if (m != NULL)
1421 
1422  while (m != NULL) {
1423  m_next = m->next;
1425  m = m_next;
1426  }
1427 }
1428 
1441 void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count);
1442 
1460 struct rte_mbuf *
1461 rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp);
1462 
1484 struct rte_mbuf *
1485 rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
1486  uint32_t offset, uint32_t length);
1487 
1499 static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
1500 {
1502 
1503  do {
1504  rte_mbuf_refcnt_update(m, v);
1505  } while ((m = m->next) != NULL);
1506 }
1507 
1516 static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
1517 {
1519  return m->data_off;
1520 }
1521 
1530 static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
1531 {
1533  return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) -
1534  m->data_len);
1535 }
1536 
1545 static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
1546 {
1548  while (m->next != NULL)
1549  m = m->next;
1550  return m;
1551 }
1552 
1561 #define rte_pktmbuf_pkt_len(m) ((m)->pkt_len)
1562 
1571 #define rte_pktmbuf_data_len(m) ((m)->data_len)
1572 
1588 static inline char *rte_pktmbuf_prepend(struct rte_mbuf *m,
1589  uint16_t len)
1590 {
1592 
1593  if (unlikely(len > rte_pktmbuf_headroom(m)))
1594  return NULL;
1595 
1596  /* NB: elaborating the subtraction like this instead of using
1597  * -= allows us to ensure the result type is uint16_t
1598  * avoiding compiler warnings on gcc 8.1 at least */
1599  m->data_off = (uint16_t)(m->data_off - len);
1600  m->data_len = (uint16_t)(m->data_len + len);
1601  m->pkt_len = (m->pkt_len + len);
1602 
1603  return (char *)m->buf_addr + m->data_off;
1604 }
1605 
1621 static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
1622 {
1623  void *tail;
1624  struct rte_mbuf *m_last;
1625 
1627 
1628  m_last = rte_pktmbuf_lastseg(m);
1629  if (unlikely(len > rte_pktmbuf_tailroom(m_last)))
1630  return NULL;
1631 
1632  tail = (char *)m_last->buf_addr + m_last->data_off + m_last->data_len;
1633  m_last->data_len = (uint16_t)(m_last->data_len + len);
1634  m->pkt_len = (m->pkt_len + len);
1635  return (char*) tail;
1636 }
1637 
1652 static inline char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
1653 {
1655 
1656  if (unlikely(len > m->data_len))
1657  return NULL;
1658 
1659  /* NB: elaborating the addition like this instead of using
1660  * += allows us to ensure the result type is uint16_t
1661  * avoiding compiler warnings on gcc 8.1 at least */
1662  m->data_len = (uint16_t)(m->data_len - len);
1663  m->data_off = (uint16_t)(m->data_off + len);
1664  m->pkt_len = (m->pkt_len - len);
1665  return (char *)m->buf_addr + m->data_off;
1666 }
1667 
1682 static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
1683 {
1684  struct rte_mbuf *m_last;
1685 
1687 
1688  m_last = rte_pktmbuf_lastseg(m);
1689  if (unlikely(len > m_last->data_len))
1690  return -1;
1691 
1692  m_last->data_len = (uint16_t)(m_last->data_len - len);
1693  m->pkt_len = (m->pkt_len - len);
1694  return 0;
1695 }
1696 
1706 static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
1707 {
1709  return m->nb_segs == 1;
1710 }
1711 
1715 const void *__rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off,
1716  uint32_t len, void *buf);
1717 
1738 static inline const void *rte_pktmbuf_read(const struct rte_mbuf *m,
1739  uint32_t off, uint32_t len, void *buf)
1740 {
1741  if (likely(off + len <= rte_pktmbuf_data_len(m)))
1742  return rte_pktmbuf_mtod_offset(m, char *, off);
1743  else
1744  return __rte_pktmbuf_read(m, off, len, buf);
1745 }
1746 
1763 static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
1764 {
1765  struct rte_mbuf *cur_tail;
1766 
1767  /* Check for number-of-segments-overflow */
1768  if (head->nb_segs + tail->nb_segs > RTE_MBUF_MAX_NB_SEGS)
1769  return -EOVERFLOW;
1770 
1771  /* Chain 'tail' onto the old tail */
1772  cur_tail = rte_pktmbuf_lastseg(head);
1773  cur_tail->next = tail;
1774 
1775  /* accumulate number of segments and total length.
1776  * NB: elaborating the addition like this instead of using
1777  * -= allows us to ensure the result type is uint16_t
1778  * avoiding compiler warnings on gcc 8.1 at least */
1779  head->nb_segs = (uint16_t)(head->nb_segs + tail->nb_segs);
1780  head->pkt_len += tail->pkt_len;
1781 
1782  /* pkt_len is only set in the head */
1783  tail->pkt_len = tail->data_len;
1784 
1785  return 0;
1786 }
1787 
1809 static __rte_always_inline uint64_t
1810 rte_mbuf_tx_offload(uint64_t il2, uint64_t il3, uint64_t il4, uint64_t tso,
1811  uint64_t ol3, uint64_t ol2, uint64_t unused)
1812 {
1813  return il2 << RTE_MBUF_L2_LEN_OFS |
1814  il3 << RTE_MBUF_L3_LEN_OFS |
1815  il4 << RTE_MBUF_L4_LEN_OFS |
1816  tso << RTE_MBUF_TSO_SEGSZ_OFS |
1817  ol3 << RTE_MBUF_OUTL3_LEN_OFS |
1818  ol2 << RTE_MBUF_OUTL2_LEN_OFS |
1819  unused << RTE_MBUF_TXOFLD_UNUSED_OFS;
1820 }
1821 
1832 static inline int
1834 {
1835  uint64_t ol_flags = m->ol_flags;
1836 
1837  /* Does packet set any of available offloads? */
1838  if (!(ol_flags & RTE_MBUF_F_TX_OFFLOAD_MASK))
1839  return 0;
1840 
1841  /* IP checksum can be counted only for IPv4 packet */
1842  if ((ol_flags & RTE_MBUF_F_TX_IP_CKSUM) && (ol_flags & RTE_MBUF_F_TX_IPV6))
1843  return -EINVAL;
1844 
1845  /* IP type not set when required */
1846  if (ol_flags & (RTE_MBUF_F_TX_L4_MASK | RTE_MBUF_F_TX_TCP_SEG))
1847  if (!(ol_flags & (RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IPV6)))
1848  return -EINVAL;
1849 
1850  /* Check requirements for TSO packet */
1851  if (ol_flags & RTE_MBUF_F_TX_TCP_SEG)
1852  if ((m->tso_segsz == 0) ||
1853  ((ol_flags & RTE_MBUF_F_TX_IPV4) &&
1854  !(ol_flags & RTE_MBUF_F_TX_IP_CKSUM)))
1855  return -EINVAL;
1856 
1857  /* RTE_MBUF_F_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */
1858  if ((ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM) &&
1859  !(ol_flags & RTE_MBUF_F_TX_OUTER_IPV4))
1860  return -EINVAL;
1861 
1862  return 0;
1863 }
1864 
1868 int __rte_pktmbuf_linearize(struct rte_mbuf *mbuf);
1869 
1882 static inline int
1884 {
1885  if (rte_pktmbuf_is_contiguous(mbuf))
1886  return 0;
1887  return __rte_pktmbuf_linearize(mbuf);
1888 }
1889 
1904 void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
1905 
1909 static inline uint32_t
1911 {
1912  return m->hash.sched.queue_id;
1913 }
1914 
1918 static inline uint8_t
1920 {
1921  return m->hash.sched.traffic_class;
1922 }
1923 
1927 static inline uint8_t
1929 {
1930  return m->hash.sched.color;
1931 }
1932 
1945 static inline void
1946 rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
1947  uint8_t *traffic_class,
1948  uint8_t *color)
1949 {
1950  struct rte_mbuf_sched sched = m->hash.sched;
1951 
1952  *queue_id = sched.queue_id;
1953  *traffic_class = sched.traffic_class;
1954  *color = sched.color;
1955 }
1956 
1960 static inline void
1962 {
1963  m->hash.sched.queue_id = queue_id;
1964 }
1965 
1969 static inline void
1971 {
1972  m->hash.sched.traffic_class = traffic_class;
1973 }
1974 
1978 static inline void
1980 {
1981  m->hash.sched.color = color;
1982 }
1983 
1996 static inline void
1998  uint8_t traffic_class,
1999  uint8_t color)
2000 {
2001  m->hash.sched = (struct rte_mbuf_sched){
2002  .queue_id = queue_id,
2003  .traffic_class = traffic_class,
2004  .color = color,
2005  .reserved = 0,
2006  };
2007 }
2008 
2009 #ifdef __cplusplus
2010 }
2011 #endif
2012 
2013 #endif /* _RTE_MBUF_H_ */
static void rte_pktmbuf_reset(struct rte_mbuf *m)
Definition: rte_mbuf.h:876
struct rte_mbuf_ext_shared_info * shinfo
static rte_iova_t rte_mbuf_data_iova(const struct rte_mbuf *mb)
Definition: rte_mbuf.h:184
struct rte_mbuf * next
uint16_t mbuf_data_room_size
Definition: rte_mbuf.h:300
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:404
#define RTE_MBUF_F_TX_OFFLOAD_MASK
static struct rte_mbuf * rte_pktmbuf_alloc(struct rte_mempool *mp)
Definition: rte_mbuf.h:907
static void rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
Definition: rte_mbuf.h:1970
static uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp)
Definition: rte_mbuf.h:846
static int rte_validate_tx_offload(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1833
uint32_t queue_id
#define likely(x)
static void rte_pktmbuf_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:1415
static uint32_t rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1910
#define RTE_PTR_ALIGN_FLOOR(ptr, align)
Definition: rte_common.h:473
void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
uint64_t rte_iova_t
Definition: rte_common.h:633
static __rte_always_inline void rte_pktmbuf_free_seg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1399
void * buf_addr
static struct rte_mbuf * rte_mbuf_from_indirect(struct rte_mbuf *mi)
Definition: rte_mbuf.h:216
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:1763
static uint8_t rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1919
#define __rte_unused
Definition: rte_common.h:171
static void rte_mbuf_iova_set(struct rte_mbuf *m, rte_iova_t iova)
Definition: rte_mbuf.h:165
#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)
static __rte_always_inline void __rte_mbuf_raw_sanity_check(__rte_unused const struct rte_mbuf *m)
Definition: rte_mbuf.h:566
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:1516
static int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool, struct rte_mbuf **mbufs, unsigned count)
Definition: rte_mbuf.h:929
static void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
Definition: rte_mbuf.h:862
static void * rte_mbuf_to_priv(struct rte_mbuf *m)
Definition: rte_mbuf.h:288
uint32_t cache_size
Definition: rte_mempool.h:241
static void rte_mbuf_prefetch_part2(struct rte_mbuf *m)
Definition: rte_mbuf.h:126
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:496
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:1347
static int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1706
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:444
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:1997
static uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1530
static __rte_always_inline void rte_mbuf_raw_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:624
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:1946
#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:1810
static void rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
Definition: rte_mbuf.h:1961
static char * rte_mbuf_buf_addr(struct rte_mbuf *mb, struct rte_mempool *mp)
Definition: rte_mbuf.h:237
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:1979
void(* rte_mbuf_extbuf_free_callback_t)(void *addr, void *opaque)
#define RTE_MIN(a, b)
Definition: rte_common.h:658
uint64_t dynfield2
#define __rte_mbuf_sanity_check(m, is_h)
Definition: rte_mbuf.h:348
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:439
static int rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
Definition: rte_mbuf.h:1883
static __rte_always_inline int rte_mempool_get(struct rte_mempool *mp, void **obj_p)
Definition: rte_mempool.h:1708
static uint32_t rte_pktmbuf_priv_flags(struct rte_mempool *mp)
Definition: rte_mbuf.h:314
uint16_t elt_size
Definition: rte_mbuf.h:763
uint16_t refcnt
static char * rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1652
#define RTE_MBUF_DIRECT(mb)
#define RTE_MBUF_CLONED(mb)
#define RTE_CACHE_LINE_MIN_SIZE
Definition: rte_common.h:599
static void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
Definition: rte_mbuf.h:1165
static __rte_always_inline int rte_mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned int n)
Definition: rte_mempool.h:1679
#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:1123
static void rte_pktmbuf_detach(struct rte_mbuf *m)
Definition: rte_mbuf.h:1255
static uint16_t rte_mbuf_ext_refcnt_read(const struct rte_mbuf_ext_shared_info *shinfo)
Definition: rte_mbuf.h:464
uint32_t pkt_len
uint16_t buf_len
#define rte_pktmbuf_data_len(m)
Definition: rte_mbuf.h:1571
#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:430
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:825
#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:1004
#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:478
static char * rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1621
static void rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
Definition: rte_mbuf.h:448
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:202
static int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1682
static char * rte_mbuf_to_baddr(struct rte_mbuf *md)
Definition: rte_mbuf.h:270
static const void * rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off, uint32_t len, void *buf)
Definition: rte_mbuf.h:1738
static char * rte_pktmbuf_prepend(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1588
static struct rte_mbuf * rte_mbuf_raw_alloc(struct rte_mempool *mp)
Definition: rte_mbuf.h:596
static rte_iova_t rte_mbuf_iova_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:147
static void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
Definition: rte_mbuf.h:1499
#define RTE_PTR_SUB(ptr, x)
Definition: rte_common.h:449
static struct rte_mbuf * rte_pktmbuf_lastseg(struct rte_mbuf *m)
Definition: rte_mbuf.h:1545
static uint8_t rte_mbuf_sched_color_get(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1928
#define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF
Definition: rte_mbuf.h:328
static char * rte_mbuf_data_addr_default(struct rte_mbuf *mb)
Definition: rte_mbuf.h:251
static rte_iova_t rte_mempool_virt2iova(const void *elt)
Definition: rte_mempool.h:1833
static __rte_always_inline void rte_mempool_put(struct rte_mempool *mp, void *obj)
Definition: rte_mempool.h:1487
rte_iova_t buf_iova
Definition: rte_mbuf.h:761
uint8_t traffic_class
#define RTE_MBUF_F_TX_IPV4
#define RTE_PTR_DIFF(ptr1, ptr2)
Definition: rte_common.h:456
static void rte_mbuf_prefetch_part1(struct rte_mbuf *m)
Definition: rte_mbuf.h:109
#define RTE_MBUF_F_EXTERNAL
static void * rte_mempool_get_priv(struct rte_mempool *mp)
Definition: rte_mempool.h:1861
uint64_t tx_offload
uint16_t vlan_tci
#define RTE_MBUF_HAS_PINNED_EXTBUF(mb)
Definition: rte_mbuf.h:337
struct rte_mbuf * rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp)
#define RTE_SET_USED(x)
Definition: rte_common.h:187
int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen)
static void rte_prefetch0(const volatile void *p)
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:1086