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