LCOV - code coverage report
Current view: top level - lib/mbuf - rte_mbuf.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 206 237 86.9 %
Date: 2025-11-01 17:50:34 Functions: 16 31 51.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 295 2060 14.3 %

           Branch data     Line data    Source code
       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                 :            : 
       9                 :            : /**
      10                 :            :  * @file
      11                 :            :  * RTE Mbuf
      12                 :            :  *
      13                 :            :  * The mbuf library provides the ability to create and destroy buffers
      14                 :            :  * that may be used by the RTE application to store message
      15                 :            :  * buffers. The message buffers are stored in a mempool, using the
      16                 :            :  * RTE mempool library.
      17                 :            :  *
      18                 :            :  * The preferred way to create a mbuf pool is to use
      19                 :            :  * rte_pktmbuf_pool_create(). However, in some situations, an
      20                 :            :  * application may want to have more control (ex: populate the pool with
      21                 :            :  * specific memory), in this case it is possible to use functions from
      22                 :            :  * rte_mempool. See how rte_pktmbuf_pool_create() is implemented for
      23                 :            :  * details.
      24                 :            :  *
      25                 :            :  * This library provides an API to allocate/free packet mbufs, which are
      26                 :            :  * used to carry network packets.
      27                 :            :  *
      28                 :            :  * To understand the concepts of packet buffers or mbufs, you
      29                 :            :  * should read "TCP/IP Illustrated, Volume 2: The Implementation,
      30                 :            :  * Addison-Wesley, 1995, ISBN 0-201-63354-X from Richard Stevens"
      31                 :            :  * http://www.kohala.com/start/tcpipiv2.html
      32                 :            :  */
      33                 :            : 
      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                 :            : 
      50                 :            : /**
      51                 :            :  * Get the name of a RX offload flag
      52                 :            :  *
      53                 :            :  * @param mask
      54                 :            :  *   The mask describing the flag.
      55                 :            :  * @return
      56                 :            :  *   The name of this flag, or NULL if it's not a valid RX flag.
      57                 :            :  */
      58                 :            : const char *rte_get_rx_ol_flag_name(uint64_t mask);
      59                 :            : 
      60                 :            : /**
      61                 :            :  * Dump the list of RX offload flags in a buffer
      62                 :            :  *
      63                 :            :  * @param mask
      64                 :            :  *   The mask describing the RX flags.
      65                 :            :  * @param buf
      66                 :            :  *   The output buffer.
      67                 :            :  * @param buflen
      68                 :            :  *   The length of the buffer.
      69                 :            :  * @return
      70                 :            :  *   0 on success, (-1) on error.
      71                 :            :  */
      72                 :            : int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen);
      73                 :            : 
      74                 :            : /**
      75                 :            :  * Get the name of a TX offload flag
      76                 :            :  *
      77                 :            :  * @param mask
      78                 :            :  *   The mask describing the flag. Usually only one bit must be set.
      79                 :            :  *   Several bits can be given if they belong to the same mask.
      80                 :            :  *   Ex: RTE_MBUF_F_TX_L4_MASK.
      81                 :            :  * @return
      82                 :            :  *   The name of this flag, or NULL if it's not a valid TX flag.
      83                 :            :  */
      84                 :            : const char *rte_get_tx_ol_flag_name(uint64_t mask);
      85                 :            : 
      86                 :            : /**
      87                 :            :  * Dump the list of TX offload flags in a buffer
      88                 :            :  *
      89                 :            :  * @param mask
      90                 :            :  *   The mask describing the TX flags.
      91                 :            :  * @param buf
      92                 :            :  *   The output buffer.
      93                 :            :  * @param buflen
      94                 :            :  *   The length of the buffer.
      95                 :            :  * @return
      96                 :            :  *   0 on success, (-1) on error.
      97                 :            :  */
      98                 :            : int rte_get_tx_ol_flag_list(uint64_t mask, char *buf, size_t buflen);
      99                 :            : 
     100                 :            : /**
     101                 :            :  * Prefetch the first part of the mbuf
     102                 :            :  *
     103                 :            :  * The first 64 bytes of the mbuf corresponds to fields that are used early
     104                 :            :  * in the receive path. If the cache line of the architecture is higher than
     105                 :            :  * 64B, the second part will also be prefetched.
     106                 :            :  *
     107                 :            :  * @param m
     108                 :            :  *   The pointer to the mbuf.
     109                 :            :  */
     110                 :            : static inline void
     111                 :            : rte_mbuf_prefetch_part1(struct rte_mbuf *m)
     112                 :            : {
     113                 :            :         rte_prefetch0(m);
     114                 :          0 : }
     115                 :            : 
     116                 :            : /**
     117                 :            :  * Prefetch the second part of the mbuf
     118                 :            :  *
     119                 :            :  * The next 64 bytes of the mbuf corresponds to fields that are used in the
     120                 :            :  * transmit path. If the cache line of the architecture is higher than 64B,
     121                 :            :  * this function does nothing as it is expected that the full mbuf is
     122                 :            :  * already in cache.
     123                 :            :  *
     124                 :            :  * @param m
     125                 :            :  *   The pointer to the mbuf.
     126                 :            :  */
     127                 :            : static inline void
     128                 :            : rte_mbuf_prefetch_part2(struct rte_mbuf *m)
     129                 :            : {
     130                 :            : #if RTE_CACHE_LINE_SIZE == 64
     131                 :          0 :         rte_prefetch0(RTE_PTR_ADD(m, RTE_CACHE_LINE_MIN_SIZE));
     132                 :            : #else
     133                 :            :         RTE_SET_USED(m);
     134                 :            : #endif
     135                 :          0 : }
     136                 :            : 
     137                 :            : 
     138                 :            : static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
     139                 :            : 
     140                 :            : /**
     141                 :            :  * Get the IOVA address of the mbuf data buffer.
     142                 :            :  *
     143                 :            :  * @param m
     144                 :            :  *   The pointer to the mbuf.
     145                 :            :  * @return
     146                 :            :  *   The IOVA address of the mbuf.
     147                 :            :  */
     148                 :            : static inline rte_iova_t
     149                 :          0 : rte_mbuf_iova_get(const struct rte_mbuf *m)
     150                 :            : {
     151                 :            : #if RTE_IOVA_IN_MBUF
     152   [ +  +  -  +  :        421 :         return m->buf_iova;
          -  +  -  +  -  
          +  -  -  +  +  
          +  +  -  +  -  
          -  -  -  -  +  
          -  +  -  -  -  
                      - ]
     153                 :            : #else
     154                 :            :         return (rte_iova_t)m->buf_addr;
     155                 :            : #endif
     156                 :            : }
     157                 :            : 
     158                 :            : /**
     159                 :            :  * Set the IOVA address of the mbuf data buffer.
     160                 :            :  *
     161                 :            :  * @param m
     162                 :            :  *   The pointer to the mbuf.
     163                 :            :  * @param iova
     164                 :            :  *   Value to set as IOVA address of the mbuf.
     165                 :            :  */
     166                 :            : static inline void
     167                 :          0 : rte_mbuf_iova_set(struct rte_mbuf *m, rte_iova_t iova)
     168                 :            : {
     169                 :            : #if RTE_IOVA_IN_MBUF
     170         [ +  + ]:        192 :         m->buf_iova = iova;
     171                 :            : #else
     172                 :            :         RTE_SET_USED(m);
     173                 :            :         RTE_SET_USED(iova);
     174                 :            : #endif
     175                 :          0 : }
     176                 :            : 
     177                 :            : /**
     178                 :            :  * Return the IO address of the beginning of the mbuf data
     179                 :            :  *
     180                 :            :  * @param mb
     181                 :            :  *   The pointer to the mbuf.
     182                 :            :  * @return
     183                 :            :  *   The IO address of the beginning of the mbuf data
     184                 :            :  */
     185                 :            : static inline rte_iova_t
     186                 :          0 : rte_mbuf_data_iova(const struct rte_mbuf *mb)
     187                 :            : {
     188   [ #  #  #  #  :          0 :         return rte_mbuf_iova_get(mb) + mb->data_off;
             #  #  #  # ]
     189                 :            : }
     190                 :            : 
     191                 :            : /**
     192                 :            :  * Return the default IO address of the beginning of the mbuf data
     193                 :            :  *
     194                 :            :  * This function is used by drivers in their receive function, as it
     195                 :            :  * returns the location where data should be written by the NIC, taking
     196                 :            :  * the default headroom in account.
     197                 :            :  *
     198                 :            :  * @param mb
     199                 :            :  *   The pointer to the mbuf.
     200                 :            :  * @return
     201                 :            :  *   The IO address of the beginning of the mbuf data
     202                 :            :  */
     203                 :            : static inline rte_iova_t
     204                 :            : rte_mbuf_data_iova_default(const struct rte_mbuf *mb)
     205                 :            : {
     206   [ #  #  #  #  :          0 :         return rte_mbuf_iova_get(mb) + RTE_PKTMBUF_HEADROOM;
             #  #  #  # ]
     207                 :            : }
     208                 :            : 
     209                 :            : /**
     210                 :            :  * Return the mbuf owning the data buffer address of an indirect mbuf.
     211                 :            :  *
     212                 :            :  * @param mi
     213                 :            :  *   The pointer to the indirect mbuf.
     214                 :            :  * @return
     215                 :            :  *   The address of the direct mbuf corresponding to buffer_addr.
     216                 :            :  */
     217                 :            : static inline struct rte_mbuf *
     218                 :            : rte_mbuf_from_indirect(struct rte_mbuf *mi)
     219                 :            : {
     220                 :         58 :         return (struct rte_mbuf *)RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size);
     221                 :            : }
     222                 :            : 
     223                 :            : /**
     224                 :            :  * Return address of buffer embedded in the given mbuf.
     225                 :            :  *
     226                 :            :  * The return value shall be same as mb->buf_addr if the mbuf is already
     227                 :            :  * initialized and direct. However, this API is useful if mempool of the
     228                 :            :  * mbuf is already known because it doesn't need to access mbuf contents in
     229                 :            :  * order to get the mempool pointer.
     230                 :            :  *
     231                 :            :  * @param mb
     232                 :            :  *   The pointer to the mbuf.
     233                 :            :  * @param mp
     234                 :            :  *   The pointer to the mempool of the mbuf.
     235                 :            :  * @return
     236                 :            :  *   The pointer of the mbuf buffer.
     237                 :            :  */
     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                 :            : 
     244                 :            : /**
     245                 :            :  * Return the default address of the beginning of the mbuf data.
     246                 :            :  *
     247                 :            :  * @param mb
     248                 :            :  *   The pointer to the mbuf.
     249                 :            :  * @return
     250                 :            :  *   The pointer of the beginning of the mbuf data.
     251                 :            :  */
     252                 :            : static inline char *
     253                 :            : rte_mbuf_data_addr_default(struct rte_mbuf *mb)
     254                 :            : {
     255                 :            :         return rte_mbuf_buf_addr(mb, mb->pool) + RTE_PKTMBUF_HEADROOM;
     256                 :            : }
     257                 :            : 
     258                 :            : /**
     259                 :            :  * Return address of buffer embedded in the given mbuf.
     260                 :            :  *
     261                 :            :  * @note: Accessing mempool pointer of a mbuf is expensive because the
     262                 :            :  * pointer is stored in the 2nd cache line of mbuf. If mempool is known, it
     263                 :            :  * is better not to reference the mempool pointer in mbuf but calling
     264                 :            :  * rte_mbuf_buf_addr() would be more efficient.
     265                 :            :  *
     266                 :            :  * @param md
     267                 :            :  *   The pointer to the mbuf.
     268                 :            :  * @return
     269                 :            :  *   The address of the data buffer owned by the mbuf.
     270                 :            :  */
     271                 :            : static inline char *
     272                 :            : rte_mbuf_to_baddr(struct rte_mbuf *md)
     273                 :            : {
     274                 :            :         return rte_mbuf_buf_addr(md, md->pool);
     275                 :            : }
     276                 :            : 
     277                 :            : /**
     278                 :            :  * Return the starting address of the private data area embedded in
     279                 :            :  * the given mbuf.
     280                 :            :  *
     281                 :            :  * Note that no check is made to ensure that a private data area
     282                 :            :  * actually exists in the supplied mbuf.
     283                 :            :  *
     284                 :            :  * @param m
     285                 :            :  *   The pointer to the mbuf.
     286                 :            :  * @return
     287                 :            :  *   The starting address of the private data area of the given mbuf.
     288                 :            :  */
     289                 :            : static inline void *
     290                 :          0 : rte_mbuf_to_priv(struct rte_mbuf *m)
     291                 :            : {
     292                 :          0 :         return RTE_PTR_ADD(m, sizeof(struct rte_mbuf));
     293                 :            : }
     294                 :            : 
     295                 :            : /**
     296                 :            :  * Private data in case of pktmbuf pool.
     297                 :            :  *
     298                 :            :  * A structure that contains some pktmbuf_pool-specific data that are
     299                 :            :  * appended after the mempool structure (in private data).
     300                 :            :  */
     301                 :            : struct rte_pktmbuf_pool_private {
     302                 :            :         uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf. */
     303                 :            :         uint16_t mbuf_priv_size;      /**< Size of private area in each mbuf. */
     304                 :            :         uint32_t flags; /**< reserved for future use. */
     305                 :            : };
     306                 :            : 
     307                 :            : /**
     308                 :            :  * Return the flags from private data in an mempool structure.
     309                 :            :  *
     310                 :            :  * @param mp
     311                 :            :  *   A pointer to the mempool structure.
     312                 :            :  * @return
     313                 :            :  *   The flags from the private data structure.
     314                 :            :  */
     315                 :            : static inline uint32_t
     316         [ #  # ]:          0 : rte_pktmbuf_priv_flags(struct rte_mempool *mp)
     317                 :            : {
     318                 :            :         struct rte_pktmbuf_pool_private *mbp_priv;
     319                 :            : 
     320                 :            :         mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
     321   [ +  +  +  + ]:       3401 :         return mbp_priv->flags;
     322                 :            : }
     323                 :            : 
     324                 :            : /**
     325                 :            :  * When set, pktmbuf mempool will hold only mbufs with pinned external
     326                 :            :  * buffer. The external buffer will be attached to the mbuf at the
     327                 :            :  * memory pool creation and will never be detached by the mbuf free calls.
     328                 :            :  * mbuf should not contain any room for data after the mbuf structure.
     329                 :            :  */
     330                 :            : #define RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF (1 << 0)
     331                 :            : 
     332                 :            : /**
     333                 :            :  * Returns non zero if given mbuf has a pinned external buffer, or zero
     334                 :            :  * otherwise. The pinned external buffer is allocated at pool creation
     335                 :            :  * time and should not be freed on mbuf freeing.
     336                 :            :  *
     337                 :            :  * External buffer is a user-provided anonymous buffer.
     338                 :            :  */
     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                 :            : 
     344                 :            : /** Check reinitialized mbuf type in debug mode. */
     345                 :            : #define __rte_mbuf_raw_sanity_check_mp(m, mp) rte_mbuf_raw_sanity_check(m, mp)
     346                 :            : /** Check mbuf type in debug mode. */
     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                 :            : 
     358                 :            : /**
     359                 :            :  * Reads the value of an mbuf's refcnt.
     360                 :            :  * @param m
     361                 :            :  *   Mbuf to read
     362                 :            :  * @return
     363                 :            :  *   Reference count number.
     364                 :            :  */
     365                 :            : static inline uint16_t
     366                 :    2378168 : rte_mbuf_refcnt_read(const struct rte_mbuf *m)
     367                 :            : {
     368   [ +  +  -  +  :    2100626 :         return rte_atomic_load_explicit(&m->refcnt, rte_memory_order_relaxed);
          -  +  -  +  -  
          +  #  #  #  #  
             #  #  #  # ]
     369                 :            : }
     370                 :            : 
     371                 :            : /**
     372                 :            :  * Sets an mbuf's refcnt to a defined value.
     373                 :            :  * @param m
     374                 :            :  *   Mbuf to update
     375                 :            :  * @param new_value
     376                 :            :  *   Value set
     377                 :            :  */
     378                 :            : static inline void
     379                 :          0 : rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
     380                 :            : {
     381   [ +  -  #  # ]:      89875 :         rte_atomic_store_explicit(&m->refcnt, new_value, rte_memory_order_relaxed);
     382                 :          0 : }
     383                 :            : 
     384                 :            : /* internal */
     385                 :            : static inline uint16_t
     386                 :     262365 : __rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
     387                 :            : {
     388                 :     393716 :         return rte_atomic_fetch_add_explicit(&m->refcnt, value,
     389                 :     393716 :                                  rte_memory_order_acq_rel) + value;
     390                 :            : }
     391                 :            : 
     392                 :            : /**
     393                 :            :  * Adds given value to an mbuf's refcnt and returns its new value.
     394                 :            :  * @param m
     395                 :            :  *   Mbuf to update
     396                 :            :  * @param value
     397                 :            :  *   Value to add/subtract
     398                 :            :  * @return
     399                 :            :  *   Updated value
     400                 :            :  */
     401                 :            : static inline uint16_t
     402                 :     135470 : 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         [ +  + ]:     135470 :         if (likely(rte_mbuf_refcnt_read(m) == 1)) {
     412                 :       4119 :                 ++value;
     413                 :       4119 :                 rte_mbuf_refcnt_set(m, (uint16_t)value);
     414                 :       4119 :                 return (uint16_t)value;
     415                 :            :         }
     416                 :            : 
     417                 :     131351 :         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                 :            : 
     430                 :            : /**
     431                 :            :  * Adds given value to an mbuf's refcnt and returns its new value.
     432                 :            :  */
     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                 :            : 
     439                 :            : /**
     440                 :            :  * Reads the value of an mbuf's refcnt.
     441                 :            :  */
     442                 :            : static inline uint16_t
     443                 :            : rte_mbuf_refcnt_read(const struct rte_mbuf *m)
     444                 :            : {
     445                 :            :         return m->refcnt;
     446                 :            : }
     447                 :            : 
     448                 :            : /**
     449                 :            :  * Sets an mbuf's refcnt to the defined value.
     450                 :            :  */
     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                 :            : 
     459                 :            : /**
     460                 :            :  * Reads the refcnt of an external buffer.
     461                 :            :  *
     462                 :            :  * @param shinfo
     463                 :            :  *   Shared data of the external buffer.
     464                 :            :  * @return
     465                 :            :  *   Reference count number.
     466                 :            :  */
     467                 :            : static inline uint16_t
     468                 :            : rte_mbuf_ext_refcnt_read(const struct rte_mbuf_ext_shared_info *shinfo)
     469                 :            : {
     470   [ -  +  -  +  :         10 :         return rte_atomic_load_explicit(&shinfo->refcnt, rte_memory_order_relaxed);
                   -  + ]
     471                 :            : }
     472                 :            : 
     473                 :            : /**
     474                 :            :  * Set refcnt of an external buffer.
     475                 :            :  *
     476                 :            :  * @param shinfo
     477                 :            :  *   Shared data of the external buffer.
     478                 :            :  * @param new_value
     479                 :            :  *   Value set
     480                 :            :  */
     481                 :            : static inline void
     482                 :          0 : rte_mbuf_ext_refcnt_set(struct rte_mbuf_ext_shared_info *shinfo,
     483                 :            :         uint16_t new_value)
     484                 :            : {
     485         [ +  + ]:          5 :         rte_atomic_store_explicit(&shinfo->refcnt, new_value, rte_memory_order_relaxed);
     486                 :          0 : }
     487                 :            : 
     488                 :            : /**
     489                 :            :  * Add given value to refcnt of an external buffer and return its new
     490                 :            :  * value.
     491                 :            :  *
     492                 :            :  * @param shinfo
     493                 :            :  *   Shared data of the external buffer.
     494                 :            :  * @param value
     495                 :            :  *   Value to add/subtract
     496                 :            :  * @return
     497                 :            :  *   Updated value
     498                 :            :  */
     499                 :            : static inline uint16_t
     500                 :         18 : rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo,
     501                 :            :         int16_t value)
     502                 :            : {
     503         [ +  + ]:         18 :         if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1)) {
     504                 :          8 :                 ++value;
     505                 :          8 :                 rte_mbuf_ext_refcnt_set(shinfo, (uint16_t)value);
     506                 :          8 :                 return (uint16_t)value;
     507                 :            :         }
     508                 :            : 
     509                 :         10 :         return rte_atomic_fetch_add_explicit(&shinfo->refcnt, value,
     510                 :         10 :                                  rte_memory_order_acq_rel) + value;
     511                 :            : }
     512                 :            : 
     513                 :            : /** Mbuf prefetch */
     514                 :            : #define RTE_MBUF_PREFETCH_TO_FREE(m) do {       \
     515                 :            :         if ((m) != NULL)                        \
     516                 :            :                 rte_prefetch0(m);               \
     517                 :            : } while (0)
     518                 :            : 
     519                 :            : 
     520                 :            : /**
     521                 :            :  * Sanity checks on a reinitialized mbuf.
     522                 :            :  *
     523                 :            :  * Check the consistency of the given reinitialized mbuf.
     524                 :            :  * The function will cause a panic if corruption is detected.
     525                 :            :  *
     526                 :            :  * Check that the mbuf is properly reinitialized (refcnt=1, next=NULL,
     527                 :            :  * nb_segs=1), as done by rte_pktmbuf_prefree_seg().
     528                 :            :  *
     529                 :            :  * @param m
     530                 :            :  *   The mbuf to be checked.
     531                 :            :  * @param mp
     532                 :            :  *   The mempool to which the mbuf belongs.
     533                 :            :  *   NULL if unknown, not to be checked.
     534                 :            :  */
     535                 :            : void
     536                 :            : rte_mbuf_raw_sanity_check(const struct rte_mbuf *m, const struct rte_mempool *mp);
     537                 :            : 
     538                 :            : /**
     539                 :            :  * Sanity checks on a reinitialized mbuf.
     540                 :            :  *
     541                 :            :  * Almost like rte_mbuf_raw_sanity_check(), but this function gives the reason
     542                 :            :  * if corruption is detected rather than panic.
     543                 :            :  *
     544                 :            :  * @param m
     545                 :            :  *   The mbuf to be checked.
     546                 :            :  * @param mp
     547                 :            :  *   The mempool to which the mbuf belongs.
     548                 :            :  *   NULL if unknown, not to be checked.
     549                 :            :  * @param reason
     550                 :            :  *   A reference to a string pointer where to store the reason
     551                 :            :  *   why a mbuf is considered invalid.
     552                 :            :  * @return
     553                 :            :  *   - 0 if no issue has been found, reason is left untouched.
     554                 :            :  *   - -1 if a problem is detected, reason then points to a string
     555                 :            :  *     describing the reason why the mbuf is deemed invalid.
     556                 :            :  */
     557                 :            : int rte_mbuf_raw_check(const struct rte_mbuf *m, const struct rte_mempool *mp,
     558                 :            :                    const char **reason);
     559                 :            : 
     560                 :            : /**
     561                 :            :  * Sanity checks on an mbuf.
     562                 :            :  *
     563                 :            :  * Check the consistency of the given mbuf. The function will cause a
     564                 :            :  * panic if corruption is detected.
     565                 :            :  *
     566                 :            :  * @param m
     567                 :            :  *   The mbuf to be checked.
     568                 :            :  * @param is_header
     569                 :            :  *   True if the mbuf is a packet header, false if it is a sub-segment
     570                 :            :  *   of a packet (in this case, some fields like nb_segs are not checked)
     571                 :            :  */
     572                 :            : void
     573                 :            : rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
     574                 :            : 
     575                 :            : /**
     576                 :            :  * Sanity checks on a mbuf.
     577                 :            :  *
     578                 :            :  * Almost like rte_mbuf_sanity_check(), but this function gives the reason
     579                 :            :  * if corruption is detected rather than panic.
     580                 :            :  *
     581                 :            :  * @param m
     582                 :            :  *   The mbuf to be checked.
     583                 :            :  * @param is_header
     584                 :            :  *   True if the mbuf is a packet header, false if it is a sub-segment
     585                 :            :  *   of a packet (in this case, some fields like nb_segs are not checked)
     586                 :            :  * @param reason
     587                 :            :  *   A reference to a string pointer where to store the reason why a mbuf is
     588                 :            :  *   considered invalid.
     589                 :            :  * @return
     590                 :            :  *   - 0 if no issue has been found, reason is left untouched.
     591                 :            :  *   - -1 if a problem is detected, reason then points to a string describing
     592                 :            :  *     the reason why the mbuf is deemed invalid.
     593                 :            :  */
     594                 :            : int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
     595                 :            :                    const char **reason);
     596                 :            : 
     597                 :            : /** For backwards compatibility. */
     598                 :            : #define __rte_mbuf_raw_sanity_check(m) __rte_mbuf_raw_sanity_check_mp(m, NULL)
     599                 :            : 
     600                 :            : /** For backwards compatibility. */
     601                 :            : #define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_sanity_check_mp(m, NULL)
     602                 :            : 
     603                 :            : /**
     604                 :            :  * Allocate an uninitialized mbuf from mempool *mp*.
     605                 :            :  *
     606                 :            :  * This function can be used by PMDs (especially in RX functions) to
     607                 :            :  * allocate an uninitialized mbuf. The driver is responsible of
     608                 :            :  * initializing all the required fields. See rte_pktmbuf_reset().
     609                 :            :  * For standard needs, prefer rte_pktmbuf_alloc().
     610                 :            :  *
     611                 :            :  * The caller can expect that the following fields of the mbuf structure
     612                 :            :  * are initialized: buf_addr, buf_iova, buf_len, refcnt=1, nb_segs=1,
     613                 :            :  * next=NULL, pool, priv_size. The other fields must be initialized
     614                 :            :  * by the caller.
     615                 :            :  *
     616                 :            :  * @param mp
     617                 :            :  *   The mempool from which mbuf is allocated.
     618                 :            :  * @return
     619                 :            :  *   - The pointer to the new mbuf on success.
     620                 :            :  *   - NULL if allocation failed.
     621                 :            :  */
     622         [ +  + ]:      17529 : 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         [ +  + ]:       4616 :         if (rte_mempool_get(mp, &ret.ptr) < 0)
     630                 :            :                 return NULL;
     631                 :            :         __rte_mbuf_raw_sanity_check_mp(ret.m, mp);
     632                 :            : 
     633                 :      17521 :         rte_mbuf_history_mark(ret.m, RTE_MBUF_HISTORY_OP_LIB_ALLOC);
     634                 :            : 
     635                 :      17521 :         return ret.m;
     636                 :            : }
     637                 :            : 
     638                 :            : /**
     639                 :            :  * Allocate a bulk of uninitialized mbufs from mempool *mp*.
     640                 :            :  *
     641                 :            :  * This function can be used by PMDs (especially in Rx functions)
     642                 :            :  * to allocate a bulk of uninitialized mbufs.
     643                 :            :  * The driver is responsible of initializing all the required fields.
     644                 :            :  * See rte_pktmbuf_reset().
     645                 :            :  * For standard needs, prefer rte_pktmbuf_alloc_bulk().
     646                 :            :  *
     647                 :            :  * The caller can expect that the following fields of the mbuf structure
     648                 :            :  * are initialized:
     649                 :            :  * buf_addr, buf_iova, buf_len, refcnt=1, nb_segs=1, next=NULL, pool, priv_size.
     650                 :            :  * The other fields must be initialized by the caller.
     651                 :            :  *
     652                 :            :  * @param mp
     653                 :            :  *   The mempool from which mbufs are allocated.
     654                 :            :  * @param mbufs
     655                 :            :  *   Array of pointers to mbufs.
     656                 :            :  * @param count
     657                 :            :  *   Array size.
     658                 :            :  * @return
     659                 :            :  *   - 0: Success.
     660                 :            :  *   - -ENOENT: Not enough entries in the mempool; no mbufs are retrieved.
     661                 :            :  */
     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 (likely(rc == 0)) {
     667                 :            :                 for (unsigned int idx = 0; idx < count; idx++)
     668                 :            :                         __rte_mbuf_raw_sanity_check_mp(mbufs[idx], mp);
     669                 :            :         }
     670                 :            : 
     671                 :            :         rte_mbuf_history_mark_bulk(mbufs, count, RTE_MBUF_HISTORY_OP_LIB_ALLOC);
     672                 :            : 
     673                 :            :         return rc;
     674                 :            : }
     675                 :            : 
     676                 :            : /**
     677                 :            :  * Put mbuf back into its original mempool.
     678                 :            :  *
     679                 :            :  * The caller must ensure that the mbuf is direct and properly
     680                 :            :  * reinitialized (refcnt=1, next=NULL, nb_segs=1), as done by
     681                 :            :  * rte_pktmbuf_prefree_seg().
     682                 :            :  *
     683                 :            :  * This function should be used with care, when optimization is
     684                 :            :  * required. For standard needs, prefer rte_pktmbuf_free() or
     685                 :            :  * rte_pktmbuf_free_seg().
     686                 :            :  *
     687                 :            :  * @param m
     688                 :            :  *   The mbuf to be freed.
     689                 :            :  */
     690                 :            : static __rte_always_inline void
     691                 :            : rte_mbuf_raw_free(struct rte_mbuf *m)
     692                 :            : {
     693                 :            :         __rte_mbuf_raw_sanity_check_mp(m, NULL);
     694                 :            :         rte_mbuf_history_mark(m, RTE_MBUF_HISTORY_OP_LIB_FREE);
     695   [ +  +  +  +  :    2106790 :         rte_mempool_put(m->pool, m);
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     696                 :    2106798 : }
     697                 :            : 
     698                 :            : /**
     699                 :            :  * Put a bulk of mbufs allocated from the same mempool back into the mempool.
     700                 :            :  *
     701                 :            :  * The caller must ensure that the mbufs come from the specified mempool,
     702                 :            :  * are direct and properly reinitialized (refcnt=1, next=NULL, nb_segs=1),
     703                 :            :  * as done by rte_pktmbuf_prefree_seg().
     704                 :            :  *
     705                 :            :  * This function should be used with care, when optimization is required.
     706                 :            :  * For standard needs, prefer rte_pktmbuf_free_bulk().
     707                 :            :  *
     708                 :            :  * @see RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
     709                 :            :  *
     710                 :            :  * @param mp
     711                 :            :  *   The mempool to which the mbufs belong.
     712                 :            :  * @param mbufs
     713                 :            :  *   Array of pointers to packet mbufs.
     714                 :            :  *   The array must not contain NULL pointers.
     715                 :            :  * @param count
     716                 :            :  *   Array size.
     717                 :            :  */
     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);
     723                 :            :         rte_mbuf_history_mark_bulk(mbufs, count, RTE_MBUF_HISTORY_OP_LIB_FREE);
     724                 :            :         rte_mempool_put_bulk(mp, (void **)mbufs, count);
     725                 :            : }
     726                 :            : 
     727                 :            : /**
     728                 :            :  * The packet mbuf constructor.
     729                 :            :  *
     730                 :            :  * This function initializes some fields in the mbuf structure that are
     731                 :            :  * not modified by the user once created (origin pool, buffer start
     732                 :            :  * address, and so on). This function is given as a callback function to
     733                 :            :  * rte_mempool_obj_iter() or rte_mempool_create() at pool creation time.
     734                 :            :  *
     735                 :            :  * This function expects that the mempool private area was previously
     736                 :            :  * initialized with rte_pktmbuf_pool_init().
     737                 :            :  *
     738                 :            :  * @param mp
     739                 :            :  *   The mempool from which mbufs originate.
     740                 :            :  * @param opaque_arg
     741                 :            :  *   A pointer that can be used by the user to retrieve useful information
     742                 :            :  *   for mbuf initialization. This pointer is the opaque argument passed to
     743                 :            :  *   rte_mempool_obj_iter() or rte_mempool_create().
     744                 :            :  * @param m
     745                 :            :  *   The mbuf to initialize.
     746                 :            :  * @param i
     747                 :            :  *   The index of the mbuf in the pool table.
     748                 :            :  */
     749                 :            : void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg,
     750                 :            :                       void *m, unsigned i);
     751                 :            : 
     752                 :            : /**
     753                 :            :  * A packet mbuf pool constructor.
     754                 :            :  *
     755                 :            :  * This function initializes the mempool private data in the case of a
     756                 :            :  * pktmbuf pool. This private data is needed by the driver. The
     757                 :            :  * function must be called on the mempool before it is used, or it
     758                 :            :  * can be given as a callback function to rte_mempool_create() at
     759                 :            :  * pool creation. It can be extended by the user, for example, to
     760                 :            :  * provide another packet size.
     761                 :            :  *
     762                 :            :  * The mempool private area size must be at least equal to
     763                 :            :  * sizeof(struct rte_pktmbuf_pool_private).
     764                 :            :  *
     765                 :            :  * @param mp
     766                 :            :  *   The mempool from which mbufs originate.
     767                 :            :  * @param opaque_arg
     768                 :            :  *   A pointer that can be used by the user to retrieve useful information
     769                 :            :  *   for mbuf initialization. This pointer is the opaque argument passed to
     770                 :            :  *   rte_mempool_create().
     771                 :            :  */
     772                 :            : void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
     773                 :            : 
     774                 :            : /**
     775                 :            :  * Create a mbuf pool.
     776                 :            :  *
     777                 :            :  * This function creates and initializes a packet mbuf pool. It is
     778                 :            :  * a wrapper to rte_mempool functions.
     779                 :            :  *
     780                 :            :  * @param name
     781                 :            :  *   The name of the mbuf pool.
     782                 :            :  * @param n
     783                 :            :  *   The number of elements in the mbuf pool. The optimum size (in terms
     784                 :            :  *   of memory usage) for a mempool is when n is a power of two minus one:
     785                 :            :  *   n = (2^q - 1).
     786                 :            :  * @param cache_size
     787                 :            :  *   Size of the per-core object cache. See rte_mempool_create() for
     788                 :            :  *   details.
     789                 :            :  * @param priv_size
     790                 :            :  *   Size of application private are between the rte_mbuf structure
     791                 :            :  *   and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
     792                 :            :  * @param data_room_size
     793                 :            :  *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
     794                 :            :  * @param socket_id
     795                 :            :  *   The socket identifier where the memory should be allocated. The
     796                 :            :  *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
     797                 :            :  *   reserved zone.
     798                 :            :  * @return
     799                 :            :  *   The pointer to the new allocated mempool, on success. NULL on error
     800                 :            :  *   with rte_errno set appropriately. Possible rte_errno values include:
     801                 :            :  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
     802                 :            :  *    - EINVAL - cache size provided is too large, or priv_size is not aligned.
     803                 :            :  *    - ENOSPC - the maximum number of memzones has already been allocated
     804                 :            :  *    - EEXIST - a memzone with the same name already exists
     805                 :            :  *    - ENOMEM - no appropriate memory area found in which to create memzone
     806                 :            :  */
     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                 :            : 
     812                 :            : /**
     813                 :            :  * Create a mbuf pool with a given mempool ops name
     814                 :            :  *
     815                 :            :  * This function creates and initializes a packet mbuf pool. It is
     816                 :            :  * a wrapper to rte_mempool functions.
     817                 :            :  *
     818                 :            :  * @param name
     819                 :            :  *   The name of the mbuf pool.
     820                 :            :  * @param n
     821                 :            :  *   The number of elements in the mbuf pool. The optimum size (in terms
     822                 :            :  *   of memory usage) for a mempool is when n is a power of two minus one:
     823                 :            :  *   n = (2^q - 1).
     824                 :            :  * @param cache_size
     825                 :            :  *   Size of the per-core object cache. See rte_mempool_create() for
     826                 :            :  *   details.
     827                 :            :  * @param priv_size
     828                 :            :  *   Size of application private are between the rte_mbuf structure
     829                 :            :  *   and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
     830                 :            :  * @param data_room_size
     831                 :            :  *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
     832                 :            :  * @param socket_id
     833                 :            :  *   The socket identifier where the memory should be allocated. The
     834                 :            :  *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
     835                 :            :  *   reserved zone.
     836                 :            :  * @param ops_name
     837                 :            :  *   The mempool ops name to be used for this mempool instead of
     838                 :            :  *   default mempool. The value can be *NULL* to use default mempool.
     839                 :            :  * @return
     840                 :            :  *   The pointer to the new allocated mempool, on success. NULL on error
     841                 :            :  *   with rte_errno set appropriately. Possible rte_errno values include:
     842                 :            :  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
     843                 :            :  *    - EINVAL - cache size provided is too large, or priv_size is not aligned.
     844                 :            :  *    - ENOSPC - the maximum number of memzones has already been allocated
     845                 :            :  *    - EEXIST - a memzone with the same name already exists
     846                 :            :  *    - ENOMEM - no appropriate memory area found in which to create memzone
     847                 :            :  */
     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                 :            : 
     853                 :            : /** A structure that describes the pinned external buffer segment. */
     854                 :            : struct rte_pktmbuf_extmem {
     855                 :            :         void *buf_ptr;          /**< The virtual address of data buffer. */
     856                 :            :         rte_iova_t buf_iova;    /**< The IO address of the data buffer. */
     857                 :            :         size_t buf_len;         /**< External buffer length in bytes. */
     858                 :            :         uint16_t elt_size;      /**< mbuf element size in bytes. */
     859                 :            : };
     860                 :            : 
     861                 :            : /**
     862                 :            :  * Create a mbuf pool with external pinned data buffers.
     863                 :            :  *
     864                 :            :  * This function creates and initializes a packet mbuf pool that contains
     865                 :            :  * only mbufs with external buffer. It is a wrapper to rte_mempool functions.
     866                 :            :  *
     867                 :            :  * @param name
     868                 :            :  *   The name of the mbuf pool.
     869                 :            :  * @param n
     870                 :            :  *   The number of elements in the mbuf pool. The optimum size (in terms
     871                 :            :  *   of memory usage) for a mempool is when n is a power of two minus one:
     872                 :            :  *   n = (2^q - 1).
     873                 :            :  * @param cache_size
     874                 :            :  *   Size of the per-core object cache. See rte_mempool_create() for
     875                 :            :  *   details.
     876                 :            :  * @param priv_size
     877                 :            :  *   Size of application private are between the rte_mbuf structure
     878                 :            :  *   and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
     879                 :            :  * @param data_room_size
     880                 :            :  *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
     881                 :            :  * @param socket_id
     882                 :            :  *   The socket identifier where the memory should be allocated. The
     883                 :            :  *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
     884                 :            :  *   reserved zone.
     885                 :            :  * @param ext_mem
     886                 :            :  *   Pointer to the array of structures describing the external memory
     887                 :            :  *   for data buffers. It is caller responsibility to register this memory
     888                 :            :  *   with rte_extmem_register() (if needed), map this memory to appropriate
     889                 :            :  *   physical device, etc.
     890                 :            :  * @param ext_num
     891                 :            :  *   Number of elements in the ext_mem array.
     892                 :            :  * @return
     893                 :            :  *   The pointer to the new allocated mempool, on success. NULL on error
     894                 :            :  *   with rte_errno set appropriately. Possible rte_errno values include:
     895                 :            :  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
     896                 :            :  *    - EINVAL - cache size provided is too large, or priv_size is not aligned.
     897                 :            :  *    - ENOSPC - the maximum number of memzones has already been allocated
     898                 :            :  *    - EEXIST - a memzone with the same name already exists
     899                 :            :  *    - ENOMEM - no appropriate memory area found in which to create memzone
     900                 :            :  */
     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                 :            : 
     908                 :            : /**
     909                 :            :  * Get the data room size of mbufs stored in a pktmbuf_pool
     910                 :            :  *
     911                 :            :  * The data room size is the amount of data that can be stored in a
     912                 :            :  * mbuf including the headroom (RTE_PKTMBUF_HEADROOM).
     913                 :            :  *
     914                 :            :  * @param mp
     915                 :            :  *   The packet mbuf pool.
     916                 :            :  * @return
     917                 :            :  *   The data room size of mbufs stored in this mempool.
     918                 :            :  */
     919                 :            : static inline uint16_t
     920                 :            : rte_pktmbuf_data_room_size(struct rte_mempool *mp)
     921                 :            : {
     922                 :            :         struct rte_pktmbuf_pool_private *mbp_priv;
     923                 :            : 
     924                 :            :         mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
     925   [ +  +  -  +  :       3620 :         return mbp_priv->mbuf_data_room_size;
                   -  + ]
     926                 :            : }
     927                 :            : 
     928                 :            : /**
     929                 :            :  * Get the application private size of mbufs stored in a pktmbuf_pool
     930                 :            :  *
     931                 :            :  * The private size of mbuf is a zone located between the rte_mbuf
     932                 :            :  * structure and the data buffer where an application can store data
     933                 :            :  * associated to a packet.
     934                 :            :  *
     935                 :            :  * @param mp
     936                 :            :  *   The packet mbuf pool.
     937                 :            :  * @return
     938                 :            :  *   The private size of mbufs stored in this mempool.
     939                 :            :  */
     940                 :            : static inline uint16_t
     941                 :            : rte_pktmbuf_priv_size(struct rte_mempool *mp)
     942                 :            : {
     943                 :            :         struct rte_pktmbuf_pool_private *mbp_priv;
     944                 :            : 
     945                 :            :         mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp);
     946   [ +  +  -  + ]:        153 :         return mbp_priv->mbuf_priv_size;
     947                 :            : }
     948                 :            : 
     949                 :            : /**
     950                 :            :  * Reset the data_off field of a packet mbuf to its default value.
     951                 :            :  *
     952                 :            :  * The given mbuf must have only one segment, which should be empty.
     953                 :            :  *
     954                 :            :  * @param m
     955                 :            :  *   The packet mbuf's data_off field has to be reset.
     956                 :            :  */
     957                 :            : static inline void rte_pktmbuf_reset_headroom(struct rte_mbuf *m)
     958                 :            : {
     959                 :        330 :         m->data_off = (uint16_t)RTE_MIN((uint16_t)RTE_PKTMBUF_HEADROOM,
     960                 :            :                                         (uint16_t)m->buf_len);
     961                 :            : }
     962                 :            : 
     963                 :            : /**
     964                 :            :  * Reset the fields of a bulk of packet mbufs to their default values.
     965                 :            :  *
     966                 :            :  * The caller must ensure that the mbufs come from the specified mempool,
     967                 :            :  * are direct and properly reinitialized (refcnt=1, next=NULL, nb_segs=1),
     968                 :            :  * as done by rte_pktmbuf_prefree_seg().
     969                 :            :  *
     970                 :            :  * This function should be used with care, when optimization is required.
     971                 :            :  * For standard needs, prefer rte_pktmbuf_reset().
     972                 :            :  *
     973                 :            :  * @param mp
     974                 :            :  *   The mempool to which the mbuf belongs.
     975                 :            :  * @param mbufs
     976                 :            :  *   Array of pointers to packet mbufs.
     977                 :            :  *   The array must not contain NULL pointers.
     978                 :            :  * @param count
     979                 :            :  *   Array size.
     980                 :            :  */
     981                 :            : static inline void
     982         [ +  + ]:      17543 : rte_mbuf_raw_reset_bulk(struct rte_mempool *mp, struct rte_mbuf **mbufs, unsigned int count)
     983                 :            : {
     984                 :      17543 :         uint64_t ol_flags = (rte_pktmbuf_priv_flags(mp) & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF) ?
     985         [ +  + ]:      17543 :                         RTE_MBUF_F_EXTERNAL : 0;
     986                 :            :         uint16_t data_off = RTE_MIN_T(RTE_PKTMBUF_HEADROOM, rte_pktmbuf_data_room_size(mp),
     987                 :            :                         uint16_t);
     988                 :            : 
     989         [ +  + ]:      36147 :         for (unsigned int idx = 0; idx < count; idx++) {
     990                 :      18604 :                 struct rte_mbuf *m = mbufs[idx];
     991                 :            : 
     992                 :      18604 :                 m->pkt_len = 0;
     993                 :      18604 :                 m->tx_offload = 0;
     994                 :      18604 :                 m->vlan_tci = 0;
     995                 :      18604 :                 m->vlan_tci_outer = 0;
     996                 :      18604 :                 m->port = RTE_MBUF_PORT_INVALID;
     997                 :            : 
     998                 :      18604 :                 m->ol_flags = ol_flags;
     999                 :      18604 :                 m->packet_type = 0;
    1000                 :      18604 :                 m->data_off = data_off;
    1001                 :            : 
    1002                 :      18604 :                 m->data_len = 0;
    1003                 :            :                 __rte_mbuf_sanity_check(m, 1);
    1004                 :            :         }
    1005                 :      17543 : }
    1006                 :            : 
    1007                 :            : /**
    1008                 :            :  * Reset the fields of a packet mbuf to their default values.
    1009                 :            :  *
    1010                 :            :  * The given mbuf must have only one segment.
    1011                 :            :  *
    1012                 :            :  * @param m
    1013                 :            :  *   The packet mbuf to be reset.
    1014                 :            :  */
    1015                 :            : static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
    1016                 :            : {
    1017                 :        293 :         m->next = NULL;
    1018                 :        293 :         m->pkt_len = 0;
    1019                 :        293 :         m->tx_offload = 0;
    1020                 :        293 :         m->vlan_tci = 0;
    1021                 :        293 :         m->vlan_tci_outer = 0;
    1022                 :        293 :         m->nb_segs = 1;
    1023                 :        293 :         m->port = RTE_MBUF_PORT_INVALID;
    1024                 :            : 
    1025                 :        293 :         m->ol_flags &= RTE_MBUF_F_EXTERNAL;
    1026                 :        293 :         m->packet_type = 0;
    1027                 :            :         rte_pktmbuf_reset_headroom(m);
    1028                 :            : 
    1029         [ +  - ]:        293 :         m->data_len = 0;
    1030                 :            :         __rte_mbuf_sanity_check(m, 1);
    1031                 :            : }
    1032                 :            : 
    1033                 :            : /**
    1034                 :            :  * Allocate a new mbuf from a mempool.
    1035                 :            :  *
    1036                 :            :  * This new mbuf contains one segment, which has a length of 0. The pointer
    1037                 :            :  * to data is initialized to have some bytes of headroom in the buffer
    1038                 :            :  * (if buffer size allows).
    1039                 :            :  *
    1040                 :            :  * @param mp
    1041                 :            :  *   The mempool from which the mbuf is allocated.
    1042                 :            :  * @return
    1043                 :            :  *   - The pointer to the new mbuf on success.
    1044                 :            :  *   - NULL if allocation failed.
    1045                 :            :  */
    1046                 :      17526 : static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
    1047                 :            : {
    1048                 :            :         struct rte_mbuf *m;
    1049         [ +  + ]:      17526 :         if ((m = rte_mbuf_raw_alloc(mp)) != NULL)
    1050                 :      17518 :                 rte_mbuf_raw_reset_bulk(mp, &m, 1);
    1051                 :      17526 :         return m;
    1052                 :            : }
    1053                 :            : 
    1054                 :            : /**
    1055                 :            :  * Allocate a bulk of mbufs, initialize refcnt and reset the fields to default
    1056                 :            :  * values.
    1057                 :            :  *
    1058                 :            :  *  @param pool
    1059                 :            :  *    The mempool from which mbufs are allocated.
    1060                 :            :  *  @param mbufs
    1061                 :            :  *    Array of pointers to mbufs
    1062                 :            :  *  @param count
    1063                 :            :  *    Array size
    1064                 :            :  *  @return
    1065                 :            :  *   - 0: Success
    1066                 :            :  *   - -ENOENT: Not enough entries in the mempool; no mbufs are retrieved.
    1067                 :            :  */
    1068         [ +  + ]:         33 : 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         [ +  + ]:         33 :         if (unlikely(rc))
    1075                 :            :                 return rc;
    1076                 :            : 
    1077                 :            :         rte_mbuf_history_mark_bulk(mbufs, count, RTE_MBUF_HISTORY_OP_LIB_ALLOC);
    1078                 :            : 
    1079                 :         25 :         rte_mbuf_raw_reset_bulk(pool, mbufs, count);
    1080                 :            : 
    1081                 :         25 :         return 0;
    1082                 :            : }
    1083                 :            : 
    1084                 :            : /**
    1085                 :            :  * Initialize shared data at the end of an external buffer before attaching
    1086                 :            :  * to a mbuf by ``rte_pktmbuf_attach_extbuf()``. This is not a mandatory
    1087                 :            :  * initialization but a helper function to simply spare a few bytes at the
    1088                 :            :  * end of the buffer for shared data. If shared data is allocated
    1089                 :            :  * separately, this should not be called but application has to properly
    1090                 :            :  * initialize the shared data according to its need.
    1091                 :            :  *
    1092                 :            :  * Free callback and its argument is saved and the refcnt is set to 1.
    1093                 :            :  *
    1094                 :            :  * @warning
    1095                 :            :  * The value of buf_len will be reduced to RTE_PTR_DIFF(shinfo, buf_addr)
    1096                 :            :  * after this initialization. This shall be used for
    1097                 :            :  * ``rte_pktmbuf_attach_extbuf()``
    1098                 :            :  *
    1099                 :            :  * @param buf_addr
    1100                 :            :  *   The pointer to the external buffer.
    1101                 :            :  * @param [in,out] buf_len
    1102                 :            :  *   The pointer to length of the external buffer. Input value must be
    1103                 :            :  *   larger than the size of ``struct rte_mbuf_ext_shared_info`` and
    1104                 :            :  *   padding for alignment. If not enough, this function will return NULL.
    1105                 :            :  *   Adjusted buffer length will be returned through this pointer.
    1106                 :            :  * @param free_cb
    1107                 :            :  *   Free callback function to call when the external buffer needs to be
    1108                 :            :  *   freed.
    1109                 :            :  * @param fcb_opaque
    1110                 :            :  *   Argument for the free callback function.
    1111                 :            :  *
    1112                 :            :  * @return
    1113                 :            :  *   A pointer to the initialized shared data on success, return NULL
    1114                 :            :  *   otherwise.
    1115                 :            :  */
    1116                 :            : static inline struct rte_mbuf_ext_shared_info *
    1117                 :            : rte_pktmbuf_ext_shinfo_init_helper(void *buf_addr, uint16_t *buf_len,
    1118                 :            :         rte_mbuf_extbuf_free_callback_t free_cb, void *fcb_opaque)
    1119                 :            : {
    1120                 :            :         struct rte_mbuf_ext_shared_info *shinfo;
    1121                 :          3 :         void *buf_end = RTE_PTR_ADD(buf_addr, *buf_len);
    1122                 :            :         void *addr;
    1123                 :            : 
    1124                 :          3 :         addr = RTE_PTR_ALIGN_FLOOR(RTE_PTR_SUB(buf_end, sizeof(*shinfo)),
    1125                 :            :                                    sizeof(uintptr_t));
    1126         [ -  + ]:          3 :         if (addr <= buf_addr)
    1127                 :            :                 return NULL;
    1128                 :            : 
    1129                 :            :         shinfo = (struct rte_mbuf_ext_shared_info *)addr;
    1130                 :          3 :         shinfo->free_cb = free_cb;
    1131         [ -  + ]:          3 :         shinfo->fcb_opaque = fcb_opaque;
    1132                 :            :         rte_mbuf_ext_refcnt_set(shinfo, 1);
    1133                 :            : 
    1134                 :          2 :         *buf_len = (uint16_t)RTE_PTR_DIFF(shinfo, buf_addr);
    1135                 :          0 :         return shinfo;
    1136                 :            : }
    1137                 :            : 
    1138                 :            : /**
    1139                 :            :  * Attach an external buffer to a mbuf.
    1140                 :            :  *
    1141                 :            :  * User-managed anonymous buffer can be attached to an mbuf. When attaching
    1142                 :            :  * it, corresponding free callback function and its argument should be
    1143                 :            :  * provided via shinfo. This callback function will be called once all the
    1144                 :            :  * mbufs are detached from the buffer (refcnt becomes zero).
    1145                 :            :  *
    1146                 :            :  * The headroom length of the attaching mbuf will be set to zero and this
    1147                 :            :  * can be properly adjusted after attachment. For example, ``rte_pktmbuf_adj()``
    1148                 :            :  * or ``rte_pktmbuf_reset_headroom()`` might be used.
    1149                 :            :  *
    1150                 :            :  * Similarly, the packet length is initialized to 0. If the buffer contains
    1151                 :            :  * data, the user has to adjust ``data_len`` and the ``pkt_len`` field of
    1152                 :            :  * the mbuf accordingly.
    1153                 :            :  *
    1154                 :            :  * More mbufs can be attached to the same external buffer by
    1155                 :            :  * ``rte_pktmbuf_attach()`` once the external buffer has been attached by
    1156                 :            :  * this API.
    1157                 :            :  *
    1158                 :            :  * Detachment can be done by either ``rte_pktmbuf_detach_extbuf()`` or
    1159                 :            :  * ``rte_pktmbuf_detach()``.
    1160                 :            :  *
    1161                 :            :  * Memory for shared data must be provided and user must initialize all of
    1162                 :            :  * the content properly, especially free callback and refcnt. The pointer
    1163                 :            :  * of shared data will be stored in m->shinfo.
    1164                 :            :  * ``rte_pktmbuf_ext_shinfo_init_helper`` can help to simply spare a few
    1165                 :            :  * bytes at the end of buffer for the shared data, store free callback and
    1166                 :            :  * its argument and set the refcnt to 1. The following is an example:
    1167                 :            :  *
    1168                 :            :  *   struct rte_mbuf_ext_shared_info *shinfo =
    1169                 :            :  *          rte_pktmbuf_ext_shinfo_init_helper(buf_addr, &buf_len,
    1170                 :            :  *                                             free_cb, fcb_arg);
    1171                 :            :  *   rte_pktmbuf_attach_extbuf(m, buf_addr, buf_iova, buf_len, shinfo);
    1172                 :            :  *   rte_pktmbuf_reset_headroom(m);
    1173                 :            :  *   rte_pktmbuf_adj(m, data_len);
    1174                 :            :  *
    1175                 :            :  * Attaching an external buffer is quite similar to mbuf indirection in
    1176                 :            :  * replacing buffer addresses and length of a mbuf, but a few differences:
    1177                 :            :  * - When an indirect mbuf is attached, refcnt of the direct mbuf would be
    1178                 :            :  *   2 as long as the direct mbuf itself isn't freed after the attachment.
    1179                 :            :  *   In such cases, the buffer area of a direct mbuf must be read-only. But
    1180                 :            :  *   external buffer has its own refcnt and it starts from 1. Unless
    1181                 :            :  *   multiple mbufs are attached to a mbuf having an external buffer, the
    1182                 :            :  *   external buffer is writable.
    1183                 :            :  * - There's no need to allocate buffer from a mempool. Any buffer can be
    1184                 :            :  *   attached with appropriate free callback and its IO address.
    1185                 :            :  * - Smaller metadata is required to maintain shared data such as refcnt.
    1186                 :            :  *
    1187                 :            :  * @param m
    1188                 :            :  *   The pointer to the mbuf.
    1189                 :            :  * @param buf_addr
    1190                 :            :  *   The pointer to the external buffer.
    1191                 :            :  * @param buf_iova
    1192                 :            :  *   IO address of the external buffer.
    1193                 :            :  * @param buf_len
    1194                 :            :  *   The size of the external buffer.
    1195                 :            :  * @param shinfo
    1196                 :            :  *   User-provided memory for shared data of the external buffer.
    1197                 :            :  */
    1198                 :            : static inline void
    1199                 :            : rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
    1200                 :            :         rte_iova_t buf_iova, uint16_t buf_len,
    1201                 :            :         struct rte_mbuf_ext_shared_info *shinfo)
    1202                 :            : {
    1203                 :            :         /* mbuf should not be read-only */
    1204                 :            :         RTE_ASSERT(RTE_MBUF_DIRECT(m) && rte_mbuf_refcnt_read(m) == 1);
    1205                 :            :         RTE_ASSERT(shinfo->free_cb != NULL);
    1206                 :            : 
    1207                 :          3 :         m->buf_addr = buf_addr;
    1208                 :            :         rte_mbuf_iova_set(m, buf_iova);
    1209                 :          3 :         m->buf_len = buf_len;
    1210                 :            : 
    1211                 :          3 :         m->data_len = 0;
    1212                 :          3 :         m->data_off = 0;
    1213                 :            : 
    1214                 :          3 :         m->ol_flags |= RTE_MBUF_F_EXTERNAL;
    1215         [ -  + ]:          3 :         m->shinfo = shinfo;
    1216                 :            : }
    1217                 :            : 
    1218                 :            : /**
    1219                 :            :  * Detach the external buffer attached to a mbuf, same as
    1220                 :            :  * ``rte_pktmbuf_detach()``
    1221                 :            :  *
    1222                 :            :  * @param m
    1223                 :            :  *   The mbuf having external buffer.
    1224                 :            :  */
    1225                 :            : #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
    1226                 :            : 
    1227                 :            : /**
    1228                 :            :  * Copy dynamic fields from msrc to mdst.
    1229                 :            :  *
    1230                 :            :  * @param mdst
    1231                 :            :  *   The destination mbuf.
    1232                 :            :  * @param msrc
    1233                 :            :  *   The source mbuf.
    1234                 :            :  */
    1235                 :            : static inline void
    1236                 :            : rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
    1237                 :            : {
    1238                 :            : #if !RTE_IOVA_IN_MBUF
    1239                 :            :         mdst->dynfield2 = msrc->dynfield2;
    1240                 :            : #endif
    1241                 :       4147 :         memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1));
    1242                 :            : }
    1243                 :            : 
    1244                 :            : /* internal */
    1245                 :            : static inline void
    1246                 :       4147 : __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
    1247                 :            : {
    1248                 :       4147 :         mdst->port = msrc->port;
    1249                 :       4147 :         mdst->vlan_tci = msrc->vlan_tci;
    1250                 :       4147 :         mdst->vlan_tci_outer = msrc->vlan_tci_outer;
    1251                 :       4147 :         mdst->tx_offload = msrc->tx_offload;
    1252                 :       4147 :         mdst->hash = msrc->hash;
    1253                 :       4147 :         mdst->packet_type = msrc->packet_type;
    1254                 :            :         rte_mbuf_dynfield_copy(mdst, msrc);
    1255                 :       4147 : }
    1256                 :            : 
    1257                 :            : /**
    1258                 :            :  * Attach packet mbuf to another packet mbuf.
    1259                 :            :  *
    1260                 :            :  * If the mbuf we are attaching to isn't a direct buffer and is attached to
    1261                 :            :  * an external buffer, the mbuf being attached will be attached to the
    1262                 :            :  * external buffer instead of mbuf indirection.
    1263                 :            :  *
    1264                 :            :  * Otherwise, the mbuf will be indirectly attached. After attachment we
    1265                 :            :  * refer the mbuf we attached as 'indirect', while mbuf we attached to as
    1266                 :            :  * 'direct'.  The direct mbuf's reference counter is incremented.
    1267                 :            :  *
    1268                 :            :  * Right now, not supported:
    1269                 :            :  *  - attachment for already indirect mbuf (e.g. - mi has to be direct).
    1270                 :            :  *  - mbuf we trying to attach (mi) is used by someone else
    1271                 :            :  *    e.g. it's reference counter is greater then 1.
    1272                 :            :  *
    1273                 :            :  * @param mi
    1274                 :            :  *   The indirect packet mbuf.
    1275                 :            :  * @param m
    1276                 :            :  *   The packet mbuf we're attaching to.
    1277                 :            :  */
    1278                 :         36 : static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
    1279                 :            : {
    1280                 :            :         RTE_ASSERT(RTE_MBUF_DIRECT(mi) &&
    1281                 :            :             rte_mbuf_refcnt_read(mi) == 1);
    1282                 :            : 
    1283         [ +  + ]:         36 :         if (RTE_MBUF_HAS_EXTBUF(m)) {
    1284                 :          7 :                 rte_mbuf_ext_refcnt_update(m->shinfo, 1);
    1285                 :          7 :                 mi->ol_flags = m->ol_flags;
    1286                 :          7 :                 mi->shinfo = m->shinfo;
    1287                 :            :         } else {
    1288                 :            :                 /* if m is not direct, get the mbuf that embeds the data */
    1289                 :         29 :                 rte_mbuf_refcnt_update(rte_mbuf_from_indirect(m), 1);
    1290                 :         29 :                 mi->priv_size = m->priv_size;
    1291                 :         29 :                 mi->ol_flags = m->ol_flags | RTE_MBUF_F_INDIRECT;
    1292                 :            :         }
    1293                 :            : 
    1294                 :         36 :         __rte_pktmbuf_copy_hdr(mi, m);
    1295                 :            : 
    1296                 :         36 :         mi->data_off = m->data_off;
    1297                 :         36 :         mi->data_len = m->data_len;
    1298                 :            :         rte_mbuf_iova_set(mi, rte_mbuf_iova_get(m));
    1299                 :         36 :         mi->buf_addr = m->buf_addr;
    1300                 :         36 :         mi->buf_len = m->buf_len;
    1301                 :            : 
    1302                 :         36 :         mi->next = NULL;
    1303                 :         36 :         mi->pkt_len = mi->data_len;
    1304                 :         36 :         mi->nb_segs = 1;
    1305                 :            : 
    1306                 :            :         __rte_mbuf_sanity_check(mi, 1);
    1307                 :            :         __rte_mbuf_sanity_check(m, 0);
    1308                 :         36 : }
    1309                 :            : 
    1310                 :            : /**
    1311                 :            :  * @internal used by rte_pktmbuf_detach().
    1312                 :            :  *
    1313                 :            :  * Decrement the reference counter of the external buffer. When the
    1314                 :            :  * reference counter becomes 0, the buffer is freed by pre-registered
    1315                 :            :  * callback.
    1316                 :            :  */
    1317                 :            : static inline void
    1318                 :         10 : __rte_pktmbuf_free_extbuf(struct rte_mbuf *m)
    1319                 :            : {
    1320                 :            :         RTE_ASSERT(RTE_MBUF_HAS_EXTBUF(m));
    1321                 :            :         RTE_ASSERT(m->shinfo != NULL);
    1322                 :            : 
    1323         [ +  + ]:         10 :         if (rte_mbuf_ext_refcnt_update(m->shinfo, -1) == 0)
    1324                 :          3 :                 m->shinfo->free_cb(m->buf_addr, m->shinfo->fcb_opaque);
    1325                 :         10 : }
    1326                 :            : 
    1327                 :            : /**
    1328                 :            :  * @internal used by rte_pktmbuf_detach().
    1329                 :            :  *
    1330                 :            :  * Decrement the direct mbuf's reference counter. When the reference
    1331                 :            :  * counter becomes 0, the direct mbuf is freed.
    1332                 :            :  */
    1333                 :            : static inline void
    1334                 :         29 : __rte_pktmbuf_free_direct(struct rte_mbuf *m)
    1335                 :            : {
    1336                 :            :         struct rte_mbuf *md;
    1337                 :            : 
    1338                 :            :         RTE_ASSERT(RTE_MBUF_CLONED(m));
    1339                 :            : 
    1340                 :            :         md = rte_mbuf_from_indirect(m);
    1341                 :            : 
    1342         [ +  + ]:         29 :         if (rte_mbuf_refcnt_update(md, -1) == 0) {
    1343                 :         10 :                 md->next = NULL;
    1344         [ +  - ]:         10 :                 md->nb_segs = 1;
    1345                 :            :                 rte_mbuf_refcnt_set(md, 1);
    1346                 :            :                 rte_mbuf_raw_free(md);
    1347                 :            :         }
    1348                 :         29 : }
    1349                 :            : 
    1350                 :            : /**
    1351                 :            :  * Detach a packet mbuf from external buffer or direct buffer.
    1352                 :            :  *
    1353                 :            :  *  - decrement refcnt and free the external/direct buffer if refcnt
    1354                 :            :  *    becomes zero.
    1355                 :            :  *  - restore original mbuf address and length values.
    1356                 :            :  *  - reset pktmbuf data and data_len to their default values.
    1357                 :            :  *
    1358                 :            :  * All other fields of the given packet mbuf will be left intact.
    1359                 :            :  *
    1360                 :            :  * If the packet mbuf was allocated from the pool with pinned
    1361                 :            :  * external buffers the rte_pktmbuf_detach does nothing with the
    1362                 :            :  * mbuf of this kind, because the pinned buffers are not supposed
    1363                 :            :  * to be detached.
    1364                 :            :  *
    1365                 :            :  * @param m
    1366                 :            :  *   The indirect attached packet mbuf.
    1367                 :            :  */
    1368                 :       1141 : static inline void rte_pktmbuf_detach(struct rte_mbuf *m)
    1369                 :            : {
    1370                 :       1141 :         struct rte_mempool *mp = m->pool;
    1371                 :            :         uint32_t mbuf_size, buf_len;
    1372                 :            :         uint16_t priv_size;
    1373                 :            : 
    1374         [ +  + ]:       1141 :         if (RTE_MBUF_HAS_EXTBUF(m)) {
    1375                 :            :                 /*
    1376                 :            :                  * The mbuf has the external attached buffer,
    1377                 :            :                  * we should check the type of the memory pool where
    1378                 :            :                  * the mbuf was allocated from to detect the pinned
    1379                 :            :                  * external buffer.
    1380                 :            :                  */
    1381                 :            :                 uint32_t flags = rte_pktmbuf_priv_flags(mp);
    1382                 :            : 
    1383         [ +  + ]:       1112 :                 if (flags & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF) {
    1384                 :            :                         /*
    1385                 :            :                          * The pinned external buffer should not be
    1386                 :            :                          * detached from its backing mbuf, just exit.
    1387                 :            :                          */
    1388                 :            :                         return;
    1389                 :            :                 }
    1390                 :         10 :                 __rte_pktmbuf_free_extbuf(m);
    1391                 :            :         } else {
    1392                 :         29 :                 __rte_pktmbuf_free_direct(m);
    1393                 :            :         }
    1394                 :            :         priv_size = rte_pktmbuf_priv_size(mp);
    1395                 :         39 :         mbuf_size = (uint32_t)(sizeof(struct rte_mbuf) + priv_size);
    1396                 :            :         buf_len = rte_pktmbuf_data_room_size(mp);
    1397                 :            : 
    1398                 :         39 :         m->priv_size = priv_size;
    1399                 :         39 :         m->buf_addr = (char *)m + mbuf_size;
    1400                 :         39 :         rte_mbuf_iova_set(m, rte_mempool_virt2iova(m) + mbuf_size);
    1401                 :         39 :         m->buf_len = (uint16_t)buf_len;
    1402                 :            :         rte_pktmbuf_reset_headroom(m);
    1403                 :         39 :         m->data_len = 0;
    1404                 :         39 :         m->ol_flags = 0;
    1405                 :            : }
    1406                 :            : 
    1407                 :            : /**
    1408                 :            :  * @internal Handle the packet mbufs with attached pinned external buffer
    1409                 :            :  * on the mbuf freeing:
    1410                 :            :  *
    1411                 :            :  *  - return zero if reference counter in shinfo is one. It means there is
    1412                 :            :  *  no more reference to this pinned buffer and mbuf can be returned to
    1413                 :            :  *  the pool
    1414                 :            :  *
    1415                 :            :  *  - otherwise (if reference counter is not one), decrement reference
    1416                 :            :  *  counter and return non-zero value to prevent freeing the backing mbuf.
    1417                 :            :  *
    1418                 :            :  * Returns non zero if mbuf should not be freed.
    1419                 :            :  */
    1420                 :       1102 : static inline int __rte_pktmbuf_pinned_extbuf_decref(struct rte_mbuf *m)
    1421                 :            : {
    1422                 :            :         struct rte_mbuf_ext_shared_info *shinfo;
    1423                 :            : 
    1424                 :            :         /* Clear flags, mbuf is being freed. */
    1425                 :       1102 :         m->ol_flags = RTE_MBUF_F_EXTERNAL;
    1426                 :       1102 :         shinfo = m->shinfo;
    1427                 :            : 
    1428                 :            :         /* Optimize for performance - do not dec/reinit */
    1429         [ +  + ]:       1102 :         if (likely(rte_mbuf_ext_refcnt_read(shinfo) == 1))
    1430                 :            :                 return 0;
    1431                 :            : 
    1432                 :            :         /*
    1433                 :            :          * Direct usage of add primitive to avoid
    1434                 :            :          * duplication of comparing with one.
    1435                 :            :          */
    1436         [ -  + ]:          2 :         if (likely(rte_atomic_fetch_add_explicit(&shinfo->refcnt, -1,
    1437                 :            :                                      rte_memory_order_acq_rel) - 1))
    1438                 :            :                 return 1;
    1439                 :            : 
    1440                 :            :         /* Reinitialize counter before mbuf freeing. */
    1441                 :            :         rte_mbuf_ext_refcnt_set(shinfo, 1);
    1442                 :          0 :         return 0;
    1443                 :            : }
    1444                 :            : 
    1445                 :            : /**
    1446                 :            :  * Decrease reference counter and unlink a mbuf segment
    1447                 :            :  *
    1448                 :            :  * This function does the same than a free, except that it does not
    1449                 :            :  * return the segment to its pool.
    1450                 :            :  * It decreases the reference counter, and if it reaches 0, it is
    1451                 :            :  * detached from its parent for an indirect mbuf.
    1452                 :            :  *
    1453                 :            :  * @param m
    1454                 :            :  *   The mbuf to be unlinked
    1455                 :            :  * @return
    1456                 :            :  *   - (m) if it is the last reference. It can be recycled or freed.
    1457                 :            :  *   - (NULL) if the mbuf still has remaining references on it.
    1458                 :            :  */
    1459                 :            : static __rte_always_inline struct rte_mbuf *
    1460                 :            : rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
    1461                 :            : {
    1462                 :            :         bool refcnt_not_one;
    1463                 :            : 
    1464                 :            :         __rte_mbuf_sanity_check(m, 0);
    1465                 :            : 
    1466                 :    4210010 :         refcnt_not_one = unlikely(rte_mbuf_refcnt_read(m) != 1);
    1467   [ +  +  -  +  :    2378112 :         if (refcnt_not_one && __rte_mbuf_refcnt_update(m, -1) != 0)
          +  +  -  +  -  
          -  -  -  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1468                 :            :                 return NULL;
    1469                 :            : 
    1470   [ +  +  +  +  :    2115465 :         if (unlikely(!RTE_MBUF_DIRECT(m))) {
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1471                 :       1137 :                 rte_pktmbuf_detach(m);
    1472   [ +  +  +  +  :       1137 :                 if (RTE_MBUF_HAS_EXTBUF(m) &&
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1473   [ +  -  +  -  :       3306 :                                 RTE_MBUF_HAS_PINNED_EXTBUF(m) &&
          +  -  +  -  +  
          -  +  +  -  -  
          -  -  -  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1474                 :       1102 :                                 __rte_pktmbuf_pinned_extbuf_decref(m))
    1475                 :            :                         return NULL;
    1476                 :            :         }
    1477                 :            : 
    1478   [ -  +  -  +  :    2115463 :         if (refcnt_not_one)
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1479                 :          0 :                 rte_mbuf_refcnt_set(m, 1);
    1480   [ +  +  +  +  :    2115463 :         if (m->nb_segs != 1)
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1481                 :       4175 :                 m->nb_segs = 1;
    1482   [ +  +  +  +  :    2115463 :         if (m->next != NULL)
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1483                 :       4725 :                 m->next = NULL;
    1484                 :            : 
    1485                 :            :         return m;
    1486                 :            : }
    1487                 :            : 
    1488                 :            : /**
    1489                 :            :  * Free a segment of a packet mbuf into its original mempool.
    1490                 :            :  *
    1491                 :            :  * Free an mbuf, without parsing other segments in case of chained
    1492                 :            :  * buffers.
    1493                 :            :  *
    1494                 :            :  * @param m
    1495                 :            :  *   The packet mbuf segment to be freed.
    1496                 :            :  */
    1497                 :            : static __rte_always_inline void
    1498                 :            : rte_pktmbuf_free_seg(struct rte_mbuf *m)
    1499                 :            : {
    1500                 :            :         m = rte_pktmbuf_prefree_seg(m);
    1501   [ +  +  +  +  :    2370083 :         if (likely(m != NULL))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1502                 :            :                 rte_mbuf_raw_free(m);
    1503                 :            : }
    1504                 :            : 
    1505                 :            : /**
    1506                 :            :  * Free a packet mbuf back into its original mempool.
    1507                 :            :  *
    1508                 :            :  * Free an mbuf, and all its segments in case of chained buffers. Each
    1509                 :            :  * segment is added back into its original mempool.
    1510                 :            :  *
    1511                 :            :  * @param m
    1512                 :            :  *   The packet mbuf to be freed. If NULL, the function does nothing.
    1513                 :            :  */
    1514                 :    2402351 : static inline void rte_pktmbuf_free(struct rte_mbuf *m)
    1515                 :            : {
    1516                 :            :         struct rte_mbuf *m_next;
    1517                 :            : 
    1518                 :            :         if (m != NULL)
    1519                 :            :                 __rte_mbuf_sanity_check(m, 1);
    1520                 :            : 
    1521         [ +  + ]:    4771994 :         while (m != NULL) {
    1522                 :    2369654 :                 m_next = m->next;
    1523                 :            :                 rte_pktmbuf_free_seg(m);
    1524                 :            :                 m = m_next;
    1525                 :            :         }
    1526                 :    2402340 : }
    1527                 :            : 
    1528                 :            : /**
    1529                 :            :  * Free a bulk of packet mbufs back into their original mempools.
    1530                 :            :  *
    1531                 :            :  * Free a bulk of mbufs, and all their segments in case of chained buffers.
    1532                 :            :  * Each segment is added back into its original mempool.
    1533                 :            :  *
    1534                 :            :  *  @param mbufs
    1535                 :            :  *    Array of pointers to packet mbufs.
    1536                 :            :  *    The array may contain NULL pointers.
    1537                 :            :  *  @param count
    1538                 :            :  *    Array size.
    1539                 :            :  */
    1540                 :            : void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count);
    1541                 :            : 
    1542                 :            : /**
    1543                 :            :  * Create a "clone" of the given packet mbuf.
    1544                 :            :  *
    1545                 :            :  * Walks through all segments of the given packet mbuf, and for each of them:
    1546                 :            :  *  - Creates a new packet mbuf from the given pool.
    1547                 :            :  *  - Attaches newly created mbuf to the segment.
    1548                 :            :  * Then updates pkt_len and nb_segs of the "clone" packet mbuf to match values
    1549                 :            :  * from the original packet mbuf.
    1550                 :            :  *
    1551                 :            :  * @param md
    1552                 :            :  *   The packet mbuf to be cloned.
    1553                 :            :  * @param mp
    1554                 :            :  *   The mempool from which the "clone" mbufs are allocated.
    1555                 :            :  * @return
    1556                 :            :  *   - The pointer to the new "clone" mbuf on success.
    1557                 :            :  *   - NULL if allocation fails.
    1558                 :            :  */
    1559                 :            : struct rte_mbuf *
    1560                 :            : rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp);
    1561                 :            : 
    1562                 :            : /**
    1563                 :            :  * Create a full copy of a given packet mbuf.
    1564                 :            :  *
    1565                 :            :  * Copies all the data from a given packet mbuf to a newly allocated
    1566                 :            :  * set of mbufs. The private data are is not copied.
    1567                 :            :  *
    1568                 :            :  * @param m
    1569                 :            :  *   The packet mbuf to be copied.
    1570                 :            :  * @param mp
    1571                 :            :  *   The mempool from which the "clone" mbufs are allocated.
    1572                 :            :  * @param offset
    1573                 :            :  *   The number of bytes to skip before copying.
    1574                 :            :  *   If the mbuf does not have that many bytes, it is an error
    1575                 :            :  *   and NULL is returned.
    1576                 :            :  * @param length
    1577                 :            :  *   The upper limit on bytes to copy.  Passing UINT32_MAX
    1578                 :            :  *   means all data (after offset).
    1579                 :            :  * @return
    1580                 :            :  *   - The pointer to the new "clone" mbuf on success.
    1581                 :            :  *   - NULL if allocation fails.
    1582                 :            :  */
    1583                 :            : struct rte_mbuf *
    1584                 :            : rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
    1585                 :            :                  uint32_t offset, uint32_t length);
    1586                 :            : 
    1587                 :            : /**
    1588                 :            :  * Adds given value to the refcnt of all packet mbuf segments.
    1589                 :            :  *
    1590                 :            :  * Walks through all segments of given packet mbuf and for each of them
    1591                 :            :  * invokes rte_mbuf_refcnt_update().
    1592                 :            :  *
    1593                 :            :  * @param m
    1594                 :            :  *   The packet mbuf whose refcnt to be updated.
    1595                 :            :  * @param v
    1596                 :            :  *   The value to add to the mbuf's segments refcnt.
    1597                 :            :  */
    1598                 :            : static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
    1599                 :            : {
    1600                 :            :         __rte_mbuf_sanity_check(m, 1);
    1601                 :            : 
    1602                 :            :         do {
    1603                 :     135412 :                 rte_mbuf_refcnt_update(m, v);
    1604   [ -  +  -  + ]:     135412 :         } while ((m = m->next) != NULL);
    1605                 :            : }
    1606                 :            : 
    1607                 :            : /**
    1608                 :            :  * Get the headroom in a packet mbuf.
    1609                 :            :  *
    1610                 :            :  * @param m
    1611                 :            :  *   The packet mbuf.
    1612                 :            :  * @return
    1613                 :            :  *   The length of the headroom.
    1614                 :            :  */
    1615                 :          0 : static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
    1616                 :            : {
    1617                 :            :         __rte_mbuf_sanity_check(m, 0);
    1618   [ +  +  -  -  :      41213 :         return m->data_off;
                   -  - ]
    1619                 :            : }
    1620                 :            : 
    1621                 :            : /**
    1622                 :            :  * Get the tailroom of a packet mbuf.
    1623                 :            :  *
    1624                 :            :  * @param m
    1625                 :            :  *   The packet mbuf.
    1626                 :            :  * @return
    1627                 :            :  *   The length of the tailroom.
    1628                 :            :  */
    1629                 :          0 : static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
    1630                 :            : {
    1631                 :            :         __rte_mbuf_sanity_check(m, 0);
    1632         [ +  - ]:       5474 :         return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) -
    1633   [ +  +  +  +  :      25352 :                           m->data_len);
          +  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  -  
                      - ]
    1634                 :            : }
    1635                 :            : 
    1636                 :            : /**
    1637                 :            :  * Get the last segment of the packet.
    1638                 :            :  *
    1639                 :            :  * @param m
    1640                 :            :  *   The packet mbuf.
    1641                 :            :  * @return
    1642                 :            :  *   The last segment of the given mbuf.
    1643                 :            :  */
    1644                 :          0 : static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
    1645                 :            : {
    1646                 :            :         __rte_mbuf_sanity_check(m, 1);
    1647   [ +  +  +  +  :      24078 :         while (m->next != NULL)
          -  +  +  +  -  
          +  -  +  +  +  
          -  +  +  +  -  
          +  +  +  +  +  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  +  
             -  +  +  + ]
    1648                 :            :                 m = m->next;
    1649                 :          0 :         return m;
    1650                 :            : }
    1651                 :            : 
    1652                 :            : /**
    1653                 :            :  * A macro that returns the length of the packet.
    1654                 :            :  *
    1655                 :            :  * The value can be read or assigned.
    1656                 :            :  *
    1657                 :            :  * @param m
    1658                 :            :  *   The packet mbuf.
    1659                 :            :  */
    1660                 :            : #define rte_pktmbuf_pkt_len(m) ((m)->pkt_len)
    1661                 :            : 
    1662                 :            : /**
    1663                 :            :  * A macro that returns the length of the segment.
    1664                 :            :  *
    1665                 :            :  * The value can be read or assigned.
    1666                 :            :  *
    1667                 :            :  * @param m
    1668                 :            :  *   The packet mbuf.
    1669                 :            :  */
    1670                 :            : #define rte_pktmbuf_data_len(m) ((m)->data_len)
    1671                 :            : 
    1672                 :            : /**
    1673                 :            :  * Prepend len bytes to an mbuf data area.
    1674                 :            :  *
    1675                 :            :  * Returns a pointer to the new
    1676                 :            :  * data start address. If there is not enough headroom in the first
    1677                 :            :  * segment, the function will return NULL, without modifying the mbuf.
    1678                 :            :  *
    1679                 :            :  * @param m
    1680                 :            :  *   The pkt mbuf.
    1681                 :            :  * @param len
    1682                 :            :  *   The amount of data to prepend (in bytes).
    1683                 :            :  * @return
    1684                 :            :  *   A pointer to the start of the newly prepended data, or
    1685                 :            :  *   NULL if there is not enough headroom space in the first segment
    1686                 :            :  */
    1687                 :          0 : static inline char *rte_pktmbuf_prepend(struct rte_mbuf *m,
    1688                 :            :                                         uint16_t len)
    1689                 :            : {
    1690                 :            :         __rte_mbuf_sanity_check(m, 1);
    1691                 :            : 
    1692   [ +  -  +  -  :       4112 :         if (unlikely(len > rte_pktmbuf_headroom(m)))
          +  -  +  -  +  
                -  #  # ]
    1693                 :            :                 return NULL;
    1694                 :            : 
    1695                 :            :         /* NB: elaborating the subtraction like this instead of using
    1696                 :            :          *     -= allows us to ensure the result type is uint16_t
    1697                 :            :          *     avoiding compiler warnings on gcc 8.1 at least */
    1698                 :       4110 :         m->data_off = (uint16_t)(m->data_off - len);
    1699                 :       4110 :         m->data_len = (uint16_t)(m->data_len + len);
    1700                 :       4102 :         m->pkt_len  = (m->pkt_len + len);
    1701                 :            : 
    1702   [ -  +  -  +  :       4110 :         return (char *)m->buf_addr + m->data_off;
             -  +  -  + ]
    1703                 :            : }
    1704                 :            : 
    1705                 :            : /**
    1706                 :            :  * Append len bytes to an mbuf.
    1707                 :            :  *
    1708                 :            :  * Append len bytes to an mbuf and return a pointer to the start address
    1709                 :            :  * of the added data. If there is not enough tailroom in the last
    1710                 :            :  * segment, the function will return NULL, without modifying the mbuf.
    1711                 :            :  *
    1712                 :            :  * @param m
    1713                 :            :  *   The packet mbuf.
    1714                 :            :  * @param len
    1715                 :            :  *   The amount of data to append (in bytes).
    1716                 :            :  * @return
    1717                 :            :  *   A pointer to the start of the newly appended data, or
    1718                 :            :  *   NULL if there is not enough tailroom space in the last segment
    1719                 :            :  */
    1720                 :          0 : static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
    1721                 :            : {
    1722                 :            :         void *tail;
    1723                 :            :         struct rte_mbuf *m_last;
    1724                 :            : 
    1725                 :            :         __rte_mbuf_sanity_check(m, 1);
    1726                 :            : 
    1727                 :            :         m_last = rte_pktmbuf_lastseg(m);
    1728   [ +  -  +  -  :       5142 :         if (unlikely(len > rte_pktmbuf_tailroom(m_last)))
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  +  -  
          -  -  -  -  -  
             -  +  -  +  
                      - ]
    1729                 :            :                 return NULL;
    1730                 :            : 
    1731                 :       5110 :         tail = (char *)m_last->buf_addr + m_last->data_off + m_last->data_len;
    1732                 :       5140 :         m_last->data_len = (uint16_t)(m_last->data_len + len);
    1733   [ +  +  +  +  :        656 :         m->pkt_len  = (m->pkt_len + len);
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  +  -  
                      + ]
    1734                 :       4500 :         return (char*) tail;
    1735                 :            : }
    1736                 :            : 
    1737                 :            : /**
    1738                 :            :  * Remove len bytes at the beginning of an mbuf.
    1739                 :            :  *
    1740                 :            :  * Returns a pointer to the start address of the new data area. If the
    1741                 :            :  * length is greater than the length of the first segment, then the
    1742                 :            :  * function will fail and return NULL, without modifying the mbuf.
    1743                 :            :  *
    1744                 :            :  * @param m
    1745                 :            :  *   The packet mbuf.
    1746                 :            :  * @param len
    1747                 :            :  *   The amount of data to remove (in bytes).
    1748                 :            :  * @return
    1749                 :            :  *   A pointer to the new start of the data.
    1750                 :            :  */
    1751                 :            : static inline char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
    1752                 :            : {
    1753                 :            :         __rte_mbuf_sanity_check(m, 1);
    1754                 :            : 
    1755   [ +  -  #  #  :          2 :         if (unlikely(len > m->data_len))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1756                 :            :                 return NULL;
    1757                 :            : 
    1758                 :            :         /* NB: elaborating the addition like this instead of using
    1759                 :            :          *     += allows us to ensure the result type is uint16_t
    1760                 :            :          *     avoiding compiler warnings on gcc 8.1 at least */
    1761                 :          2 :         m->data_len = (uint16_t)(m->data_len - len);
    1762                 :          2 :         m->data_off = (uint16_t)(m->data_off + len);
    1763                 :          2 :         m->pkt_len  = (m->pkt_len - len);
    1764                 :          2 :         return (char *)m->buf_addr + m->data_off;
    1765                 :            : }
    1766                 :            : 
    1767                 :            : /**
    1768                 :            :  * Remove len bytes of data at the end of the mbuf.
    1769                 :            :  *
    1770                 :            :  * If the length is greater than the length of the last segment, the
    1771                 :            :  * function will fail and return -1 without modifying the mbuf.
    1772                 :            :  *
    1773                 :            :  * @param m
    1774                 :            :  *   The packet mbuf.
    1775                 :            :  * @param len
    1776                 :            :  *   The amount of data to remove (in bytes).
    1777                 :            :  * @return
    1778                 :            :  *   - 0: On success.
    1779                 :            :  *   - -1: On error.
    1780                 :            :  */
    1781                 :            : static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
    1782                 :            : {
    1783                 :            :         struct rte_mbuf *m_last;
    1784                 :            : 
    1785                 :            :         __rte_mbuf_sanity_check(m, 1);
    1786                 :            : 
    1787                 :            :         m_last = rte_pktmbuf_lastseg(m);
    1788   [ +  -  -  + ]:          6 :         if (unlikely(len > m_last->data_len))
    1789                 :            :                 return -1;
    1790                 :            : 
    1791                 :          4 :         m_last->data_len = (uint16_t)(m_last->data_len - len);
    1792         [ -  + ]:          4 :         m->pkt_len  = (m->pkt_len - len);
    1793                 :          2 :         return 0;
    1794                 :            : }
    1795                 :            : 
    1796                 :            : /**
    1797                 :            :  * Test if mbuf data is contiguous.
    1798                 :            :  *
    1799                 :            :  * @param m
    1800                 :            :  *   The packet mbuf.
    1801                 :            :  * @return
    1802                 :            :  *   - 1, if all data is contiguous (one segment).
    1803                 :            :  *   - 0, if there is several segments.
    1804                 :            :  */
    1805                 :            : static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
    1806                 :            : {
    1807                 :            :         __rte_mbuf_sanity_check(m, 1);
    1808   [ +  +  -  +  :        232 :         return m->nb_segs == 1;
          -  +  -  +  -  
             +  -  +  -  
                      + ]
    1809                 :            : }
    1810                 :            : 
    1811                 :            : /**
    1812                 :            :  * @internal used by rte_pktmbuf_read().
    1813                 :            :  */
    1814                 :            : const void *__rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off,
    1815                 :            :         uint32_t len, void *buf);
    1816                 :            : 
    1817                 :            : /**
    1818                 :            :  * Read len data bytes in a mbuf at specified offset.
    1819                 :            :  *
    1820                 :            :  * If the data is contiguous, return the pointer in the mbuf data, else
    1821                 :            :  * copy the data in the buffer provided by the user and return its
    1822                 :            :  * pointer.
    1823                 :            :  *
    1824                 :            :  * @param m
    1825                 :            :  *   The pointer to the mbuf.
    1826                 :            :  * @param off
    1827                 :            :  *   The offset of the data in the mbuf.
    1828                 :            :  * @param len
    1829                 :            :  *   The amount of bytes to read.
    1830                 :            :  * @param buf
    1831                 :            :  *   The buffer where data is copied if it is not contiguous in mbuf
    1832                 :            :  *   data. Its length should be at least equal to the len parameter.
    1833                 :            :  * @return
    1834                 :            :  *   The pointer to the data, either in the mbuf if it is contiguous,
    1835                 :            :  *   or in the user buffer. If mbuf is too small, NULL is returned.
    1836                 :            :  */
    1837                 :          0 : static inline const void *rte_pktmbuf_read(const struct rte_mbuf *m,
    1838                 :            :         uint32_t off, uint32_t len, void *buf)
    1839                 :            : {
    1840   [ +  +  +  +  :        210 :         if (likely(off + len <= rte_pktmbuf_data_len(m)))
          +  +  +  -  +  
          +  +  +  +  +  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  -  
                      - ]
    1841         [ -  + ]:        173 :                 return rte_pktmbuf_mtod_offset(m, char *, off);
    1842                 :            :         else
    1843                 :         45 :                 return __rte_pktmbuf_read(m, off, len, buf);
    1844                 :            : }
    1845                 :            : 
    1846                 :            : /**
    1847                 :            :  * Chain an mbuf to another, thereby creating a segmented packet.
    1848                 :            :  *
    1849                 :            :  * Note: The implementation will do a linear walk over the segments to find
    1850                 :            :  * the tail entry. For cases when there are many segments, it's better to
    1851                 :            :  * chain the entries manually.
    1852                 :            :  *
    1853                 :            :  * @param head
    1854                 :            :  *   The head of the mbuf chain (the first packet)
    1855                 :            :  * @param tail
    1856                 :            :  *   The mbuf to put last in the chain
    1857                 :            :  *
    1858                 :            :  * @return
    1859                 :            :  *   - 0, on success.
    1860                 :            :  *   - -EOVERFLOW, if the chain segment limit exceeded
    1861                 :            :  */
    1862                 :            : static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
    1863                 :            : {
    1864                 :            :         struct rte_mbuf *cur_tail;
    1865                 :            : 
    1866                 :            :         /* Check for number-of-segments-overflow */
    1867   [ +  -  +  -  :        665 :         if (head->nb_segs + tail->nb_segs > RTE_MBUF_MAX_NB_SEGS)
          +  -  +  -  -  
                +  +  - ]
    1868                 :            :                 return -EOVERFLOW;
    1869                 :            : 
    1870                 :            :         /* Chain 'tail' onto the old tail */
    1871                 :            :         cur_tail = rte_pktmbuf_lastseg(head);
    1872                 :        665 :         cur_tail->next = tail;
    1873                 :            : 
    1874                 :            :         /* accumulate number of segments and total length.
    1875                 :            :          * NB: elaborating the addition like this instead of using
    1876                 :            :          *     -= allows us to ensure the result type is uint16_t
    1877                 :            :          *     avoiding compiler warnings on gcc 8.1 at least */
    1878                 :        665 :         head->nb_segs = (uint16_t)(head->nb_segs + tail->nb_segs);
    1879                 :        665 :         head->pkt_len += tail->pkt_len;
    1880                 :            : 
    1881                 :            :         /* pkt_len is only set in the head */
    1882                 :        211 :         tail->pkt_len = tail->data_len;
    1883                 :            : 
    1884                 :        538 :         return 0;
    1885                 :            : }
    1886                 :            : 
    1887                 :            : /**
    1888                 :            :  * For given input values generate raw tx_offload value.
    1889                 :            :  * Note that it is caller responsibility to make sure that input parameters
    1890                 :            :  * don't exceed maximum bit-field values.
    1891                 :            :  * @param il2
    1892                 :            :  *   l2_len value.
    1893                 :            :  * @param il3
    1894                 :            :  *   l3_len value.
    1895                 :            :  * @param il4
    1896                 :            :  *   l4_len value.
    1897                 :            :  * @param tso
    1898                 :            :  *   tso_segsz value.
    1899                 :            :  * @param ol3
    1900                 :            :  *   outer_l3_len value.
    1901                 :            :  * @param ol2
    1902                 :            :  *   outer_l2_len value.
    1903                 :            :  * @param unused
    1904                 :            :  *   unused value.
    1905                 :            :  * @return
    1906                 :            :  *   raw tx_offload value.
    1907                 :            :  */
    1908                 :            : static __rte_always_inline uint64_t
    1909                 :            : rte_mbuf_tx_offload(uint64_t il2, uint64_t il3, uint64_t il4, uint64_t tso,
    1910                 :            :         uint64_t ol3, uint64_t ol2, uint64_t unused)
    1911                 :            : {
    1912                 :      65536 :         return il2 << RTE_MBUF_L2_LEN_OFS |
    1913                 :      65536 :                 il3 << RTE_MBUF_L3_LEN_OFS |
    1914                 :      65536 :                 il4 << RTE_MBUF_L4_LEN_OFS |
    1915                 :      65536 :                 tso << RTE_MBUF_TSO_SEGSZ_OFS |
    1916                 :      65536 :                 ol3 << RTE_MBUF_OUTL3_LEN_OFS |
    1917                 :      65536 :                 ol2 << RTE_MBUF_OUTL2_LEN_OFS |
    1918                 :            :                 unused << RTE_MBUF_TXOFLD_UNUSED_OFS;
    1919                 :            : }
    1920                 :            : 
    1921                 :            : /**
    1922                 :            :  * Validate general requirements for Tx offload in mbuf.
    1923                 :            :  *
    1924                 :            :  * This function checks correctness and completeness of Tx offload settings.
    1925                 :            :  *
    1926                 :            :  * @param m
    1927                 :            :  *   The packet mbuf to be validated.
    1928                 :            :  * @return
    1929                 :            :  *   0 if packet is valid
    1930                 :            :  */
    1931                 :            : static inline int
    1932                 :         11 : rte_validate_tx_offload(const struct rte_mbuf *m)
    1933                 :            : {
    1934                 :         11 :         uint64_t ol_flags = m->ol_flags;
    1935                 :            : 
    1936                 :            :         /* Does packet set any of available offloads? */
    1937         [ +  + ]:         11 :         if (!(ol_flags & RTE_MBUF_F_TX_OFFLOAD_MASK))
    1938                 :            :                 return 0;
    1939                 :            : 
    1940                 :            :         /* IP checksum can be counted only for IPv4 packet */
    1941         [ +  + ]:         10 :         if ((ol_flags & RTE_MBUF_F_TX_IP_CKSUM) && (ol_flags & RTE_MBUF_F_TX_IPV6))
    1942                 :            :                 return -EINVAL;
    1943                 :            : 
    1944                 :            :         /* IP type not set when required */
    1945         [ +  + ]:          9 :         if (ol_flags & (RTE_MBUF_F_TX_L4_MASK | RTE_MBUF_F_TX_TCP_SEG))
    1946         [ +  + ]:          7 :                 if (!(ol_flags & (RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IPV6)))
    1947                 :            :                         return -EINVAL;
    1948                 :            : 
    1949                 :            :         /* Check requirements for TSO packet */
    1950         [ +  + ]:          7 :         if (ol_flags & RTE_MBUF_F_TX_TCP_SEG)
    1951         [ +  + ]:          4 :                 if ((m->tso_segsz == 0) ||
    1952         [ +  + ]:          3 :                                 ((ol_flags & RTE_MBUF_F_TX_IPV4) &&
    1953                 :            :                                  !(ol_flags & RTE_MBUF_F_TX_IP_CKSUM)))
    1954                 :            :                         return -EINVAL;
    1955                 :            : 
    1956                 :            :         /* RTE_MBUF_F_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */
    1957         [ +  + ]:          5 :         if ((ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM) &&
    1958                 :            :                         !(ol_flags & RTE_MBUF_F_TX_OUTER_IPV4))
    1959                 :          1 :                 return -EINVAL;
    1960                 :            : 
    1961                 :            :         return 0;
    1962                 :            : }
    1963                 :            : 
    1964                 :            : /**
    1965                 :            :  * @internal used by rte_pktmbuf_linearize().
    1966                 :            :  */
    1967                 :            : int __rte_pktmbuf_linearize(struct rte_mbuf *mbuf);
    1968                 :            : 
    1969                 :            : /**
    1970                 :            :  * Linearize data in mbuf.
    1971                 :            :  *
    1972                 :            :  * This function moves the mbuf data in the first segment if there is enough
    1973                 :            :  * tailroom. The subsequent segments are unchained and freed.
    1974                 :            :  *
    1975                 :            :  * @param mbuf
    1976                 :            :  *   mbuf to linearize
    1977                 :            :  * @return
    1978                 :            :  *   - 0, on success
    1979                 :            :  *   - -1, on error
    1980                 :            :  */
    1981                 :            : static inline int
    1982                 :            : rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
    1983                 :            : {
    1984         [ +  + ]:         10 :         if (rte_pktmbuf_is_contiguous(mbuf))
    1985                 :            :                 return 0;
    1986                 :          8 :         return __rte_pktmbuf_linearize(mbuf);
    1987                 :            : }
    1988                 :            : 
    1989                 :            : /**
    1990                 :            :  * Dump an mbuf structure to a file.
    1991                 :            :  *
    1992                 :            :  * Dump all fields for the given packet mbuf and all its associated
    1993                 :            :  * segments (in the case of a chained buffer).
    1994                 :            :  *
    1995                 :            :  * @param f
    1996                 :            :  *   A pointer to a file for output
    1997                 :            :  * @param m
    1998                 :            :  *   The packet mbuf.
    1999                 :            :  * @param dump_len
    2000                 :            :  *   If dump_len != 0, also dump the "dump_len" first data bytes of
    2001                 :            :  *   the packet.
    2002                 :            :  */
    2003                 :            : void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
    2004                 :            : 
    2005                 :            : /**
    2006                 :            :  * Get the value of mbuf sched queue_id field.
    2007                 :            :  */
    2008                 :            : static inline uint32_t
    2009                 :            : rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
    2010                 :            : {
    2011                 :          6 :         return m->hash.sched.queue_id;
    2012                 :            : }
    2013                 :            : 
    2014                 :            : /**
    2015                 :            :  * Get the value of mbuf sched traffic_class field.
    2016                 :            :  */
    2017                 :            : static inline uint8_t
    2018                 :            : rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
    2019                 :            : {
    2020                 :            :         return m->hash.sched.traffic_class;
    2021                 :            : }
    2022                 :            : 
    2023                 :            : /**
    2024                 :            :  * Get the value of mbuf sched color field.
    2025                 :            :  */
    2026                 :            : static inline uint8_t
    2027                 :            : rte_mbuf_sched_color_get(const struct rte_mbuf *m)
    2028                 :            : {
    2029                 :         10 :         return m->hash.sched.color;
    2030                 :            : }
    2031                 :            : 
    2032                 :            : /**
    2033                 :            :  * Get the values of mbuf sched queue_id, traffic_class and color.
    2034                 :            :  *
    2035                 :            :  * @param m
    2036                 :            :  *   Mbuf to read
    2037                 :            :  * @param queue_id
    2038                 :            :  *  Returns the queue id
    2039                 :            :  * @param traffic_class
    2040                 :            :  *  Returns the traffic class id
    2041                 :            :  * @param color
    2042                 :            :  *  Returns the colour id
    2043                 :            :  */
    2044                 :            : static inline void
    2045                 :            : rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
    2046                 :            :                         uint8_t *traffic_class,
    2047                 :            :                         uint8_t *color)
    2048                 :            : {
    2049                 :            :         struct rte_mbuf_sched sched = m->hash.sched;
    2050                 :            : 
    2051                 :            :         *queue_id = sched.queue_id;
    2052                 :            :         *traffic_class = sched.traffic_class;
    2053                 :            :         *color = sched.color;
    2054                 :            : }
    2055                 :            : 
    2056                 :            : /**
    2057                 :            :  * Set the mbuf sched queue_id to the defined value.
    2058                 :            :  */
    2059                 :            : static inline void
    2060                 :            : rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
    2061                 :            : {
    2062                 :            :         m->hash.sched.queue_id = queue_id;
    2063                 :            : }
    2064                 :            : 
    2065                 :            : /**
    2066                 :            :  * Set the mbuf sched traffic_class id to the defined value.
    2067                 :            :  */
    2068                 :            : static inline void
    2069                 :            : rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
    2070                 :            : {
    2071                 :            :         m->hash.sched.traffic_class = traffic_class;
    2072                 :            : }
    2073                 :            : 
    2074                 :            : /**
    2075                 :            :  * Set the mbuf sched color id to the defined value.
    2076                 :            :  */
    2077                 :            : static inline void
    2078                 :          0 : rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
    2079                 :            : {
    2080                 :          0 :         m->hash.sched.color = color;
    2081                 :          0 : }
    2082                 :            : 
    2083                 :            : /**
    2084                 :            :  * Set the mbuf sched queue_id, traffic_class and color.
    2085                 :            :  *
    2086                 :            :  * @param m
    2087                 :            :  *   Mbuf to set
    2088                 :            :  * @param queue_id
    2089                 :            :  *  Queue id value to be set
    2090                 :            :  * @param traffic_class
    2091                 :            :  *  Traffic class id value to be set
    2092                 :            :  * @param color
    2093                 :            :  *  Color id to be set
    2094                 :            :  */
    2095                 :            : static inline void
    2096                 :          0 : rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id,
    2097                 :            :                         uint8_t traffic_class,
    2098                 :            :                         uint8_t color)
    2099                 :            : {
    2100                 :         10 :         m->hash.sched = (struct rte_mbuf_sched){
    2101                 :            :                                 .queue_id = queue_id,
    2102                 :            :                                 .traffic_class = traffic_class,
    2103                 :            :                                 .color = color,
    2104                 :            :                                 .reserved = 0,
    2105                 :            :                         };
    2106                 :          0 : }
    2107                 :            : 
    2108                 :            : #ifdef __cplusplus
    2109                 :            : }
    2110                 :            : #endif
    2111                 :            : 
    2112                 :            : #endif /* _RTE_MBUF_H_ */

Generated by: LCOV version 1.14