mbuf: fix NULL freeing when debug enabled
[dpdk.git] / lib / librte_mbuf / rte_mbuf.h
index 0a555e2..ba3bfa8 100644 (file)
@@ -62,6 +62,7 @@
 
 #include <stdint.h>
 #include <rte_common.h>
+#include <rte_config.h>
 #include <rte_mempool.h>
 #include <rte_memory.h>
 #include <rte_atomic.h>
@@ -208,6 +209,13 @@ extern "C" {
 
 /* add new TX flags here */
 
+/**
+ * UDP Fragmentation Offload flag. This flag is used for enabling UDP
+ * fragmentation in SW or in HW. When use UFO, mbuf->tso_segsz is used
+ * to store the MSS of UDP fragments.
+ */
+#define PKT_TX_UDP_SEG (1ULL << 42)
+
 /**
  * Request security offload processing on the TX packet.
  */
@@ -432,7 +440,11 @@ struct rte_mbuf {
         * same mbuf cacheline0 layout for 32-bit and 64-bit. This makes
         * working on vector drivers easier.
         */
-       phys_addr_t buf_physaddr __rte_aligned(sizeof(phys_addr_t));
+       RTE_STD_C11
+       union {
+               rte_iova_t buf_iova;
+               rte_iova_t buf_physaddr; /**< deprecated */
+       } __rte_aligned(sizeof(rte_iova_t));
 
        /* next 8 bytes are initialised on RX descriptor rearm */
        MARKER64 rearm_data;
@@ -580,6 +592,9 @@ struct rte_mbuf {
 
 } __rte_cache_aligned;
 
+/**< Maximum number of nb_segs allowed. */
+#define RTE_MBUF_MAX_NB_SEGS   UINT16_MAX
+
 /**
  * Prefetch the first part of the mbuf
  *
@@ -621,21 +636,28 @@ rte_mbuf_prefetch_part2(struct rte_mbuf *m)
 static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
 
 /**
- * Return the DMA address of the beginning of the mbuf data
+ * Return the IO address of the beginning of the mbuf data
  *
  * @param mb
  *   The pointer to the mbuf.
  * @return
- *   The physical address of the beginning of the mbuf data
+ *   The IO address of the beginning of the mbuf data
  */
+static inline rte_iova_t
+rte_mbuf_data_iova(const struct rte_mbuf *mb)
+{
+       return mb->buf_iova + mb->data_off;
+}
+
+__rte_deprecated
 static inline phys_addr_t
 rte_mbuf_data_dma_addr(const struct rte_mbuf *mb)
 {
-       return mb->buf_physaddr + mb->data_off;
+       return rte_mbuf_data_iova(mb);
 }
 
 /**
- * Return the default DMA address of the beginning of the mbuf data
+ * Return the default IO address of the beginning of the mbuf data
  *
  * This function is used by drivers in their receive function, as it
  * returns the location where data should be written by the NIC, taking
@@ -644,12 +666,19 @@ rte_mbuf_data_dma_addr(const struct rte_mbuf *mb)
  * @param mb
  *   The pointer to the mbuf.
  * @return
- *   The physical address of the beginning of the mbuf data
+ *   The IO address of the beginning of the mbuf data
  */
+static inline rte_iova_t
+rte_mbuf_data_iova_default(const struct rte_mbuf *mb)
+{
+       return mb->buf_iova + RTE_PKTMBUF_HEADROOM;
+}
+
+__rte_deprecated
 static inline phys_addr_t
 rte_mbuf_data_dma_addr_default(const struct rte_mbuf *mb)
 {
-       return mb->buf_physaddr + RTE_PKTMBUF_HEADROOM;
+       return rte_mbuf_data_iova_default(mb);
 }
 
 /**
@@ -743,6 +772,13 @@ rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
        rte_atomic16_set(&m->refcnt_atomic, new_value);
 }
 
+/* internal */
+static inline uint16_t
+__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
+{
+       return (uint16_t)(rte_atomic16_add_return(&m->refcnt_atomic, value));
+}
+
 /**
  * Adds given value to an mbuf's refcnt and returns its new value.
  * @param m
@@ -767,19 +803,26 @@ rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
                return 1 + value;
        }
 
-       return (uint16_t)(rte_atomic16_add_return(&m->refcnt_atomic, value));
+       return __rte_mbuf_refcnt_update(m, value);
 }
 
 #else /* ! RTE_MBUF_REFCNT_ATOMIC */
 
+/* internal */
+static inline uint16_t
+__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
+{
+       m->refcnt = (uint16_t)(m->refcnt + value);
+       return m->refcnt;
+}
+
 /**
  * Adds given value to an mbuf's refcnt and returns its new value.
  */
 static inline uint16_t
 rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
 {
-       m->refcnt = (uint16_t)(m->refcnt + value);
-       return m->refcnt;
+       return __rte_mbuf_refcnt_update(m, value);
 }
 
 /**
@@ -832,15 +875,15 @@ rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
 } while (0)
 
 /**
- * Allocate an unitialized mbuf from mempool *mp*.
+ * Allocate an uninitialized mbuf from mempool *mp*.
  *
  * This function can be used by PMDs (especially in RX functions) to
- * allocate an unitialized mbuf. The driver is responsible of
+ * allocate an uninitialized mbuf. The driver is responsible of
  * initializing all the required fields. See rte_pktmbuf_reset().
  * For standard needs, prefer rte_pktmbuf_alloc().
  *
  * The caller can expect that the following fields of the mbuf structure
- * are initialized: buf_addr, buf_physaddr, buf_len, refcnt=1, nb_segs=1,
+ * are initialized: buf_addr, buf_iova, buf_len, refcnt=1, nb_segs=1,
  * next=NULL, pool, priv_size. The other fields must be initialized
  * by the caller.
  *
@@ -853,11 +896,9 @@ rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
 static inline struct rte_mbuf *rte_mbuf_raw_alloc(struct rte_mempool *mp)
 {
        struct rte_mbuf *m;
-       void *mb = NULL;
 
-       if (rte_mempool_get(mp, &mb) < 0)
+       if (rte_mempool_get(mp, (void **)&m) < 0)
                return NULL;
-       m = (struct rte_mbuf *)mb;
        MBUF_RAW_ALLOC_CHECK(m);
        return m;
 }
@@ -1250,7 +1291,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 
        rte_mbuf_refcnt_update(md, 1);
        mi->priv_size = m->priv_size;
-       mi->buf_physaddr = m->buf_physaddr;
+       mi->buf_iova = m->buf_iova;
        mi->buf_addr = m->buf_addr;
        mi->buf_len = m->buf_len;
 
@@ -1298,7 +1339,7 @@ static inline void rte_pktmbuf_detach(struct rte_mbuf *m)
 
        m->priv_size = priv_size;
        m->buf_addr = (char *)m + mbuf_size;
-       m->buf_physaddr = rte_mempool_virt2iova(m) + mbuf_size;
+       m->buf_iova = rte_mempool_virt2iova(m) + mbuf_size;
        m->buf_len = (uint16_t)buf_len;
        rte_pktmbuf_reset_headroom(m);
        m->data_len = 0;
@@ -1343,8 +1384,7 @@ rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
 
                return m;
 
-       } else if (rte_atomic16_add_return(&m->refcnt_atomic, -1) == 0) {
-
+       } else if (__rte_mbuf_refcnt_update(m, -1) == 0) {
 
                if (RTE_MBUF_INDIRECT(m))
                        rte_pktmbuf_detach(m);
@@ -1392,13 +1432,14 @@ rte_pktmbuf_free_seg(struct rte_mbuf *m)
  * segment is added back into its original mempool.
  *
  * @param m
- *   The packet mbuf to be freed.
+ *   The packet mbuf to be freed. If NULL, the function does nothing.
  */
 static inline void rte_pktmbuf_free(struct rte_mbuf *m)
 {
        struct rte_mbuf *m_next;
 
-       __rte_mbuf_sanity_check(m, 1);
+       if (m != NULL)
+               __rte_mbuf_sanity_check(m, 1);
 
        while (m != NULL) {
                m_next = m->next;
@@ -1429,7 +1470,7 @@ static inline struct rte_mbuf *rte_pktmbuf_clone(struct rte_mbuf *md,
 {
        struct rte_mbuf *mc, *mi, **prev;
        uint32_t pktlen;
-       uint8_t nseg;
+       uint16_t nseg;
 
        if (unlikely ((mc = rte_pktmbuf_alloc(mp)) == NULL))
                return NULL;
@@ -1520,12 +1561,10 @@ static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
  */
 static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
 {
-       struct rte_mbuf *m2 = (struct rte_mbuf *)m;
-
        __rte_mbuf_sanity_check(m, 1);
-       while (m2->next != NULL)
-               m2 = m2->next;
-       return m2;
+       while (m->next != NULL)
+               m = m->next;
+       return m;
 }
 
 /**
@@ -1560,7 +1599,7 @@ static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
 #define rte_pktmbuf_mtod(m, t) rte_pktmbuf_mtod_offset(m, t, 0)
 
 /**
- * A macro that returns the physical address that points to an offset of the
+ * A macro that returns the IO address that points to an offset of the
  * start of the data in the mbuf
  *
  * @param m
@@ -1568,17 +1607,24 @@ static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
  * @param o
  *   The offset into the data to calculate address from.
  */
+#define rte_pktmbuf_iova_offset(m, o) \
+       (rte_iova_t)((m)->buf_iova + (m)->data_off + (o))
+
+/* deprecated */
 #define rte_pktmbuf_mtophys_offset(m, o) \
-       (phys_addr_t)((m)->buf_physaddr + (m)->data_off + (o))
+       rte_pktmbuf_iova_offset(m, o)
 
 /**
- * A macro that returns the physical address that points to the start of the
+ * A macro that returns the IO address that points to the start of the
  * data in the mbuf
  *
  * @param m
  *   The packet mbuf.
  */
-#define rte_pktmbuf_mtophys(m) rte_pktmbuf_mtophys_offset(m, 0)
+#define rte_pktmbuf_iova(m) rte_pktmbuf_iova_offset(m, 0)
+
+/* deprecated */
+#define rte_pktmbuf_mtophys(m) rte_pktmbuf_iova(m)
 
 /**
  * A macro that returns the length of the packet.
@@ -1753,7 +1799,7 @@ const void *__rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off,
  * @param len
  *   The amount of bytes to read.
  * @param buf
- *   The buffer where data is copied if it is not contigous in mbuf
+ *   The buffer where data is copied if it is not contiguous in mbuf
  *   data. Its length should be at least equal to the len parameter.
  * @return
  *   The pointer to the data, either in the mbuf if it is contiguous,
@@ -1782,14 +1828,14 @@ static inline const void *rte_pktmbuf_read(const struct rte_mbuf *m,
  *
  * @return
  *   - 0, on success.
- *   - -EOVERFLOW, if the chain is full (256 entries)
+ *   - -EOVERFLOW, if the chain segment limit exceeded
  */
 static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
 {
        struct rte_mbuf *cur_tail;
 
        /* Check for number-of-segments-overflow */
-       if (head->nb_segs + tail->nb_segs >= 1 << (sizeof(head->nb_segs) * 8))
+       if (head->nb_segs + tail->nb_segs > RTE_MBUF_MAX_NB_SEGS)
                return -EOVERFLOW;
 
        /* Chain 'tail' onto the old tail */
@@ -1797,7 +1843,7 @@ static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail
        cur_tail->next = tail;
 
        /* accumulate number of segments and total length. */
-       head->nb_segs = (uint8_t)(head->nb_segs + tail->nb_segs);
+       head->nb_segs += tail->nb_segs;
        head->pkt_len += tail->pkt_len;
 
        /* pkt_len is only set in the head */