X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_mbuf%2Frte_mbuf.h;h=42db8e3df958ef12ee2e50cb0cdfb6b76bc406b6;hb=bbd778248985e542175e9b4ce560f2d379e78c4e;hp=367fc56da4376e5159b16a1654268b9e4c5f7870;hpb=1224decaa44b3dba58e0a524fd0383969929c575;p=dpdk.git diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 367fc56da4..42db8e3df9 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -55,6 +55,7 @@ #include #include +#include #include #include #include @@ -63,8 +64,9 @@ extern "C" { #endif -/* deprecated feature, renamed in RTE_MBUF_REFCNT */ +/* deprecated options */ #pragma GCC poison RTE_MBUF_SCATTER_GATHER +#pragma GCC poison RTE_MBUF_REFCNT /* * Packet Offload Features Flags. It also carry packet type information. @@ -102,7 +104,22 @@ extern "C" { /* add new RX flags here */ /* add new TX flags here */ -#define PKT_TX_VXLAN_CKSUM (1ULL << 50) /**< TX checksum of VXLAN computed by NIC */ + +/** + * TCP segmentation offload. To enable this offload feature for a + * packet to be transmitted on hardware supporting TSO: + * - set the PKT_TX_TCP_SEG flag in mbuf->ol_flags (this flag implies + * PKT_TX_TCP_CKSUM) + * - set the flag PKT_TX_IPV4 or PKT_TX_IPV6 + * - if it's IPv4, set the PKT_TX_IP_CKSUM flag and write the IP checksum + * to 0 in the packet + * - fill the mbuf offload information: l2_len, l3_len, l4_len, tso_segsz + * - calculate the pseudo header checksum without taking ip_len in account, + * and set it in the TCP header. Refer to rte_ipv4_phdr_cksum() and + * rte_ipv6_phdr_cksum() that can be used as helpers. + */ +#define PKT_TX_TCP_SEG (1ULL << 50) + #define PKT_TX_IEEE1588_TMST (1ULL << 51) /**< TX IEEE1588 packet to timestamp. */ /** @@ -122,31 +139,58 @@ extern "C" { #define PKT_TX_UDP_CKSUM (3ULL << 52) /**< UDP cksum of TX pkt. computed by NIC. */ #define PKT_TX_L4_MASK (3ULL << 52) /**< Mask for L4 cksum offload request. */ -#define PKT_TX_IP_CKSUM (1ULL << 54) /**< IP cksum of TX pkt. computed by NIC. */ -#define PKT_TX_IPV4_CSUM PKT_TX_IP_CKSUM /**< Alias of PKT_TX_IP_CKSUM. */ +/** + * Offload the IP checksum in the hardware. The flag PKT_TX_IPV4 should + * also be set by the application, although a PMD will only check + * PKT_TX_IP_CKSUM. + * - set the IP checksum field in the packet to 0 + * - fill the mbuf offload information: l2_len, l3_len + */ +#define PKT_TX_IP_CKSUM (1ULL << 54) -/** Tell the NIC it's an IPv4 packet. Required for L4 checksum offload or TSO. */ -#define PKT_TX_IPV4 PKT_RX_IPV4_HDR +/** + * Packet is IPv4. This flag must be set when using any offload feature + * (TSO, L3 or L4 checksum) to tell the NIC that the packet is an IPv4 + * packet. If the packet is a tunneled packet, this flag is related to + * the inner headers. + */ +#define PKT_TX_IPV4 (1ULL << 55) -/** Tell the NIC it's an IPv6 packet. Required for L4 checksum offload or TSO. */ -#define PKT_TX_IPV6 PKT_RX_IPV6_HDR +/** + * Packet is IPv6. This flag must be set when using an offload feature + * (TSO or L4 checksum) to tell the NIC that the packet is an IPv6 + * packet. If the packet is a tunneled packet, this flag is related to + * the inner headers. + */ +#define PKT_TX_IPV6 (1ULL << 56) -#define PKT_TX_VLAN_PKT (1ULL << 55) /**< TX packet is a 802.1q VLAN packet. */ +#define PKT_TX_VLAN_PKT (1ULL << 57) /**< TX packet is a 802.1q VLAN packet. */ /** - * TCP segmentation offload. To enable this offload feature for a - * packet to be transmitted on hardware supporting TSO: - * - set the PKT_TX_TCP_SEG flag in mbuf->ol_flags (this flag implies - * PKT_TX_TCP_CKSUM) - * - set the flag PKT_TX_IPV4 or PKT_TX_IPV6 - * - if it's IPv4, set the PKT_TX_IP_CKSUM flag and write the IP checksum - * to 0 in the packet - * - fill the mbuf offload information: l2_len, l3_len, l4_len, tso_segsz - * - calculate the pseudo header checksum without taking ip_len in accound, - * and set it in the TCP header. Refer to rte_ipv4_phdr_cksum() and - * rte_ipv6_phdr_cksum() that can be used as helpers. + * Offload the IP checksum of an external header in the hardware. The + * flag PKT_TX_OUTER_IPV4 should also be set by the application, alto ugh + * a PMD will only check PKT_TX_IP_CKSUM. The IP checksum field in the + * packet must be set to 0. + * - set the outer IP checksum field in the packet to 0 + * - fill the mbuf offload information: outer_l2_len, outer_l3_len */ -#define PKT_TX_TCP_SEG (1ULL << 49) +#define PKT_TX_OUTER_IP_CKSUM (1ULL << 58) + +/** + * Packet outer header is IPv4. This flag must be set when using any + * outer offload feature (L3 or L4 checksum) to tell the NIC that the + * outer header of the tunneled packet is an IPv4 packet. + */ +#define PKT_TX_OUTER_IPV4 (1ULL << 59) + +/** + * Packet outer header is IPv6. This flag must be set when using any + * outer offload feature (L4 checksum) to tell the NIC that the outer + * header of the tunneled packet is an IPv6 packet. + */ +#define PKT_TX_OUTER_IPV6 (1ULL << 60) + +#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 */ @@ -176,8 +220,10 @@ const char *rte_get_tx_ol_flag_name(uint64_t 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 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 */ + /** * The generic rte_mbuf, containing a packet mbuf. */ @@ -187,9 +233,10 @@ struct rte_mbuf { 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. */ + + /* next 6 bytes are initialised on RX descriptor rearm */ + MARKER8 rearm_data; uint16_t data_off; /** @@ -201,11 +248,8 @@ struct rte_mbuf { * config option. */ union { -#ifdef RTE_MBUF_REFCNT rte_atomic16_t refcnt_atomic; /**< Atomically accessed refcnt */ uint16_t refcnt; /**< Non-atomically accessed refcnt */ -#endif - uint16_t refcnt_reserved; /**< Do not use this field */ }; uint8_t nb_segs; /**< Number of segments. */ uint8_t port; /**< Input port. */ @@ -242,9 +286,11 @@ struct rte_mbuf { PKT_RX_FDIR_* flag in ol_flags. */ } fdir; /**< Filter identifier if FDIR enabled */ uint32_t sched; /**< Hierarchical scheduler */ - uint32_t usr; /**< User defined tags. See @rte_distributor_process */ + uint32_t usr; /**< User defined tags. See rte_distributor_process() */ } hash; /**< hash information */ + uint32_t seqn; /**< Sequence number. See also rte_reorder_insert() */ + /* second cache line - fields only used in slow path or on TX */ MARKER cacheline1 __rte_cache_aligned; @@ -266,8 +312,8 @@ struct rte_mbuf { uint64_t tso_segsz:16; /**< TCP TSO segment size */ /* fields for TX offloading of tunnels */ - uint64_t inner_l3_len:9; /**< inner L3 (IP) Hdr Length. */ - uint64_t inner_l2_len:7; /**< inner L2 (MAC) Hdr Length. */ + uint64_t outer_l3_len:9; /**< Outer L3 (IP) Hdr Length. */ + uint64_t outer_l2_len:7; /**< Outer L2 (MAC) Hdr Length. */ /* uint64_t unused:8; */ }; @@ -288,13 +334,12 @@ struct rte_mbuf { /** * Returns TRUE if given mbuf is indirect, or FALSE otherwise. */ -#define RTE_MBUF_INDIRECT(mb) (RTE_MBUF_FROM_BADDR((mb)->buf_addr) != (mb)) +#define RTE_MBUF_INDIRECT(mb) ((mb)->ol_flags & IND_ATTACHED_MBUF) /** * Returns TRUE if given mbuf is direct, or FALSE otherwise. */ -#define RTE_MBUF_DIRECT(mb) (RTE_MBUF_FROM_BADDR((mb)->buf_addr) == (mb)) - +#define RTE_MBUF_DIRECT(mb) (!RTE_MBUF_INDIRECT(mb)) /** * Private data in case of pktmbuf pool. @@ -303,7 +348,8 @@ struct rte_mbuf { * appended after the mempool structure (in private data). */ struct rte_pktmbuf_pool_private { - uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf.*/ + uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf. */ + uint16_t mbuf_priv_size; /**< Size of private area in each mbuf. */ }; #ifdef RTE_LIBRTE_MBUF_DEBUG @@ -336,7 +382,6 @@ if (!(exp)) { \ #endif /* RTE_LIBRTE_MBUF_DEBUG */ -#ifdef RTE_MBUF_REFCNT #ifdef RTE_MBUF_REFCNT_ATOMIC /** @@ -418,15 +463,6 @@ rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value) rte_prefetch0(m); \ } while (0) -#else /* ! RTE_MBUF_REFCNT */ - -/** Mbuf prefetch */ -#define RTE_MBUF_PREFETCH_TO_FREE(m) do { } while(0) - -#define rte_mbuf_refcnt_set(m,v) do { } while(0) - -#endif /* RTE_MBUF_REFCNT */ - /** * Sanity checks on an mbuf. @@ -461,10 +497,8 @@ static inline struct rte_mbuf *__rte_mbuf_raw_alloc(struct rte_mempool *mp) if (rte_mempool_get(mp, &mb) < 0) return NULL; m = (struct rte_mbuf *)mb; -#ifdef RTE_MBUF_REFCNT RTE_MBUF_ASSERT(rte_mbuf_refcnt_read(m) == 0); rte_mbuf_refcnt_set(m, 1); -#endif /* RTE_MBUF_REFCNT */ return (m); } @@ -479,9 +513,7 @@ static inline struct rte_mbuf *__rte_mbuf_raw_alloc(struct rte_mempool *mp) static inline void __attribute__((always_inline)) __rte_mbuf_raw_free(struct rte_mbuf *m) { -#ifdef RTE_MBUF_REFCNT RTE_MBUF_ASSERT(rte_mbuf_refcnt_read(m) == 0); -#endif /* RTE_MBUF_REFCNT */ rte_mempool_put(m->pool, m); } @@ -609,6 +641,87 @@ void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, */ void rte_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg); +/** + * Create a mbuf pool. + * + * This function creates and initializes a packet mbuf pool. It is + * a wrapper to rte_mempool_create() with the proper packet constructor + * and mempool constructor. + * + * @param name + * The name of the mbuf pool. + * @param n + * The number of elements in the mbuf pool. The optimum size (in terms + * of memory usage) for a mempool is when n is a power of two minus one: + * n = (2^q - 1). + * @param cache_size + * Size of the per-core object cache. See rte_mempool_create() for + * details. + * @param priv_size + * Size of application private are between the rte_mbuf structure + * and the data buffer. + * @param data_room_size + * Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM. + * @param socket_id + * The socket identifier where the memory should be allocated. The + * value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the + * reserved zone. + * @return + * The pointer to the new allocated mempool, on success. NULL on error + * 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 + * - 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 + */ +struct rte_mempool * +rte_pktmbuf_pool_create(const char *name, unsigned n, + unsigned cache_size, uint16_t priv_size, uint16_t data_room_size, + int socket_id); + +/** + * Get the data room size of mbufs stored in a pktmbuf_pool + * + * The data room size is the amount of data that can be stored in a + * mbuf including the headroom (RTE_PKTMBUF_HEADROOM). + * + * @param mp + * The packet mbuf pool. + * @return + * The data room size of mbufs stored in this mempool. + */ +static inline uint16_t +rte_pktmbuf_data_room_size(struct rte_mempool *mp) +{ + struct rte_pktmbuf_pool_private *mbp_priv; + + mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp); + return mbp_priv->mbuf_data_room_size; +} + +/** + * Get the application private size of mbufs stored in a pktmbuf_pool + * + * The private size of mbuf is a zone located between the rte_mbuf + * structure and the data buffer where an application can store data + * associated to a packet. + * + * @param mp + * The packet mbuf pool. + * @return + * The private size of mbufs stored in this mempool. + */ +static inline uint16_t +rte_pktmbuf_priv_size(struct rte_mempool *mp) +{ + struct rte_pktmbuf_pool_private *mbp_priv; + + mbp_priv = (struct rte_pktmbuf_pool_private *)rte_mempool_get_priv(mp); + return mbp_priv->mbuf_priv_size; +} + /** * Reset the fields of a packet mbuf to their default values. * @@ -656,8 +769,6 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp) return (m); } -#ifdef RTE_MBUF_REFCNT - /** * Attach packet mbuf to another packet mbuf. * After attachment we refer the mbuf we attached as 'indirect', @@ -696,7 +807,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) mi->next = NULL; mi->pkt_len = mi->data_len; mi->nb_segs = 1; - mi->ol_flags = md->ol_flags; + mi->ol_flags = md->ol_flags | IND_ATTACHED_MBUF; mi->packet_type = md->packet_type; __rte_mbuf_sanity_check(mi, 1); @@ -727,20 +838,27 @@ static inline void rte_pktmbuf_detach(struct rte_mbuf *m) RTE_PKTMBUF_HEADROOM : m->buf_len; m->data_len = 0; -} - -#endif /* RTE_MBUF_REFCNT */ + m->ol_flags = 0; +} static inline struct rte_mbuf* __attribute__((always_inline)) __rte_pktmbuf_prefree_seg(struct rte_mbuf *m) { __rte_mbuf_sanity_check(m, 0); -#ifdef RTE_MBUF_REFCNT + /* + * Check to see if this is the last reference to the mbuf. + * Note: the double check here is deliberate. If the ref_cnt is "atomic" + * the call to "refcnt_update" is a very expensive operation, so we + * don't want to call it in the case where we know we are the holder + * of the last reference to this mbuf i.e. ref_cnt == 1. + * If however, ref_cnt != 1, it's still possible that we may still be + * the final decrementer of the count, so we need to check that + * result also, to make sure the mbuf is freed properly. + */ if (likely (rte_mbuf_refcnt_read(m) == 1) || likely (rte_mbuf_refcnt_update(m, -1) == 0)) { - struct rte_mbuf *md = RTE_MBUF_FROM_BADDR(m->buf_addr); rte_mbuf_refcnt_set(m, 0); @@ -748,17 +866,15 @@ __rte_pktmbuf_prefree_seg(struct rte_mbuf *m) * - detach mbuf * - free attached mbuf segment */ - if (unlikely (md != m)) { + if (RTE_MBUF_INDIRECT(m)) { + struct rte_mbuf *md = RTE_MBUF_FROM_BADDR(m->buf_addr); rte_pktmbuf_detach(m); if (rte_mbuf_refcnt_update(md, -1) == 0) __rte_mbuf_raw_free(md); } -#endif return(m); -#ifdef RTE_MBUF_REFCNT } return (NULL); -#endif } /** @@ -801,8 +917,6 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m) } } -#ifdef RTE_MBUF_REFCNT - /** * Creates a "clone" of the given packet mbuf. * @@ -877,8 +991,6 @@ static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v) } while ((m = m->next) != NULL); } -#endif /* RTE_MBUF_REFCNT */ - /** * Get the headroom in a packet mbuf. *