#define PKT_TX_IPV4_CSUM 0x1000 /**< Alias of PKT_TX_IP_CKSUM. */
#define PKT_TX_IPV4 PKT_RX_IPV4_HDR /**< IPv4 with no IP checksum offload. */
#define PKT_TX_IPV6 PKT_RX_IPV6_HDR /**< IPv6 packet */
+
/*
* Bit 14~13 used for L4 packet type with checksum enabled.
* 00: Reserved
/* Bit 15 */
#define PKT_TX_IEEE1588_TMST 0x8000 /**< TX IEEE1588 packet to timestamp. */
+/* Use final bit of flags to indicate a control mbuf */
+#define CTRL_MBUF_FLAG (1ULL << 63)
+
/**
* Bit Mask to indicate what bits required for building TX context
*/
#define PKT_TX_OFFLOAD_MASK (PKT_TX_VLAN_PKT | PKT_TX_IP_CKSUM | PKT_TX_L4_MASK)
-/** Offload features */
-union rte_vlan_macip {
- uint32_t data;
- struct {
- uint16_t l3_len:9; /**< L3 (IP) Header Length. */
- uint16_t l2_len:7; /**< L2 (MAC) Header Length. */
- uint16_t vlan_tci;
- /**< VLAN Tag Control Identifier (CPU order). */
- } f;
-};
-
-/*
- * Compare mask for vlan_macip_len.data,
- * should be in sync with rte_vlan_macip.f layout.
- * */
-#define TX_VLAN_CMP_MASK 0xFFFF0000 /**< VLAN length - 16-bits. */
-#define TX_MAC_LEN_CMP_MASK 0x0000FE00 /**< MAC length - 7-bits. */
-#define TX_IP_LEN_CMP_MASK 0x000001FF /**< IP length - 9-bits. */
-/**< MAC+IP length. */
-#define TX_MACIP_LEN_CMP_MASK (TX_MAC_LEN_CMP_MASK | TX_IP_LEN_CMP_MASK)
-
+/* define a set of marker types that can be used to refer to set points in the
+ * mbuf */
+typedef void *MARKER[0]; /**< generic marker for a point in a structure */
+typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes
+ * with a single assignment */
/**
* The generic rte_mbuf, containing a packet mbuf.
*/
struct rte_mbuf {
- struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */
+ MARKER cacheline0;
+
void *buf_addr; /**< Virtual address of segment buffer. */
phys_addr_t buf_physaddr; /**< Physical address of segment buffer. */
+
+ /* next 8 bytes are initialised on RX descriptor rearm */
+ MARKER64 rearm_data;
uint16_t buf_len; /**< Length of segment buffer. */
-#ifdef RTE_MBUF_REFCNT
+ uint16_t data_off;
+
/**
* 16-bit Reference counter.
* It should only be accessed using the following functions:
* config option.
*/
union {
- rte_atomic16_t refcnt_atomic; /**< Atomically accessed refcnt */
- uint16_t refcnt; /**< Non-atomically accessed refcnt */
- };
-#else
- uint16_t refcnt_reserved; /**< Do not use this field */
+#ifdef RTE_MBUF_REFCNT
+ rte_atomic16_t refcnt_atomic; /**< Atomically accessed refcnt */
+ uint16_t refcnt; /**< Non-atomically accessed refcnt */
#endif
- uint16_t reserved; /**< Unused field. Required for padding */
- uint16_t ol_flags; /**< Offload features. */
-
- /* valid for any segment */
- struct rte_mbuf *next; /**< Next segment of scattered packet. */
- void* data; /**< Start address of data in segment buffer. */
- uint16_t data_len; /**< Amount of data in segment buffer. */
-
- /* these fields are valid for first segment only */
- uint8_t nb_segs; /**< Number of segments. */
- uint8_t port; /**< Input port. */
- uint32_t pkt_len; /**< Total pkt len: sum of all segment data_len. */
-
- /* offload features, valid for first segment only */
- union rte_vlan_macip vlan_macip;
+ uint16_t refcnt_reserved; /**< Do not use this field */
+ };
+ uint8_t nb_segs; /**< Number of segments. */
+ uint8_t port; /**< Input port. */
+
+ uint64_t ol_flags; /**< Offload features. */
+
+ /* remaining bytes are set on RX when pulling packet from descriptor */
+ MARKER rx_descriptor_fields1;
+ uint16_t reserved2; /**< Unused field. Required for padding */
+ 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 reserved;
union {
- uint32_t rss; /**< RSS hash result if RSS enabled */
+ uint32_t rss; /**< RSS hash result if RSS enabled */
struct {
uint16_t hash;
uint16_t id;
- } fdir; /**< Filter identifier if FDIR enabled */
- uint32_t sched; /**< Hierarchical scheduler */
- } hash; /**< hash information */
+ } fdir; /**< Filter identifier if FDIR enabled */
+ uint32_t sched; /**< Hierarchical scheduler */
+ } hash; /**< hash information */
+
+ /* second cache line - fields only used in slow path or on TX */
+ MARKER cacheline1 __rte_cache_aligned;
union {
- uint8_t metadata[0];
- uint16_t metadata16[0];
- uint32_t metadata32[0];
- uint64_t metadata64[0];
+ void *userdata; /**< Can be used for external metadata */
+ uint64_t udata64; /**< Allow 8-byte userdata on 32-bit */
};
-} __rte_cache_aligned;
-#define RTE_MBUF_METADATA_UINT8(mbuf, offset) \
- (mbuf->metadata[offset])
-#define RTE_MBUF_METADATA_UINT16(mbuf, offset) \
- (mbuf->metadata16[offset/sizeof(uint16_t)])
-#define RTE_MBUF_METADATA_UINT32(mbuf, offset) \
- (mbuf->metadata32[offset/sizeof(uint32_t)])
-#define RTE_MBUF_METADATA_UINT64(mbuf, offset) \
- (mbuf->metadata64[offset/sizeof(uint64_t)])
-
-#define RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset) \
- (&mbuf->metadata[offset])
-#define RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset) \
- (&mbuf->metadata16[offset/sizeof(uint16_t)])
-#define RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset) \
- (&mbuf->metadata32[offset/sizeof(uint32_t)])
-#define RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset) \
- (&mbuf->metadata64[offset/sizeof(uint64_t)])
+ struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */
+ struct rte_mbuf *next; /**< Next segment of scattered packet. */
+
+ /* fields to support TX offloads */
+ union {
+ uint16_t l2_l3_len; /**< combined l2/l3 lengths as single var */
+ struct {
+ uint16_t l3_len:9; /**< L3 (IP) Header Length. */
+ uint16_t l2_len:7; /**< L2 (MAC) Header Length. */
+ };
+ };
+} __rte_cache_aligned;
/**
* Given the buf_addr returns the pointer to corresponding mbuf.
* @param m
* The control mbuf.
*/
-#define rte_ctrlmbuf_data(m) ((m)->data)
+#define rte_ctrlmbuf_data(m) ((char *)((m)->buf_addr) + (m)->data_off)
/**
* A macro that returns the length of the carried data.
*/
#define rte_ctrlmbuf_len(m) rte_pktmbuf_data_len(m)
+/**
+ * Tests if an mbuf is a control mbuf
+ *
+ * @param m
+ * The mbuf to be tested
+ * @return
+ * - True (1) if the mbuf is a control mbuf
+ * - False(0) otherwise
+ */
+static inline int
+rte_is_ctrlmbuf(struct rte_mbuf *m)
+{
+ return (!!(m->ol_flags & CTRL_MBUF_FLAG));
+}
+
/* Operations on pkt mbuf */
/**
*/
static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
{
- uint32_t buf_ofs;
-
m->next = NULL;
m->pkt_len = 0;
- m->vlan_macip.data = 0;
+ m->l2_l3_len = 0;
+ m->vlan_tci = 0;
m->nb_segs = 1;
m->port = 0xff;
m->ol_flags = 0;
- buf_ofs = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
+ m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
RTE_PKTMBUF_HEADROOM : m->buf_len;
- m->data = (char*) m->buf_addr + buf_ofs;
m->data_len = 0;
__rte_mbuf_sanity_check(m, 1);
mi->buf_len = md->buf_len;
mi->next = md->next;
- mi->data = md->data;
+ mi->data_off = md->data_off;
mi->data_len = md->data_len;
mi->port = md->port;
- mi->vlan_macip = md->vlan_macip;
+ mi->vlan_tci = md->vlan_tci;
+ mi->l2_l3_len = md->l2_l3_len;
mi->hash = md->hash;
mi->next = NULL;
{
const struct rte_mempool *mp = m->pool;
void *buf = RTE_MBUF_TO_BADDR(m);
- uint32_t buf_ofs;
uint32_t buf_len = mp->elt_size - sizeof(*m);
m->buf_physaddr = rte_mempool_virt2phy(mp, m) + sizeof (*m);
m->buf_addr = buf;
m->buf_len = (uint16_t)buf_len;
- buf_ofs = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
+ m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
RTE_PKTMBUF_HEADROOM : m->buf_len;
- m->data = (char*) m->buf_addr + buf_ofs;
m->data_len = 0;
}
static inline void __attribute__((always_inline))
rte_pktmbuf_free_seg(struct rte_mbuf *m)
{
- if (likely(NULL != (m = __rte_pktmbuf_prefree_seg(m))))
+ if (likely(NULL != (m = __rte_pktmbuf_prefree_seg(m)))) {
+ m->next = NULL;
__rte_mbuf_raw_free(m);
+ }
}
/**
static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
{
__rte_mbuf_sanity_check(m, 1);
- return (uint16_t) ((char*) m->data - (char*) m->buf_addr);
+ return m->data_off;
}
/**
* @param t
* The type to cast the result into.
*/
-#define rte_pktmbuf_mtod(m, t) ((t)((m)->data))
+#define rte_pktmbuf_mtod(m, t) ((t)((char *)(m)->buf_addr + (m)->data_off))
/**
* A macro that returns the length of the packet.
if (unlikely(len > rte_pktmbuf_headroom(m)))
return NULL;
- m->data = (char*) m->data - len;
+ m->data_off -= len;
m->data_len = (uint16_t)(m->data_len + len);
m->pkt_len = (m->pkt_len + len);
- return (char*) m->data;
+ return (char *)m->buf_addr + m->data_off;
}
/**
if (unlikely(len > rte_pktmbuf_tailroom(m_last)))
return NULL;
- tail = (char*) m_last->data + m_last->data_len;
+ tail = (char *)m_last->buf_addr + m_last->data_off + m_last->data_len;
m_last->data_len = (uint16_t)(m_last->data_len + len);
m->pkt_len = (m->pkt_len + len);
return (char*) tail;
return NULL;
m->data_len = (uint16_t)(m->data_len - len);
- m->data = ((char*) m->data + len);
+ m->data_off += len;
m->pkt_len = (m->pkt_len - len);
- return (char*) m->data;
+ return (char *)m->buf_addr + m->data_off;
}
/**