mbuf: fix performance with 128-byte cache line
[dpdk.git] / lib / librte_mbuf / rte_mbuf.h
index 115c560..c973e9b 100644 (file)
@@ -75,9 +75,10 @@ extern "C" {
  *
  * - RX flags start at bit position zero, and get added to the left of previous
  *   flags.
- * - The most-significant 8 bits are reserved for generic mbuf flags
- * - TX flags therefore start at bit position 55 (i.e. 63-8), and new flags get
- *   added to the right of the previously defined flags
+ * - The most-significant 3 bits are reserved for generic mbuf flags
+ * - TX flags therefore start at bit position 60 (i.e. 63-3), and new flags get
+ *   added to the right of the previously defined flags i.e. they should count
+ *   downwards, not upwards.
  *
  * Keep these flags synchronized with rte_get_rx_ol_flag_name() and
  * rte_get_tx_ol_flag_name().
@@ -92,18 +93,8 @@ extern "C" {
 #define PKT_RX_HBUF_OVERFLOW (0ULL << 0)  /**< Header buffer overflow. */
 #define PKT_RX_RECIP_ERR     (0ULL << 0)  /**< Hardware processing error. */
 #define PKT_RX_MAC_ERR       (0ULL << 0)  /**< MAC error. */
-#ifndef RTE_NEXT_ABI
-#define PKT_RX_IPV4_HDR      (1ULL << 5)  /**< RX packet with IPv4 header. */
-#define PKT_RX_IPV4_HDR_EXT  (1ULL << 6)  /**< RX packet with extended IPv4 header. */
-#define PKT_RX_IPV6_HDR      (1ULL << 7)  /**< RX packet with IPv6 header. */
-#define PKT_RX_IPV6_HDR_EXT  (1ULL << 8)  /**< RX packet with extended IPv6 header. */
-#endif /* RTE_NEXT_ABI */
 #define PKT_RX_IEEE1588_PTP  (1ULL << 9)  /**< RX IEEE1588 L2 Ethernet PT Packet. */
 #define PKT_RX_IEEE1588_TMST (1ULL << 10) /**< RX IEEE1588 L2/L4 timestamped packet.*/
-#ifndef RTE_NEXT_ABI
-#define PKT_RX_TUNNEL_IPV4_HDR (1ULL << 11) /**< RX tunnel packet with IPv4 header.*/
-#define PKT_RX_TUNNEL_IPV6_HDR (1ULL << 12) /**< RX tunnel packet with IPv6 header. */
-#endif /* RTE_NEXT_ABI */
 #define PKT_RX_FDIR_ID       (1ULL << 13) /**< FD id reported if FDIR match. */
 #define PKT_RX_FDIR_FLX      (1ULL << 14) /**< Flexible bytes reported if FDIR match. */
 #define PKT_RX_QINQ_PKT      (1ULL << 15)  /**< RX packet with double VLAN stripped. */
@@ -201,12 +192,13 @@ extern "C" {
  */
 #define PKT_TX_OUTER_IPV6    (1ULL << 60)
 
+#define __RESERVED           (1ULL << 61) /**< reserved for future mbuf use */
+
 #define IND_ATTACHED_MBUF    (1ULL << 62) /**< Indirect attached mbuf */
 
 /* Use final bit of flags to indicate a control mbuf */
 #define CTRL_MBUF_FLAG       (1ULL << 63) /**< Mbuf contains control data */
 
-#ifdef RTE_NEXT_ABI
 /*
  * 32 bits are divided into several fields to mark packet types. Note that
  * each field is indexical.
@@ -595,7 +587,7 @@ extern "C" {
 /**
  * Mask of inner layer 3 packet types.
  */
-#define RTE_PTYPE_INNER_INNER_L3_MASK       0x00f00000
+#define RTE_PTYPE_INNER_L3_MASK             0x00f00000
 /**
  * TCP (Transmission Control Protocol) packet type.
  * It is used for inner packet only.
@@ -677,20 +669,25 @@ extern "C" {
 /**
  * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
  * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
- * determin if it is an IPV4 packet.
+ * determine if it is an IPV4 packet.
  */
 #define  RTE_ETH_IS_IPV4_HDR(ptype) ((ptype) & RTE_PTYPE_L3_IPV4)
 
 /**
  * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
  * one, bit 6 is selected to be used for IPv4 only. Then checking bit 6 can
- * determin if it is an IPV4 packet.
+ * determine if it is an IPV4 packet.
  */
 #define  RTE_ETH_IS_IPV6_HDR(ptype) ((ptype) & RTE_PTYPE_L3_IPV6)
 
 /* Check if it is a tunneling packet */
-#define RTE_ETH_IS_TUNNEL_PKT(ptype) ((ptype) & RTE_PTYPE_TUNNEL_MASK)
-#endif /* RTE_NEXT_ABI */
+#define RTE_ETH_IS_TUNNEL_PKT(ptype) ((ptype) & (RTE_PTYPE_TUNNEL_MASK | \
+                                                 RTE_PTYPE_INNER_L2_MASK | \
+                                                 RTE_PTYPE_INNER_L3_MASK | \
+                                                 RTE_PTYPE_INNER_L4_MASK))
+
+/** Alignment constraint of mbuf private area. */
+#define RTE_MBUF_PRIV_ALIGN 8
 
 /**
  * Get the name of a RX offload flag
@@ -731,6 +728,9 @@ typedef uint8_t  MARKER8[0];  /**< generic marker with 1B alignment */
 typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes
                                * with a single assignment */
 
+/** Opaque rte_mbuf_offload  structure declarations */
+struct rte_mbuf_offload;
+
 /**
  * The generic rte_mbuf, containing a packet mbuf.
  */
@@ -766,7 +766,6 @@ struct rte_mbuf {
        /* remaining bytes are set on RX when pulling packet from descriptor */
        MARKER rx_descriptor_fields1;
 
-#ifdef RTE_NEXT_ABI
        /*
         * The packet type, which is the combination of outer/inner L2, L3, L4
         * and tunnel types.
@@ -787,19 +786,7 @@ struct rte_mbuf {
        uint32_t pkt_len;         /**< Total pkt len: sum of all segments. */
        uint16_t data_len;        /**< Amount of data in segment buffer. */
        uint16_t vlan_tci;        /**< VLAN Tag Control Identifier (CPU order) */
-#else /* RTE_NEXT_ABI */
-       /**
-        * The packet type, which is used to indicate ordinary packet and also
-        * tunneled packet format, i.e. each number is represented a type of
-        * packet.
-        */
-       uint16_t packet_type;
 
-       uint16_t data_len;        /**< Amount of data in segment buffer. */
-       uint32_t pkt_len;         /**< Total pkt len: sum of all segments. */
-       uint16_t vlan_tci;        /**< VLAN Tag Control Identifier (CPU order) */
-       uint16_t vlan_tci_outer;  /**< Outer VLAN Tag Control Identifier (CPU order) */
-#endif /* RTE_NEXT_ABI */
        union {
                uint32_t rss;     /**< RSS hash result if RSS enabled */
                struct {
@@ -815,17 +802,19 @@ struct rte_mbuf {
                        /**< First 4 flexible bytes or FD ID, dependent on
                             PKT_RX_FDIR_* flag in ol_flags. */
                } fdir;           /**< Filter identifier if FDIR enabled */
-               uint32_t sched;   /**< Hierarchical scheduler */
+               struct {
+                       uint32_t lo;
+                       uint32_t hi;
+               } sched;          /**< Hierarchical scheduler */
                uint32_t usr;     /**< User defined tags. See rte_distributor_process() */
        } hash;                   /**< hash information */
 
        uint32_t seqn; /**< Sequence number. See also rte_reorder_insert() */
-#ifdef RTE_NEXT_ABI
+
        uint16_t vlan_tci_outer;  /**< Outer VLAN Tag Control Identifier (CPU order) */
-#endif /* RTE_NEXT_ABI */
 
        /* second cache line - fields only used in slow path or on TX */
-       MARKER cacheline1 __rte_cache_aligned;
+       MARKER cacheline1 __rte_cache_min_aligned;
 
        union {
                void *userdata;   /**< Can be used for external metadata */
@@ -858,6 +847,9 @@ struct rte_mbuf {
 
        /** Timesync flags for use with IEEE1588. */
        uint16_t timesync;
+
+       /* Chain of off-load operations to perform on mbuf */
+       struct rte_mbuf_offload *offload_ops;
 } __rte_cache_aligned;
 
 static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
@@ -873,7 +865,7 @@ static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
 static inline struct rte_mbuf *
 rte_mbuf_from_indirect(struct rte_mbuf *mi)
 {
-       return RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size);
+       return (struct rte_mbuf *)RTE_PTR_SUB(mi->buf_addr, sizeof(*mi) + mi->priv_size);
 }
 
 /**
@@ -1232,7 +1224,7 @@ void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
  *   details.
  * @param priv_size
  *   Size of application private are between the rte_mbuf structure
- *   and the data buffer.
+ *   and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
  * @param data_room_size
  *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
  * @param socket_id
@@ -1244,7 +1236,7 @@ void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
  *   with rte_errno set appropriately. Possible rte_errno values include:
  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
  *    - E_RTE_SECONDARY - function was called from a secondary process instance
- *    - EINVAL - cache size provided is too large
+ *    - EINVAL - cache size provided is too large, or priv_size is not aligned.
  *    - ENOSPC - the maximum number of memzones has already been allocated
  *    - EEXIST - a memzone with the same name already exists
  *    - ENOMEM - no appropriate memory area found in which to create memzone
@@ -1638,6 +1630,27 @@ 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
+ * start of the data in the mbuf
+ *
+ * @param m
+ *   The packet mbuf.
+ * @param o
+ *   The offset into the data to calculate address from.
+ */
+#define rte_pktmbuf_mtophys_offset(m, o) \
+       (phys_addr_t)((m)->buf_physaddr + (m)->data_off + (o))
+
+/**
+ * A macro that returns the physical 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)
+
 /**
  * A macro that returns the length of the packet.
  *
@@ -1791,6 +1804,44 @@ static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
        return !!(m->nb_segs == 1);
 }
 
+/**
+ * Chain an mbuf to another, thereby creating a segmented packet.
+ *
+ * Note: The implementation will do a linear walk over the segments to find
+ * the tail entry. For cases when there are many segments, it's better to
+ * chain the entries manually.
+ *
+ * @param head
+ *   The head of the mbuf chain (the first packet)
+ * @param tail
+ *   The mbuf to put last in the chain
+ *
+ * @return
+ *   - 0, on success.
+ *   - -EOVERFLOW, if the chain is full (256 entries)
+ */
+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))
+               return -EOVERFLOW;
+
+       /* Chain 'tail' onto the old tail */
+       cur_tail = rte_pktmbuf_lastseg(head);
+       cur_tail->next = tail;
+
+       /* accumulate number of segments and total length. */
+       head->nb_segs = (uint8_t)(head->nb_segs + tail->nb_segs);
+       head->pkt_len += tail->pkt_len;
+
+       /* pkt_len is only set in the head */
+       tail->pkt_len = tail->data_len;
+
+       return 0;
+}
+
 /**
  * Dump an mbuf structure to the console.
  *