* [dpdk-dev] [PATCH v7 02/18] ixgbe: support unified packet type in vectorized PMD
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
@ 2015-06-19 8:14 3% ` Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 03/18] mbuf: add definitions of unified packet types Helin Zhang
` (16 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify the packet type, bit masks of packet type for ol_flags are
replaced. In addition, more packet types (UDP, TCP and SCTP) are
supported in vectorized ixgbe PMD.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Note that around 2% performance drop (64B) was observed of doing 4
ports (1 port per 82599 card) IO forwarding on the same SNB core.
Signed-off-by: Cunming Liang <cunming.liang@intel.com>
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
config/common_linuxapp | 2 +-
drivers/net/ixgbe/ixgbe_rxtx_vec.c | 75 +++++++++++++++++++++++++++++++++++++-
2 files changed, 74 insertions(+), 3 deletions(-)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v3 changes:
* Put vector ixgbe changes right after mbuf changes.
* Enabled vector ixgbe PMD by default together with changes for updated
vector PMD.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 617d4a1..5deb55a 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -167,7 +167,7 @@ CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_IXGBE_INC_VECTOR=n
+CONFIG_RTE_IXGBE_INC_VECTOR=y
CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
#
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec.c b/drivers/net/ixgbe/ixgbe_rxtx_vec.c
index abd10f6..ccea7cd 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec.c
@@ -134,6 +134,12 @@ ixgbe_rxq_rearm(struct ixgbe_rx_queue *rxq)
*/
#ifdef RTE_IXGBE_RX_OLFLAGS_ENABLE
+#ifdef RTE_NEXT_ABI
+#define OLFLAGS_MASK_V (((uint64_t)PKT_RX_VLAN_PKT << 48) | \
+ ((uint64_t)PKT_RX_VLAN_PKT << 32) | \
+ ((uint64_t)PKT_RX_VLAN_PKT << 16) | \
+ ((uint64_t)PKT_RX_VLAN_PKT))
+#else
#define OLFLAGS_MASK ((uint16_t)(PKT_RX_VLAN_PKT | PKT_RX_IPV4_HDR |\
PKT_RX_IPV4_HDR_EXT | PKT_RX_IPV6_HDR |\
PKT_RX_IPV6_HDR_EXT))
@@ -142,11 +148,26 @@ ixgbe_rxq_rearm(struct ixgbe_rx_queue *rxq)
((uint64_t)OLFLAGS_MASK << 16) | \
((uint64_t)OLFLAGS_MASK))
#define PTYPE_SHIFT (1)
+#endif /* RTE_NEXT_ABI */
+
#define VTAG_SHIFT (3)
static inline void
desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
{
+#ifdef RTE_NEXT_ABI
+ __m128i vtag0, vtag1;
+ union {
+ uint16_t e[4];
+ uint64_t dword;
+ } vol;
+
+ vtag0 = _mm_unpackhi_epi16(descs[0], descs[1]);
+ vtag1 = _mm_unpackhi_epi16(descs[2], descs[3]);
+ vtag1 = _mm_unpacklo_epi32(vtag0, vtag1);
+ vtag1 = _mm_srli_epi16(vtag1, VTAG_SHIFT);
+ vol.dword = _mm_cvtsi128_si64(vtag1) & OLFLAGS_MASK_V;
+#else
__m128i ptype0, ptype1, vtag0, vtag1;
union {
uint16_t e[4];
@@ -166,6 +187,7 @@ desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
ptype1 = _mm_or_si128(ptype1, vtag1);
vol.dword = _mm_cvtsi128_si64(ptype1) & OLFLAGS_MASK_V;
+#endif /* RTE_NEXT_ABI */
rx_pkts[0]->ol_flags = vol.e[0];
rx_pkts[1]->ol_flags = vol.e[1];
@@ -196,6 +218,18 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
int pos;
uint64_t var;
__m128i shuf_msk;
+#ifdef RTE_NEXT_ABI
+ __m128i crc_adjust = _mm_set_epi16(
+ 0, 0, 0, /* ignore non-length fields */
+ -rxq->crc_len, /* sub crc on data_len */
+ 0, /* ignore high-16bits of pkt_len */
+ -rxq->crc_len, /* sub crc on pkt_len */
+ 0, 0 /* ignore pkt_type field */
+ );
+ __m128i dd_check, eop_check;
+ __m128i desc_mask = _mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFF07F0);
+#else
__m128i crc_adjust = _mm_set_epi16(
0, 0, 0, 0, /* ignore non-length fields */
0, /* ignore high-16bits of pkt_len */
@@ -204,6 +238,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
0 /* ignore pkt_type field */
);
__m128i dd_check, eop_check;
+#endif /* RTE_NEXT_ABI */
if (unlikely(nb_pkts < RTE_IXGBE_VPMD_RX_BURST))
return 0;
@@ -232,6 +267,18 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
eop_check = _mm_set_epi64x(0x0000000200000002LL, 0x0000000200000002LL);
/* mask to shuffle from desc. to mbuf */
+#ifdef RTE_NEXT_ABI
+ shuf_msk = _mm_set_epi8(
+ 7, 6, 5, 4, /* octet 4~7, 32bits rss */
+ 15, 14, /* octet 14~15, low 16 bits vlan_macip */
+ 13, 12, /* octet 12~13, 16 bits data_len */
+ 0xFF, 0xFF, /* skip high 16 bits pkt_len, zero out */
+ 13, 12, /* octet 12~13, low 16 bits pkt_len */
+ 0xFF, 0xFF, /* skip high 16 bits pkt_type */
+ 1, /* octet 1, 8 bits pkt_type field */
+ 0 /* octet 0, 4 bits offset 4 pkt_type field */
+ );
+#else
shuf_msk = _mm_set_epi8(
7, 6, 5, 4, /* octet 4~7, 32bits rss */
0xFF, 0xFF, /* skip high 16 bits vlan_macip, zero out */
@@ -241,18 +288,28 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
13, 12, /* octet 12~13, 16 bits data_len */
0xFF, 0xFF /* skip pkt_type field */
);
+#endif /* RTE_NEXT_ABI */
/* Cache is empty -> need to scan the buffer rings, but first move
* the next 'n' mbufs into the cache */
sw_ring = &rxq->sw_ring[rxq->rx_tail];
- /*
- * A. load 4 packet in one loop
+#ifdef RTE_NEXT_ABI
+ /* A. load 4 packet in one loop
+ * [A*. mask out 4 unused dirty field in desc]
* B. copy 4 mbuf point from swring to rx_pkts
* C. calc the number of DD bits among the 4 packets
* [C*. extract the end-of-packet bit, if requested]
* D. fill info. from desc to mbuf
*/
+#else
+ /* A. load 4 packet in one loop
+ * B. copy 4 mbuf point from swring to rx_pkts
+ * C. calc the number of DD bits among the 4 packets
+ * [C*. extract the end-of-packet bit, if requested]
+ * D. fill info. from desc to mbuf
+ */
+#endif /* RTE_NEXT_ABI */
for (pos = 0, nb_pkts_recd = 0; pos < RTE_IXGBE_VPMD_RX_BURST;
pos += RTE_IXGBE_DESCS_PER_LOOP,
rxdp += RTE_IXGBE_DESCS_PER_LOOP) {
@@ -289,6 +346,16 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
/* B.2 copy 2 mbuf point into rx_pkts */
_mm_storeu_si128((__m128i *)&rx_pkts[pos+2], mbp2);
+#ifdef RTE_NEXT_ABI
+ /* A* mask out 0~3 bits RSS type */
+ descs[3] = _mm_and_si128(descs[3], desc_mask);
+ descs[2] = _mm_and_si128(descs[2], desc_mask);
+
+ /* A* mask out 0~3 bits RSS type */
+ descs[1] = _mm_and_si128(descs[1], desc_mask);
+ descs[0] = _mm_and_si128(descs[0], desc_mask);
+#endif /* RTE_NEXT_ABI */
+
/* avoid compiler reorder optimization */
rte_compiler_barrier();
@@ -301,7 +368,11 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
/* C.1 4=>2 filter staterr info only */
sterr_tmp1 = _mm_unpackhi_epi32(descs[1], descs[0]);
+#ifdef RTE_NEXT_ABI
+ /* set ol_flags with vlan packet type */
+#else
/* set ol_flags with packet type and vlan tag */
+#endif /* RTE_NEXT_ABI */
desc_to_olflags_v(descs, &rx_pkts[pos]);
/* D.2 pkt 3,4 set in_port/nb_seg and remove crc */
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 03/18] mbuf: add definitions of unified packet types
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 02/18] ixgbe: support unified packet type in vectorized PMD Helin Zhang
@ 2015-06-19 8:14 3% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 04/18] e1000: replace bit mask based packet type with unified packet type Helin Zhang
` (15 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
As there are only 6 bit flags in ol_flags for indicating packet
types, which is not enough to describe all the possible packet
types hardware can recognize. For example, i40e hardware can
recognize more than 150 packet types. Unified packet type is
composed of L2 type, L3 type, L4 type, tunnel type, inner L2 type,
inner L3 type and inner L4 type fields, and can be stored in
'struct rte_mbuf' of 32 bits field 'packet_type'.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
lib/librte_mbuf/rte_mbuf.h | 487 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 487 insertions(+)
v3 changes:
* Put the definitions of unified packet type into a single patch.
v4 changes:
* Added detailed description of each packet types.
v5 changes:
* Re-worded the commit logs.
* Added more detailed description for all packet types, together with examples.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index aa55769..5e7cc26 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -201,6 +201,493 @@ extern "C" {
/* 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.
+ * - Bit 3:0 is for L2 types.
+ * - Bit 7:4 is for L3 or outer L3 (for tunneling case) types.
+ * - Bit 11:8 is for L4 or outer L4 (for tunneling case) types.
+ * - Bit 15:12 is for tunnel types.
+ * - Bit 19:16 is for inner L2 types.
+ * - Bit 23:20 is for inner L3 types.
+ * - Bit 27:24 is for inner L4 types.
+ * - Bit 31:28 is reserved.
+ *
+ * To be compatible with Vector PMD, RTE_PTYPE_L3_IPV4, RTE_PTYPE_L3_IPV4_EXT,
+ * RTE_PTYPE_L3_IPV6, RTE_PTYPE_L3_IPV6_EXT, RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP
+ * and RTE_PTYPE_L4_SCTP should be kept as below in a contiguous 7 bits.
+ *
+ * Note that L3 types values are selected for checking IPV4/IPV6 header from
+ * performance point of view. Reading annotations of RTE_ETH_IS_IPV4_HDR and
+ * RTE_ETH_IS_IPV6_HDR is needed for any future changes of L3 type values.
+ *
+ * Note that the packet types of the same packet recognized by different
+ * hardware may be different, as different hardware may have different
+ * capability of packet type recognition.
+ *
+ * examples:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=0x29
+ * | 'version'=6, 'next header'=0x3A
+ * | 'ICMPv6 header'>
+ * will be recognized on i40e hardware as packet type combination of,
+ * RTE_PTYPE_L2_MAC |
+ * RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ * RTE_PTYPE_TUNNEL_IP |
+ * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_INNER_L4_ICMP.
+ *
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x2F
+ * | 'GRE header'
+ * | 'version'=6, 'next header'=0x11
+ * | 'UDP header'>
+ * will be recognized on i40e hardware as packet type combination of,
+ * RTE_PTYPE_L2_MAC |
+ * RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_TUNNEL_GRENAT |
+ * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_INNER_L4_UDP.
+ */
+#define RTE_PTYPE_UNKNOWN 0x00000000
+/**
+ * MAC (Media Access Control) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=[0x0800|0x86DD|others]>
+ */
+#define RTE_PTYPE_L2_MAC 0x00000001
+/**
+ * MAC (Media Access Control) packet type for time sync.
+ *
+ * Packet format:
+ * <'ether type'=0x88F7>
+ */
+#define RTE_PTYPE_L2_MAC_TIMESYNC 0x00000002
+/**
+ * ARP (Address Resolution Protocol) packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0806>
+ */
+#define RTE_PTYPE_L2_ARP 0x00000003
+/**
+ * LLDP (Link Layer Discovery Protocol) packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x88CC>
+ */
+#define RTE_PTYPE_L2_LLDP 0x00000004
+/**
+ * Mask of layer 2 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L2_MASK 0x0000000f
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and does not contain any
+ * header option.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=5>
+ */
+#define RTE_PTYPE_L3_IPV4 0x00000010
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and contains header
+ * options.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[6-15], 'options'>
+ */
+#define RTE_PTYPE_L3_IPV4_EXT 0x00000030
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and does not contain any
+ * extension header.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x3B>
+ */
+#define RTE_PTYPE_L3_IPV6 0x00000040
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and may or maynot contain
+ * header options.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[5-15], <'options'>>
+ */
+#define RTE_PTYPE_L3_IPV4_EXT_UNKNOWN 0x00000090
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and contains extension
+ * headers.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * 'extension headers'>
+ */
+#define RTE_PTYPE_L3_IPV6_EXT 0x000000c0
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and may or maynot contain
+ * extension headers.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * <'extension headers'>>
+ */
+#define RTE_PTYPE_L3_IPV6_EXT_UNKNOWN 0x000000e0
+/**
+ * Mask of layer 3 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L3_MASK 0x000000f0
+/**
+ * TCP (Transmission Control Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=6, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=6>
+ */
+#define RTE_PTYPE_L4_TCP 0x00000100
+/**
+ * UDP (User Datagram Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17>
+ */
+#define RTE_PTYPE_L4_UDP 0x00000200
+/**
+ * Fragmented IP (Internet Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * It refers to those packets of any IP types, which can be recognized as
+ * fragmented. A fragmented packet cannot be recognized as any other L4 types
+ * (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP,
+ * RTE_PTYPE_L4_NONFRAG).
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'MF'=1>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=44>
+ */
+#define RTE_PTYPE_L4_FRAG 0x00000300
+/**
+ * SCTP (Stream Control Transmission Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=132, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=132>
+ */
+#define RTE_PTYPE_L4_SCTP 0x00000400
+/**
+ * ICMP (Internet Control Message Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=1, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=1>
+ */
+#define RTE_PTYPE_L4_ICMP 0x00000500
+/**
+ * Non-fragmented IP (Internet Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * It refers to those packets of any IP types, while cannot be recognized as
+ * any of above L4 types (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP,
+ * RTE_PTYPE_L4_FRAG, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP).
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'!=[6|17|44|132|1]>
+ */
+#define RTE_PTYPE_L4_NONFRAG 0x00000600
+/**
+ * Mask of layer 4 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L4_MASK 0x00000f00
+/**
+ * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=[4|41]>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[4|41]>
+ */
+#define RTE_PTYPE_TUNNEL_IP 0x00001000
+/**
+ * GRE (Generic Routing Encapsulation) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=47>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=47>
+ */
+#define RTE_PTYPE_TUNNEL_GRE 0x00002000
+/**
+ * VXLAN (Virtual eXtensible Local Area Network) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17
+ * | 'destination port'=4798>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17
+ * | 'destination port'=4798>
+ */
+#define RTE_PTYPE_TUNNEL_VXLAN 0x00003000
+/**
+ * NVGRE (Network Virtualization using Generic Routing Encapsulation) tunneling
+ * packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=47
+ * | 'protocol type'=0x6558>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=47
+ * | 'protocol type'=0x6558'>
+ */
+#define RTE_PTYPE_TUNNEL_NVGRE 0x00004000
+/**
+ * GENEVE (Generic Network Virtualization Encapsulation) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17
+ * | 'destination port'=6081>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17
+ * | 'destination port'=6081>
+ */
+#define RTE_PTYPE_TUNNEL_GENEVE 0x00005000
+/**
+ * Tunneling packet type of Teredo, VXLAN (Virtual eXtensible Local Area
+ * Network) or GRE (Generic Routing Encapsulation) could be recognized as this
+ * packet type, if they can not be recognized independently as of hardware
+ * capability.
+ */
+#define RTE_PTYPE_TUNNEL_GRENAT 0x00006000
+/**
+ * Mask of tunneling packet types.
+ */
+#define RTE_PTYPE_TUNNEL_MASK 0x0000f000
+/**
+ * MAC (Media Access Control) packet type.
+ * It is used for inner packet type only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=[0x800|0x86DD]>
+ */
+#define RTE_PTYPE_INNER_L2_MAC 0x00010000
+/**
+ * MAC (Media Access Control) packet type with VLAN (Virtual Local Area
+ * Network) tag.
+ *
+ * Packet format (inner only):
+ * <'ether type'=[0x800|0x86DD], vlan=[1-4095]>
+ */
+#define RTE_PTYPE_INNER_L2_MAC_VLAN 0x00020000
+/**
+ * Mask of inner layer 2 packet types.
+ */
+#define RTE_PTYPE_INNER_L2_MASK 0x000f0000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and does not contain any header option.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=5>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4 0x00100000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and contains header options.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[6-15], 'options'>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4_EXT 0x00200000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and does not contain any extension header.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x3B>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6 0x00300000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and may or maynot contain header options.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[5-15], <'options'>>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN 0x00400000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and contains extension headers.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * 'extension headers'>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6_EXT 0x00500000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and may or maynot contain extension
+ * headers.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * <'extension headers'>>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN 0x00600000
+/**
+ * Mask of inner layer 3 packet types.
+ */
+#define RTE_PTYPE_INNER_INNER_L3_MASK 0x00f00000
+/**
+ * TCP (Transmission Control Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=6, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=6>
+ */
+#define RTE_PTYPE_INNER_L4_TCP 0x01000000
+/**
+ * UDP (User Datagram Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17>
+ */
+#define RTE_PTYPE_INNER_L4_UDP 0x02000000
+/**
+ * Fragmented IP (Internet Protocol) packet type.
+ * It is used for inner packet only, and may or maynot have layer 4 packet.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'MF'=1>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=44>
+ */
+#define RTE_PTYPE_INNER_L4_FRAG 0x03000000
+/**
+ * SCTP (Stream Control Transmission Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=132, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=132>
+ */
+#define RTE_PTYPE_INNER_L4_SCTP 0x04000000
+/**
+ * ICMP (Internet Control Message Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=1, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=1>
+ */
+#define RTE_PTYPE_INNER_L4_ICMP 0x05000000
+/**
+ * Non-fragmented IP (Internet Protocol) packet type.
+ * It is used for inner packet only, and may or maynot have other unknown layer
+ * 4 packet types.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'!=[6|17|44|132|1]>
+ */
+#define RTE_PTYPE_INNER_L4_NONFRAG 0x06000000
+/**
+ * Mask of inner layer 4 packet types.
+ */
+#define RTE_PTYPE_INNER_L4_MASK 0x0f000000
+
+/**
+ * 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.
+ */
+#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.
+ */
+#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 */
+
/**
* Get the name of a RX offload flag
*
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 04/18] e1000: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 02/18] ixgbe: support unified packet type in vectorized PMD Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 03/18] mbuf: add definitions of unified packet types Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 05/18] ixgbe: " Helin Zhang
` (14 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/e1000/igb_rxtx.c | 102 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index 43d6703..d1c2ef8 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -590,6 +590,99 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
* RX functions
*
**********************************************************************/
+#ifdef RTE_NEXT_ABI
+#define IGB_PACKET_TYPE_IPV4 0X01
+#define IGB_PACKET_TYPE_IPV4_TCP 0X11
+#define IGB_PACKET_TYPE_IPV4_UDP 0X21
+#define IGB_PACKET_TYPE_IPV4_SCTP 0X41
+#define IGB_PACKET_TYPE_IPV4_EXT 0X03
+#define IGB_PACKET_TYPE_IPV4_EXT_SCTP 0X43
+#define IGB_PACKET_TYPE_IPV6 0X04
+#define IGB_PACKET_TYPE_IPV6_TCP 0X14
+#define IGB_PACKET_TYPE_IPV6_UDP 0X24
+#define IGB_PACKET_TYPE_IPV6_EXT 0X0C
+#define IGB_PACKET_TYPE_IPV6_EXT_TCP 0X1C
+#define IGB_PACKET_TYPE_IPV6_EXT_UDP 0X2C
+#define IGB_PACKET_TYPE_IPV4_IPV6 0X05
+#define IGB_PACKET_TYPE_IPV4_IPV6_TCP 0X15
+#define IGB_PACKET_TYPE_IPV4_IPV6_UDP 0X25
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT 0X0D
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT_TCP 0X1D
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT_UDP 0X2D
+#define IGB_PACKET_TYPE_MAX 0X80
+#define IGB_PACKET_TYPE_MASK 0X7F
+#define IGB_PACKET_TYPE_SHIFT 0X04
+static inline uint32_t
+igb_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
+{
+ static const uint32_t
+ ptype_table[IGB_PACKET_TYPE_MAX] __rte_cache_aligned = {
+ [IGB_PACKET_TYPE_IPV4] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4,
+ [IGB_PACKET_TYPE_IPV4_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [IGB_PACKET_TYPE_IPV6] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6,
+ [IGB_PACKET_TYPE_IPV4_IPV6] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6,
+ [IGB_PACKET_TYPE_IPV6_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT,
+ [IGB_PACKET_TYPE_IPV4_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV6_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_TCP,
+ [IGB_PACKET_TYPE_IPV6_EXT_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV6_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_UDP,
+ [IGB_PACKET_TYPE_IPV6_EXT_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_SCTP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP,
+ [IGB_PACKET_TYPE_IPV4_EXT_SCTP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_SCTP,
+ };
+ if (unlikely(pkt_info & E1000_RXDADV_PKTTYPE_ETQF))
+ return RTE_PTYPE_UNKNOWN;
+
+ pkt_info = (pkt_info >> IGB_PACKET_TYPE_SHIFT) & IGB_PACKET_TYPE_MASK;
+
+ return ptype_table[pkt_info];
+}
+
+static inline uint64_t
+rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
+{
+ uint64_t pkt_flags = ((hl_tp_rs & 0x0F) == 0) ? 0 : PKT_RX_RSS_HASH;
+
+#if defined(RTE_LIBRTE_IEEE1588)
+ static uint32_t ip_pkt_etqf_map[8] = {
+ 0, 0, 0, PKT_RX_IEEE1588_PTP,
+ 0, 0, 0, 0,
+ };
+
+ pkt_flags |= ip_pkt_etqf_map[(hl_tp_rs >> 4) & 0x07];
+#endif
+
+ return pkt_flags;
+}
+#else /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
{
@@ -617,6 +710,7 @@ rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
#endif
return pkt_flags | (((hl_tp_rs & 0x0F) == 0) ? 0 : PKT_RX_RSS_HASH);
}
+#endif /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_status_to_pkt_flags(uint32_t rx_status)
@@ -790,6 +884,10 @@ eth_igb_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
rxm->ol_flags = pkt_flags;
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = igb_rxd_pkt_info_to_pkt_type(rxd.wb.lower.
+ lo_dword.hs_rss.pkt_info);
+#endif
/*
* Store the mbuf address into the next entry of the array
@@ -1024,6 +1122,10 @@ eth_igb_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
first_seg->ol_flags = pkt_flags;
+#ifdef RTE_NEXT_ABI
+ first_seg->packet_type = igb_rxd_pkt_info_to_pkt_type(rxd.wb.
+ lower.lo_dword.hs_rss.pkt_info);
+#endif
/* Prefetch data of first segment, if configured to do so. */
rte_packet_prefetch((char *)first_seg->buf_addr +
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 05/18] ixgbe: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (2 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 04/18] e1000: replace bit mask based packet type with unified packet type Helin Zhang
@ 2015-06-19 8:14 3% ` Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 06/18] i40e: " Helin Zhang
` (13 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet type among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Note that around 2.5% performance drop (64B) was observed of doing
4 ports (1 port per 82599 card) IO forwarding on the same SNB core.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/ixgbe/ixgbe_rxtx.c | 163 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 163 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 041c544..7b5792b 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -855,6 +855,110 @@ end_of_tx:
* RX functions
*
**********************************************************************/
+#ifdef RTE_NEXT_ABI
+#define IXGBE_PACKET_TYPE_IPV4 0X01
+#define IXGBE_PACKET_TYPE_IPV4_TCP 0X11
+#define IXGBE_PACKET_TYPE_IPV4_UDP 0X21
+#define IXGBE_PACKET_TYPE_IPV4_SCTP 0X41
+#define IXGBE_PACKET_TYPE_IPV4_EXT 0X03
+#define IXGBE_PACKET_TYPE_IPV4_EXT_SCTP 0X43
+#define IXGBE_PACKET_TYPE_IPV6 0X04
+#define IXGBE_PACKET_TYPE_IPV6_TCP 0X14
+#define IXGBE_PACKET_TYPE_IPV6_UDP 0X24
+#define IXGBE_PACKET_TYPE_IPV6_EXT 0X0C
+#define IXGBE_PACKET_TYPE_IPV6_EXT_TCP 0X1C
+#define IXGBE_PACKET_TYPE_IPV6_EXT_UDP 0X2C
+#define IXGBE_PACKET_TYPE_IPV4_IPV6 0X05
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_TCP 0X15
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_UDP 0X25
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT 0X0D
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_TCP 0X1D
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_UDP 0X2D
+#define IXGBE_PACKET_TYPE_MAX 0X80
+#define IXGBE_PACKET_TYPE_MASK 0X7F
+#define IXGBE_PACKET_TYPE_SHIFT 0X04
+static inline uint32_t
+ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
+{
+ static const uint32_t
+ ptype_table[IXGBE_PACKET_TYPE_MAX] __rte_cache_aligned = {
+ [IXGBE_PACKET_TYPE_IPV4] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4,
+ [IXGBE_PACKET_TYPE_IPV4_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [IXGBE_PACKET_TYPE_IPV6] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6,
+ [IXGBE_PACKET_TYPE_IPV6_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT,
+ [IXGBE_PACKET_TYPE_IPV4_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV6_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV6_EXT_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV6_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV6_EXT_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_SCTP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP,
+ [IXGBE_PACKET_TYPE_IPV4_EXT_SCTP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_SCTP,
+ };
+ if (unlikely(pkt_info & IXGBE_RXDADV_PKTTYPE_ETQF))
+ return RTE_PTYPE_UNKNOWN;
+
+ pkt_info = (pkt_info >> IXGBE_PACKET_TYPE_SHIFT) &
+ IXGBE_PACKET_TYPE_MASK;
+
+ return ptype_table[pkt_info];
+}
+
+static inline uint64_t
+ixgbe_rxd_pkt_info_to_pkt_flags(uint16_t pkt_info)
+{
+ static uint64_t ip_rss_types_map[16] __rte_cache_aligned = {
+ 0, PKT_RX_RSS_HASH, PKT_RX_RSS_HASH, PKT_RX_RSS_HASH,
+ 0, PKT_RX_RSS_HASH, 0, PKT_RX_RSS_HASH,
+ PKT_RX_RSS_HASH, 0, 0, 0,
+ 0, 0, 0, PKT_RX_FDIR,
+ };
+#ifdef RTE_LIBRTE_IEEE1588
+ static uint64_t ip_pkt_etqf_map[8] = {
+ 0, 0, 0, PKT_RX_IEEE1588_PTP,
+ 0, 0, 0, 0,
+ };
+
+ if (likely(pkt_info & IXGBE_RXDADV_PKTTYPE_ETQF))
+ return ip_pkt_etqf_map[(pkt_info >> 4) & 0X07] |
+ ip_rss_types_map[pkt_info & 0XF];
+ else
+ return ip_rss_types_map[pkt_info & 0XF];
+#else
+ return ip_rss_types_map[pkt_info & 0XF];
+#endif
+}
+#else /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
{
@@ -890,6 +994,7 @@ rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
#endif
return pkt_flags | ip_rss_types_map[hl_tp_rs & 0xF];
}
+#endif /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_status_to_pkt_flags(uint32_t rx_status)
@@ -945,7 +1050,13 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
struct rte_mbuf *mb;
uint16_t pkt_len;
uint64_t pkt_flags;
+#ifdef RTE_NEXT_ABI
+ int nb_dd;
+ uint32_t s[LOOK_AHEAD];
+ uint16_t pkt_info[LOOK_AHEAD];
+#else
int s[LOOK_AHEAD], nb_dd;
+#endif /* RTE_NEXT_ABI */
int i, j, nb_rx = 0;
@@ -968,6 +1079,12 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
for (j = LOOK_AHEAD-1; j >= 0; --j)
s[j] = rxdp[j].wb.upper.status_error;
+#ifdef RTE_NEXT_ABI
+ for (j = LOOK_AHEAD-1; j >= 0; --j)
+ pkt_info[j] = rxdp[j].wb.lower.lo_dword.
+ hs_rss.pkt_info;
+#endif /* RTE_NEXT_ABI */
+
/* Compute how many status bits were set */
nb_dd = 0;
for (j = 0; j < LOOK_AHEAD; ++j)
@@ -984,12 +1101,22 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
mb->vlan_tci = rte_le_to_cpu_16(rxdp[j].wb.upper.vlan);
/* convert descriptor fields to rte mbuf flags */
+#ifdef RTE_NEXT_ABI
+ pkt_flags = rx_desc_status_to_pkt_flags(s[j]);
+ pkt_flags |= rx_desc_error_to_pkt_flags(s[j]);
+ pkt_flags |=
+ ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info[j]);
+ mb->ol_flags = pkt_flags;
+ mb->packet_type =
+ ixgbe_rxd_pkt_info_to_pkt_type(pkt_info[j]);
+#else /* RTE_NEXT_ABI */
pkt_flags = rx_desc_hlen_type_rss_to_pkt_flags(
rxdp[j].wb.lower.lo_dword.data);
/* reuse status field from scan list */
pkt_flags |= rx_desc_status_to_pkt_flags(s[j]);
pkt_flags |= rx_desc_error_to_pkt_flags(s[j]);
mb->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
mb->hash.rss = rxdp[j].wb.lower.hi_dword.rss;
@@ -1206,7 +1333,11 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
union ixgbe_adv_rx_desc rxd;
uint64_t dma_addr;
uint32_t staterr;
+#ifdef RTE_NEXT_ABI
+ uint32_t pkt_info;
+#else
uint32_t hlen_type_rss;
+#endif
uint16_t pkt_len;
uint16_t rx_id;
uint16_t nb_rx;
@@ -1324,6 +1455,19 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
rxm->data_len = pkt_len;
rxm->port = rxq->port_id;
+#ifdef RTE_NEXT_ABI
+ pkt_info = rte_le_to_cpu_32(rxd.wb.lower.lo_dword.hs_rss.
+ pkt_info);
+ /* Only valid if PKT_RX_VLAN_PKT set in pkt_flags */
+ rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan);
+
+ pkt_flags = rx_desc_status_to_pkt_flags(staterr);
+ pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
+ pkt_flags = pkt_flags |
+ ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info);
+ rxm->ol_flags = pkt_flags;
+ rxm->packet_type = ixgbe_rxd_pkt_info_to_pkt_type(pkt_info);
+#else /* RTE_NEXT_ABI */
hlen_type_rss = rte_le_to_cpu_32(rxd.wb.lower.lo_dword.data);
/* Only valid if PKT_RX_VLAN_PKT set in pkt_flags */
rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan);
@@ -1332,6 +1476,7 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
rxm->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
rxm->hash.rss = rxd.wb.lower.hi_dword.rss;
@@ -1405,6 +1550,23 @@ ixgbe_fill_cluster_head_buf(
uint8_t port_id,
uint32_t staterr)
{
+#ifdef RTE_NEXT_ABI
+ uint16_t pkt_info;
+ uint64_t pkt_flags;
+
+ head->port = port_id;
+
+ /* The vlan_tci field is only valid when PKT_RX_VLAN_PKT is
+ * set in the pkt_flags field.
+ */
+ head->vlan_tci = rte_le_to_cpu_16(desc->wb.upper.vlan);
+ pkt_info = rte_le_to_cpu_32(desc->wb.lower.lo_dword.hs_rss.pkt_info);
+ pkt_flags = rx_desc_status_to_pkt_flags(staterr);
+ pkt_flags |= rx_desc_error_to_pkt_flags(staterr);
+ pkt_flags |= ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info);
+ head->ol_flags = pkt_flags;
+ head->packet_type = ixgbe_rxd_pkt_info_to_pkt_type(pkt_info);
+#else /* RTE_NEXT_ABI */
uint32_t hlen_type_rss;
uint64_t pkt_flags;
@@ -1420,6 +1582,7 @@ ixgbe_fill_cluster_head_buf(
pkt_flags |= rx_desc_status_to_pkt_flags(staterr);
pkt_flags |= rx_desc_error_to_pkt_flags(staterr);
head->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
head->hash.rss = rte_le_to_cpu_32(desc->wb.lower.hi_dword.rss);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 00/18] unified packet type
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 02/18] ixgbe: support unified packet type in vectorized PMD Helin Zhang
` (17 more replies)
0 siblings, 18 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
Currently only 6 bits which are stored in ol_flags are used to indicate
the packet types. This is not enough, as some NIC hardware can recognize
quite a lot of packet types, e.g i40e hardware can recognize more than 150
packet types. Hiding those packet types hides hardware offload capabilities
which could be quite useful for improving performance and for end users.
So an unified packet types are needed to support all possible PMDs. A 16
bits packet_type in mbuf structure can be changed to 32 bits and used for
this purpose. In addition, all packet types stored in ol_flag field should
be deleted at all, and 6 bits of ol_flags can be save as the benifit.
Initially, 32 bits of packet_type can be divided into several sub fields
to indicate different packet type information of a packet. The initial
design is to divide those bits into fields for L2 types, L3 types, L4 types,
tunnel types, inner L2 types, inner L3 types and inner L4 types. All PMDs
should translate the offloaded packet types into these 7 fields of
information, for user applications.
To avoid breaking ABI compatibility, currently all the code changes for
unified packet type are disabled at compile time by default. Users can
enable it manually by defining the macro of RTE_NEXT_ABI. The code changes
will be valid by default in a future release, and the old version will be
deleted accordingly, after the ABI change process is done.
Note that this patch set should be integrated after another patch set for
'[PATCH v3 0/7] support i40e QinQ stripping and insertion', to clearly
solve the conflict during integration. As both patch sets modified
'struct rte_mbuf', and the final layout of the 'struct rte_mbuf' is key to
vectorized ixgbe PMD.
v2 changes:
* Enlarged the packet_type field from 16 bits to 32 bits.
* Redefined the packet type sub-fields.
* Updated the 'struct rte_kni_mbuf' for KNI according to the mbuf changes.
* Used redefined packet types and enlarged packet_type field for all PMDs
and corresponding applications.
* Removed changes in bond and its relevant application, as there is no need
at all according to the recent bond changes.
v3 changes:
* Put the mbuf layout changes into a single patch.
* Put vector ixgbe changes right after mbuf changes.
* Disabled vector ixgbe PMD by default, as mbuf layout changed, and then
re-enabled it after vector ixgbe PMD updated.
* Put the definitions of unified packet type into a single patch.
* Minor bug fixes and enhancements in l3fwd example.
v4 changes:
* Added detailed description of each packet types.
* Supported unified packet type of fm10k.
* Added printing logs of packet types of each received packet for rxonly
mode in testpmd.
* Removed several useless code lines which block packet type unification from
app/test/packet_burst_generator.c.
v5 changes:
* Added more detailed description for each packet types, together with examples.
* Rolled back the macro definitions of RX packet flags, for ABI compitability.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
* Integrated with patch set for '[PATCH v3 0/7] support i40e QinQ stripping
and insertion', to clearly solve the conflicts during merging.
Helin Zhang (18):
mbuf: redefine packet_type in rte_mbuf
ixgbe: support unified packet type in vectorized PMD
mbuf: add definitions of unified packet types
e1000: replace bit mask based packet type with unified packet type
ixgbe: replace bit mask based packet type with unified packet type
i40e: replace bit mask based packet type with unified packet type
enic: replace bit mask based packet type with unified packet type
vmxnet3: replace bit mask based packet type with unified packet type
fm10k: replace bit mask based packet type with unified packet type
app/test-pipeline: replace bit mask based packet type with unified
packet type
app/testpmd: replace bit mask based packet type with unified packet
type
app/test: Remove useless code
examples/ip_fragmentation: replace bit mask based packet type with
unified packet type
examples/ip_reassembly: replace bit mask based packet type with
unified packet type
examples/l3fwd-acl: replace bit mask based packet type with unified
packet type
examples/l3fwd-power: replace bit mask based packet type with unified
packet type
examples/l3fwd: replace bit mask based packet type with unified packet
type
mbuf: remove old packet type bit masks
app/test-pipeline/pipeline_hash.c | 13 +
app/test-pmd/csumonly.c | 14 +
app/test-pmd/rxonly.c | 183 +++++++
app/test/packet_burst_generator.c | 6 +-
drivers/net/e1000/igb_rxtx.c | 102 ++++
drivers/net/enic/enic_main.c | 26 +
drivers/net/fm10k/fm10k_rxtx.c | 27 ++
drivers/net/i40e/i40e_rxtx.c | 528 +++++++++++++++++++++
drivers/net/ixgbe/ixgbe_rxtx.c | 163 +++++++
drivers/net/ixgbe/ixgbe_rxtx_vec.c | 75 ++-
drivers/net/vmxnet3/vmxnet3_rxtx.c | 8 +
examples/ip_fragmentation/main.c | 9 +
examples/ip_reassembly/main.c | 9 +
examples/l3fwd-acl/main.c | 29 +-
examples/l3fwd-power/main.c | 8 +
examples/l3fwd/main.c | 123 ++++-
.../linuxapp/eal/include/exec-env/rte_kni_common.h | 6 +
lib/librte_mbuf/rte_mbuf.c | 4 +
lib/librte_mbuf/rte_mbuf.h | 514 ++++++++++++++++++++
19 files changed, 1834 insertions(+), 13 deletions(-)
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 07/18] enic: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (4 preceding siblings ...)
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 06/18] i40e: " Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 08/18] vmxnet3: " Helin Zhang
` (11 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/enic/enic_main.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 15313c2..f47e96c 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -423,7 +423,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
rx_pkt->pkt_len = bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
rx_pkt->ol_flags |= PKT_RX_IP_CKSUM_BAD;
@@ -432,7 +436,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
rx_pkt->ol_flags |= PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV6;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
} else {
/* Header split */
if (sop && !eop) {
@@ -445,7 +453,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
*rx_pkt_bucket = rx_pkt;
rx_pkt->pkt_len = bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
rx_pkt->ol_flags |=
@@ -457,13 +469,22 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV6;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
} else {
/* Payload */
hdr_rx_pkt = *rx_pkt_bucket;
hdr_rx_pkt->pkt_len += bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ hdr_rx_pkt->packet_type =
+ RTE_PTYPE_L3_IPV4;
+#else
hdr_rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
hdr_rx_pkt->ol_flags |=
@@ -475,7 +496,12 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ hdr_rx_pkt->packet_type =
+ RTE_PTYPE_L3_IPV6;
+#else
hdr_rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
}
}
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 06/18] i40e: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (3 preceding siblings ...)
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 05/18] ixgbe: " Helin Zhang
@ 2015-06-19 8:14 3% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 07/18] enic: " Helin Zhang
` (12 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/i40e/i40e_rxtx.c | 528 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 528 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index b2e1d6d..b951da0 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -176,6 +176,514 @@ i40e_rxd_error_to_pkt_flags(uint64_t qword)
return flags;
}
+#ifdef RTE_NEXT_ABI
+/* For each value it means, datasheet of hardware can tell more details */
+static inline uint32_t
+i40e_rxd_pkt_type_mapping(uint8_t ptype)
+{
+ static const uint32_t ptype_table[UINT8_MAX] __rte_cache_aligned = {
+ /* L2 types */
+ /* [0] reserved */
+ [1] = RTE_PTYPE_L2_MAC,
+ [2] = RTE_PTYPE_L2_MAC_TIMESYNC,
+ /* [3] - [5] reserved */
+ [6] = RTE_PTYPE_L2_LLDP,
+ /* [7] - [10] reserved */
+ [11] = RTE_PTYPE_L2_ARP,
+ /* [12] - [21] reserved */
+
+ /* Non tunneled IPv4 */
+ [22] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [23] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [24] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [25] reserved */
+ [26] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [27] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [28] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+
+ /* IPv4 --> IPv4 */
+ [29] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [30] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [31] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [32] reserved */
+ [33] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [34] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [35] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> IPv6 */
+ [36] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [37] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [38] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [39] reserved */
+ [40] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [41] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [42] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN */
+ [43] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> IPv4 */
+ [44] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [45] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [46] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [47] reserved */
+ [48] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [49] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [50] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> IPv6 */
+ [51] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [52] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [53] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [54] reserved */
+ [55] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [56] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [57] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC */
+ [58] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC --> IPv4 */
+ [59] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [60] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [61] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [62] reserved */
+ [63] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [64] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [65] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC --> IPv6 */
+ [66] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [67] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [68] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [69] reserved */
+ [70] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [71] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [72] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN */
+ [73] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv4 */
+ [74] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [75] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [76] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [77] reserved */
+ [78] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [79] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [80] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv6 */
+ [81] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [82] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [83] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [84] reserved */
+ [85] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [86] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [87] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* Non tunneled IPv6 */
+ [88] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [89] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [90] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [91] reserved */
+ [92] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [93] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [94] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+
+ /* IPv6 --> IPv4 */
+ [95] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [96] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [97] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [98] reserved */
+ [99] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [100] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [101] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> IPv6 */
+ [102] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [103] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [104] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [105] reserved */
+ [106] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [107] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [108] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN */
+ [109] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> IPv4 */
+ [110] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [111] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [112] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [113] reserved */
+ [114] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [115] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [116] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> IPv6 */
+ [117] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [118] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [119] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [120] reserved */
+ [121] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [122] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [123] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC */
+ [124] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC --> IPv4 */
+ [125] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [126] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [127] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [128] reserved */
+ [129] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [130] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [131] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC --> IPv6 */
+ [132] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [133] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [134] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [135] reserved */
+ [136] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [137] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [138] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN */
+ [139] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv4 */
+ [140] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [141] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [142] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [143] reserved */
+ [144] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [145] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [146] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv6 */
+ [147] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [148] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [149] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [150] reserved */
+ [151] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [152] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [153] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* All others reserved */
+ };
+
+ return ptype_table[ptype];
+}
+#else /* RTE_NEXT_ABI */
/* Translate pkt types to pkt flags */
static inline uint64_t
i40e_rxd_ptype_to_pkt_flags(uint64_t qword)
@@ -443,6 +951,7 @@ i40e_rxd_ptype_to_pkt_flags(uint64_t qword)
return ip_ptype_map[ptype];
}
+#endif /* RTE_NEXT_ABI */
#define I40E_RX_DESC_EXT_STATUS_FLEXBH_MASK 0x03
#define I40E_RX_DESC_EXT_STATUS_FLEXBH_FD_ID 0x01
@@ -730,11 +1239,18 @@ i40e_rx_scan_hw_ring(struct i40e_rx_queue *rxq)
i40e_rxd_to_vlan_tci(mb, &rxdp[j]);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ mb->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >>
+ I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
mb->packet_type = (uint16_t)((qword1 &
I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
mb->hash.rss = rte_le_to_cpu_32(\
rxdp[j].wb.qword0.hi_dword.rss);
@@ -971,9 +1487,15 @@ i40e_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
i40e_rxd_to_vlan_tci(rxm, &rxd);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
rxm->packet_type = (uint16_t)((qword1 & I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
rxm->hash.rss =
rte_le_to_cpu_32(rxd.wb.qword0.hi_dword.rss);
@@ -1129,10 +1651,16 @@ i40e_recv_scattered_pkts(void *rx_queue,
i40e_rxd_to_vlan_tci(first_seg, &rxd);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ first_seg->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
first_seg->packet_type = (uint16_t)((qword1 &
I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
rxm->hash.rss =
rte_le_to_cpu_32(rxd.wb.qword0.hi_dword.rss);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 08/18] vmxnet3: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (5 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 07/18] enic: " Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 09/18] fm10k: " Helin Zhang
` (10 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/vmxnet3/vmxnet3_rxtx.c | 8 ++++++++
1 file changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index a1eac45..25ae2f6 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -649,9 +649,17 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = RTE_PTYPE_L3_IPV4_EXT;
+#else
rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
+#endif
else
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rxm->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!rcd->cnc) {
if (!rcd->ipc)
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 09/18] fm10k: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (6 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 08/18] vmxnet3: " Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 10/18] app/test-pipeline: " Helin Zhang
` (9 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/fm10k/fm10k_rxtx.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
v4 changes:
* Supported unified packet type of fm10k from v4.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index 56df6cd..45005c2 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -68,12 +68,37 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
static inline void
rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
{
+#ifdef RTE_NEXT_ABI
+ static const uint32_t
+ ptype_table[FM10K_RXD_PKTTYPE_MASK >> FM10K_RXD_PKTTYPE_SHIFT]
+ __rte_cache_aligned = {
+ [FM10K_PKTTYPE_OTHER] = RTE_PTYPE_L2_MAC,
+ [FM10K_PKTTYPE_IPV4] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4,
+ [FM10K_PKTTYPE_IPV4_EX] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [FM10K_PKTTYPE_IPV6] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6,
+ [FM10K_PKTTYPE_IPV6_EX] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [FM10K_PKTTYPE_IPV4 | FM10K_PKTTYPE_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [FM10K_PKTTYPE_IPV6 | FM10K_PKTTYPE_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [FM10K_PKTTYPE_IPV4 | FM10K_PKTTYPE_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [FM10K_PKTTYPE_IPV6 | FM10K_PKTTYPE_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ };
+
+ m->packet_type = ptype_table[(d->w.pkt_info & FM10K_RXD_PKTTYPE_MASK)
+ >> FM10K_RXD_PKTTYPE_SHIFT];
+#else /* RTE_NEXT_ABI */
uint16_t ptype;
static const uint16_t pt_lut[] = { 0,
PKT_RX_IPV4_HDR, PKT_RX_IPV4_HDR_EXT,
PKT_RX_IPV6_HDR, PKT_RX_IPV6_HDR_EXT,
0, 0, 0
};
+#endif /* RTE_NEXT_ABI */
if (d->w.pkt_info & FM10K_RXD_RSSTYPE_MASK)
m->ol_flags |= PKT_RX_RSS_HASH;
@@ -97,9 +122,11 @@ rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
if (unlikely(d->d.staterr & FM10K_RXD_STATUS_RXE))
m->ol_flags |= PKT_RX_RECIP_ERR;
+#ifndef RTE_NEXT_ABI
ptype = (d->d.data & FM10K_RXD_PKTTYPE_MASK_L3) >>
FM10K_RXD_PKTTYPE_SHIFT;
m->ol_flags |= pt_lut[(uint8_t)ptype];
+#endif
}
uint16_t
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 10/18] app/test-pipeline: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (7 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 09/18] fm10k: " Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 11/18] app/testpmd: " Helin Zhang
` (8 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
app/test-pipeline/pipeline_hash.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
index 4598ad4..aa3f9e5 100644
--- a/app/test-pipeline/pipeline_hash.c
+++ b/app/test-pipeline/pipeline_hash.c
@@ -459,20 +459,33 @@ app_main_loop_rx_metadata(void) {
signature = RTE_MBUF_METADATA_UINT32_PTR(m, 0);
key = RTE_MBUF_METADATA_UINT8_PTR(m, 32);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
ip_hdr = (struct ipv4_hdr *)
&m_data[sizeof(struct ether_hdr)];
ip_dst = ip_hdr->dst_addr;
k32 = (uint32_t *) key;
k32[0] = ip_dst & 0xFFFFFF00;
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
} else {
+#endif
ipv6_hdr = (struct ipv6_hdr *)
&m_data[sizeof(struct ether_hdr)];
ipv6_dst = ipv6_hdr->dst_addr;
memcpy(key, ipv6_dst, 16);
+#ifdef RTE_NEXT_ABI
+ } else
+ continue;
+#else
}
+#endif
*signature = test_hash(key, 0, 0);
}
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 11/18] app/testpmd: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (8 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 10/18] app/test-pipeline: " Helin Zhang
@ 2015-06-19 8:14 3% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 12/18] app/test: Remove useless code Helin Zhang
` (7 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
---
app/test-pmd/csumonly.c | 14 ++++
app/test-pmd/rxonly.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 197 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v4 changes:
* Added printing logs of packet types of each received packet in rxonly mode.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 950ea82..fab9600 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -202,8 +202,14 @@ parse_ethernet(struct ether_hdr *eth_hdr, struct testpmd_offload_info *info)
/* Parse a vxlan header */
static void
+#ifdef RTE_NEXT_ABI
+parse_vxlan(struct udp_hdr *udp_hdr,
+ struct testpmd_offload_info *info,
+ uint32_t pkt_type)
+#else
parse_vxlan(struct udp_hdr *udp_hdr, struct testpmd_offload_info *info,
uint64_t mbuf_olflags)
+#endif
{
struct ether_hdr *eth_hdr;
@@ -211,8 +217,12 @@ parse_vxlan(struct udp_hdr *udp_hdr, struct testpmd_offload_info *info,
* (rfc7348) or that the rx offload flag is set (i40e only
* currently) */
if (udp_hdr->dst_port != _htons(4789) &&
+#ifdef RTE_NEXT_ABI
+ RTE_ETH_IS_TUNNEL_PKT(pkt_type) == 0)
+#else
(mbuf_olflags & (PKT_RX_TUNNEL_IPV4_HDR |
PKT_RX_TUNNEL_IPV6_HDR)) == 0)
+#endif
return;
info->is_tunnel = 1;
@@ -549,7 +559,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
struct udp_hdr *udp_hdr;
udp_hdr = (struct udp_hdr *)((char *)l3_hdr +
info.l3_len);
+#ifdef RTE_NEXT_ABI
+ parse_vxlan(udp_hdr, &info, m->packet_type);
+#else
parse_vxlan(udp_hdr, &info, m->ol_flags);
+#endif
} else if (info.l4_proto == IPPROTO_GRE) {
struct simple_gre_hdr *gre_hdr;
gre_hdr = (struct simple_gre_hdr *)
diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
index f6a2f84..5a30347 100644
--- a/app/test-pmd/rxonly.c
+++ b/app/test-pmd/rxonly.c
@@ -91,7 +91,11 @@ pkt_burst_receive(struct fwd_stream *fs)
uint64_t ol_flags;
uint16_t nb_rx;
uint16_t i, packet_type;
+#ifdef RTE_NEXT_ABI
+ uint16_t is_encapsulation;
+#else
uint64_t is_encapsulation;
+#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t start_tsc;
@@ -135,8 +139,12 @@ pkt_burst_receive(struct fwd_stream *fs)
ol_flags = mb->ol_flags;
packet_type = mb->packet_type;
+#ifdef RTE_NEXT_ABI
+ is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
+#else
is_encapsulation = ol_flags & (PKT_RX_TUNNEL_IPV4_HDR |
PKT_RX_TUNNEL_IPV6_HDR);
+#endif
print_ether_addr(" src=", ð_hdr->s_addr);
print_ether_addr(" - dst=", ð_hdr->d_addr);
@@ -163,6 +171,177 @@ pkt_burst_receive(struct fwd_stream *fs)
if (ol_flags & PKT_RX_QINQ_PKT)
printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x",
mb->vlan_tci, mb->vlan_tci_outer);
+#ifdef RTE_NEXT_ABI
+ if (mb->packet_type) {
+ uint32_t ptype;
+
+ /* (outer) L2 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L2_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L2_MAC:
+ printf(" - (outer) L2 type: MAC");
+ break;
+ case RTE_PTYPE_L2_MAC_TIMESYNC:
+ printf(" - (outer) L2 type: MAC Timesync");
+ break;
+ case RTE_PTYPE_L2_ARP:
+ printf(" - (outer) L2 type: ARP");
+ break;
+ case RTE_PTYPE_L2_LLDP:
+ printf(" - (outer) L2 type: LLDP");
+ break;
+ default:
+ printf(" - (outer) L2 type: Unknown");
+ break;
+ }
+
+ /* (outer) L3 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L3_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L3_IPV4:
+ printf(" - (outer) L3 type: IPV4");
+ break;
+ case RTE_PTYPE_L3_IPV4_EXT:
+ printf(" - (outer) L3 type: IPV4_EXT");
+ break;
+ case RTE_PTYPE_L3_IPV6:
+ printf(" - (outer) L3 type: IPV6");
+ break;
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ printf(" - (outer) L3 type: IPV4_EXT_UNKNOWN");
+ break;
+ case RTE_PTYPE_L3_IPV6_EXT:
+ printf(" - (outer) L3 type: IPV6_EXT");
+ break;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ printf(" - (outer) L3 type: IPV6_EXT_UNKNOWN");
+ break;
+ default:
+ printf(" - (outer) L3 type: Unknown");
+ break;
+ }
+
+ /* (outer) L4 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L4_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L4_TCP:
+ printf(" - (outer) L4 type: TCP");
+ break;
+ case RTE_PTYPE_L4_UDP:
+ printf(" - (outer) L4 type: UDP");
+ break;
+ case RTE_PTYPE_L4_FRAG:
+ printf(" - (outer) L4 type: L4_FRAG");
+ break;
+ case RTE_PTYPE_L4_SCTP:
+ printf(" - (outer) L4 type: SCTP");
+ break;
+ case RTE_PTYPE_L4_ICMP:
+ printf(" - (outer) L4 type: ICMP");
+ break;
+ case RTE_PTYPE_L4_NONFRAG:
+ printf(" - (outer) L4 type: L4_NONFRAG");
+ break;
+ default:
+ printf(" - (outer) L4 type: Unknown");
+ break;
+ }
+
+ /* packet tunnel type */
+ ptype = mb->packet_type & RTE_PTYPE_TUNNEL_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_TUNNEL_IP:
+ printf(" - Tunnel type: IP");
+ break;
+ case RTE_PTYPE_TUNNEL_GRE:
+ printf(" - Tunnel type: GRE");
+ break;
+ case RTE_PTYPE_TUNNEL_VXLAN:
+ printf(" - Tunnel type: VXLAN");
+ break;
+ case RTE_PTYPE_TUNNEL_NVGRE:
+ printf(" - Tunnel type: NVGRE");
+ break;
+ case RTE_PTYPE_TUNNEL_GENEVE:
+ printf(" - Tunnel type: GENEVE");
+ break;
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ printf(" - Tunnel type: GRENAT");
+ break;
+ default:
+ printf(" - Tunnel type: Unkown");
+ break;
+ }
+
+ /* inner L2 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L2_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L2_MAC:
+ printf(" - Inner L2 type: MAC");
+ break;
+ case RTE_PTYPE_INNER_L2_MAC_VLAN:
+ printf(" - Inner L2 type: MAC_VLAN");
+ break;
+ default:
+ printf(" - Inner L2 type: Unknown");
+ break;
+ }
+
+ /* inner L3 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_INNER_L3_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L3_IPV4:
+ printf(" - Inner L3 type: IPV4");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV4_EXT:
+ printf(" - Inner L3 type: IPV4_EXT");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6:
+ printf(" - Inner L3 type: IPV6");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ printf(" - Inner L3 type: IPV4_EXT_UNKNOWN");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT:
+ printf(" - Inner L3 type: IPV6_EXT");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ printf(" - Inner L3 type: IPV6_EXT_UNKOWN");
+ break;
+ default:
+ printf(" - Inner L3 type: Unkown");
+ break;
+ }
+
+ /* inner L4 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L4_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ printf(" - Inner L4 type: TCP");
+ break;
+ case RTE_PTYPE_INNER_L4_UDP:
+ printf(" - Inner L4 type: UDP");
+ break;
+ case RTE_PTYPE_INNER_L4_FRAG:
+ printf(" - Inner L4 type: L4_FRAG");
+ break;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ printf(" - Inner L4 type: SCTP");
+ break;
+ case RTE_PTYPE_INNER_L4_ICMP:
+ printf(" - Inner L4 type: ICMP");
+ break;
+ case RTE_PTYPE_INNER_L4_NONFRAG:
+ printf(" - Inner L4 type: L4_NONFRAG");
+ break;
+ default:
+ printf(" - Inner L4 type: Unknown");
+ break;
+ }
+ printf("\n");
+ } else
+ printf("Unknown packet type\n");
+#endif /* RTE_NEXT_ABI */
if (is_encapsulation) {
struct ipv4_hdr *ipv4_hdr;
struct ipv6_hdr *ipv6_hdr;
@@ -176,7 +355,11 @@ pkt_burst_receive(struct fwd_stream *fs)
l2_len = sizeof(struct ether_hdr);
/* Do not support ipv4 option field */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(packet_type)) {
+#else
if (ol_flags & PKT_RX_TUNNEL_IPV4_HDR) {
+#endif
l3_len = sizeof(struct ipv4_hdr);
ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 12/18] app/test: Remove useless code
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (9 preceding siblings ...)
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 11/18] app/testpmd: " Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 13/18] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
` (6 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
Severl useless code lines are added accidently, which blocks packet
type unification. They should be deleted at all.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
app/test/packet_burst_generator.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
v4 changes:
* Removed several useless code lines which block packet type unification.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c
index b46eed7..61e6340 100644
--- a/app/test/packet_burst_generator.c
+++ b/app/test/packet_burst_generator.c
@@ -272,19 +272,21 @@ nomore_mbuf:
if (ipv4) {
pkt->vlan_tci = ETHER_TYPE_IPv4;
pkt->l3_len = sizeof(struct ipv4_hdr);
-
+#ifndef RTE_NEXT_ABI
if (vlan_enabled)
pkt->ol_flags = PKT_RX_IPV4_HDR | PKT_RX_VLAN_PKT;
else
pkt->ol_flags = PKT_RX_IPV4_HDR;
+#endif
} else {
pkt->vlan_tci = ETHER_TYPE_IPv6;
pkt->l3_len = sizeof(struct ipv6_hdr);
-
+#ifndef RTE_NEXT_ABI
if (vlan_enabled)
pkt->ol_flags = PKT_RX_IPV6_HDR | PKT_RX_VLAN_PKT;
else
pkt->ol_flags = PKT_RX_IPV6_HDR;
+#endif
}
pkts_burst[nb_pkt] = pkt;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 13/18] examples/ip_fragmentation: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (10 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 12/18] app/test: Remove useless code Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 14/18] examples/ip_reassembly: " Helin Zhang
` (5 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/ip_fragmentation/main.c | 9 +++++++++
1 file changed, 9 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 0922ba6..b71d05f 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -283,7 +283,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf,
len = qconf->tx_mbufs[port_out].len;
/* if this is an IPv4 packet */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
struct ipv4_hdr *ip_hdr;
uint32_t ip_dst;
/* Read the lookup key (i.e. ip_dst) from the input packet */
@@ -317,9 +321,14 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf,
if (unlikely (len2 < 0))
return;
}
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+ /* if this is an IPv6 packet */
+#else
}
/* if this is an IPv6 packet */
else if (m->ol_flags & PKT_RX_IPV6_HDR) {
+#endif
struct ipv6_hdr *ip_hdr;
ipv6 = 1;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 14/18] examples/ip_reassembly: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (11 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 13/18] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 15/18] examples/l3fwd-acl: " Helin Zhang
` (4 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/ip_reassembly/main.c | 9 +++++++++
1 file changed, 9 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 9ecb6f9..f1c47ad 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -356,7 +356,11 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue,
dst_port = portid;
/* if packet is IPv4 */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & (PKT_RX_IPV4_HDR)) {
+#endif
struct ipv4_hdr *ip_hdr;
uint32_t ip_dst;
@@ -396,9 +400,14 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue,
}
eth_hdr->ether_type = rte_be_to_cpu_16(ETHER_TYPE_IPv4);
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+ /* if packet is IPv6 */
+#else
}
/* if packet is IPv6 */
else if (m->ol_flags & (PKT_RX_IPV6_HDR | PKT_RX_IPV6_HDR_EXT)) {
+#endif
struct ipv6_extension_fragment *frag_hdr;
struct ipv6_hdr *ip_hdr;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 15/18] examples/l3fwd-acl: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (12 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 14/18] examples/ip_reassembly: " Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 16/18] examples/l3fwd-power: " Helin Zhang
` (3 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd-acl/main.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index a5d4f25..78b6df2 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -645,10 +645,13 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
struct ipv4_hdr *ipv4_hdr;
struct rte_mbuf *pkt = pkts_in[index];
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
int type = pkt->ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_IPV6_HDR);
if (type == PKT_RX_IPV4_HDR) {
-
+#endif
ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(pkt,
unsigned char *) + sizeof(struct ether_hdr));
@@ -667,9 +670,11 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
/* Not a valid IPv4 packet */
rte_pktmbuf_free(pkt);
}
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (type == PKT_RX_IPV6_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv6[acl->num_ipv6] = MBUF_IPV6_2PROTO(pkt);
acl->m_ipv6[(acl->num_ipv6)++] = pkt;
@@ -687,17 +692,22 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
{
struct rte_mbuf *pkt = pkts_in[index];
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
int type = pkt->ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_IPV6_HDR);
if (type == PKT_RX_IPV4_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv4[acl->num_ipv4] = MBUF_IPV4_2PROTO(pkt);
acl->m_ipv4[(acl->num_ipv4)++] = pkt;
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (type == PKT_RX_IPV6_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv6[acl->num_ipv6] = MBUF_IPV6_2PROTO(pkt);
acl->m_ipv6[(acl->num_ipv6)++] = pkt;
@@ -745,10 +755,17 @@ send_one_packet(struct rte_mbuf *m, uint32_t res)
/* in the ACL list, drop it */
#ifdef L3FWDACL_DEBUG
if ((res & ACL_DENY_SIGNATURE) != 0) {
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type))
+ dump_acl4_rule(m, res);
+ else if (RTE_ETH_IS_IPV6_HDR(m->packet_type))
+ dump_acl6_rule(m, res);
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR)
dump_acl4_rule(m, res);
else
dump_acl6_rule(m, res);
+#endif /* RTE_NEXT_ABI */
}
#endif
rte_pktmbuf_free(m);
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 16/18] examples/l3fwd-power: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (13 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 15/18] examples/l3fwd-acl: " Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 17/18] examples/l3fwd: " Helin Zhang
` (2 subsequent siblings)
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd-power/main.c | 8 ++++++++
1 file changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 6057059..705188f 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -635,7 +635,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
/* Handle IPv4 headers.*/
ipv4_hdr =
(struct ipv4_hdr *)(rte_pktmbuf_mtod(m, unsigned char*)
@@ -670,8 +674,12 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
}
else {
+#endif
/* Handle IPv6 headers.*/
#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
struct ipv6_hdr *ipv6_hdr;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 17/18] examples/l3fwd: replace bit mask based packet type with unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (14 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 16/18] examples/l3fwd-power: " Helin Zhang
@ 2015-06-19 8:14 3% ` Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 18/18] mbuf: remove old packet type bit masks Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd/main.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 120 insertions(+), 3 deletions(-)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v3 changes:
* Minor bug fixes and enhancements.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 7e4bbfd..eff9580 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -948,7 +948,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
/* Handle IPv4 headers.*/
ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m, unsigned char *) +
sizeof(struct ether_hdr));
@@ -979,8 +983,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
} else {
+#endif
/* Handle IPv6 headers.*/
struct ipv6_hdr *ipv6_hdr;
@@ -999,8 +1006,13 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
+#ifdef RTE_NEXT_ABI
+ } else
+ /* Free the mbuf that contains non-IPV4/IPV6 packet */
+ rte_pktmbuf_free(m);
+#else
}
-
+#endif
}
#ifdef DO_RFC_1812_CHECKS
@@ -1024,12 +1036,19 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
* to BAD_PORT value.
*/
static inline __attribute__((always_inline)) void
+#ifdef RTE_NEXT_ABI
+rfc1812_process(struct ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t ptype)
+#else
rfc1812_process(struct ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t flags)
+#endif
{
uint8_t ihl;
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(ptype)) {
+#else
if ((flags & PKT_RX_IPV4_HDR) != 0) {
-
+#endif
ihl = ipv4_hdr->version_ihl - IPV4_MIN_VER_IHL;
ipv4_hdr->time_to_live--;
@@ -1059,11 +1078,19 @@ get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
struct ipv6_hdr *ipv6_hdr;
struct ether_hdr *eth_hdr;
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
if (pkt->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
if (rte_lpm_lookup(qconf->ipv4_lookup_struct, dst_ipv4,
&next_hop) != 0)
next_hop = portid;
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (pkt->ol_flags & PKT_RX_IPV6_HDR) {
+#endif
eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
ipv6_hdr = (struct ipv6_hdr *)(eth_hdr + 1);
if (rte_lpm6_lookup(qconf->ipv6_lookup_struct,
@@ -1097,12 +1124,52 @@ process_packet(struct lcore_conf *qconf, struct rte_mbuf *pkt,
ve = val_eth[dp];
dst_port[0] = dp;
+#ifdef RTE_NEXT_ABI
+ rfc1812_process(ipv4_hdr, dst_port, pkt->packet_type);
+#else
rfc1812_process(ipv4_hdr, dst_port, pkt->ol_flags);
+#endif
te = _mm_blend_epi16(te, ve, MASK_ETH);
_mm_store_si128((__m128i *)eth_hdr, te);
}
+#ifdef RTE_NEXT_ABI
+/*
+ * Read packet_type and destination IPV4 addresses from 4 mbufs.
+ */
+static inline void
+processx4_step1(struct rte_mbuf *pkt[FWDSTEP],
+ __m128i *dip,
+ uint32_t *ipv4_flag)
+{
+ struct ipv4_hdr *ipv4_hdr;
+ struct ether_hdr *eth_hdr;
+ uint32_t x0, x1, x2, x3;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[0], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x0 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] = pkt[0]->packet_type & RTE_PTYPE_L3_IPV4;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[1], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x1 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[1]->packet_type;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[2], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x2 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[2]->packet_type;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[3], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x3 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[3]->packet_type;
+
+ dip[0] = _mm_set_epi32(x3, x2, x1, x0);
+}
+#else /* RTE_NEXT_ABI */
/*
* Read ol_flags and destination IPV4 addresses from 4 mbufs.
*/
@@ -1135,14 +1202,24 @@ processx4_step1(struct rte_mbuf *pkt[FWDSTEP], __m128i *dip, uint32_t *flag)
dip[0] = _mm_set_epi32(x3, x2, x1, x0);
}
+#endif /* RTE_NEXT_ABI */
/*
* Lookup into LPM for destination port.
* If lookup fails, use incoming port (portid) as destination port.
*/
static inline void
+#ifdef RTE_NEXT_ABI
+processx4_step2(const struct lcore_conf *qconf,
+ __m128i dip,
+ uint32_t ipv4_flag,
+ uint8_t portid,
+ struct rte_mbuf *pkt[FWDSTEP],
+ uint16_t dprt[FWDSTEP])
+#else
processx4_step2(const struct lcore_conf *qconf, __m128i dip, uint32_t flag,
uint8_t portid, struct rte_mbuf *pkt[FWDSTEP], uint16_t dprt[FWDSTEP])
+#endif /* RTE_NEXT_ABI */
{
rte_xmm_t dst;
const __m128i bswap_mask = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11,
@@ -1152,7 +1229,11 @@ processx4_step2(const struct lcore_conf *qconf, __m128i dip, uint32_t flag,
dip = _mm_shuffle_epi8(dip, bswap_mask);
/* if all 4 packets are IPV4. */
+#ifdef RTE_NEXT_ABI
+ if (likely(ipv4_flag)) {
+#else
if (likely(flag != 0)) {
+#endif
rte_lpm_lookupx4(qconf->ipv4_lookup_struct, dip, dprt, portid);
} else {
dst.x = dip;
@@ -1202,6 +1283,16 @@ processx4_step3(struct rte_mbuf *pkt[FWDSTEP], uint16_t dst_port[FWDSTEP])
_mm_store_si128(p[2], te[2]);
_mm_store_si128(p[3], te[3]);
+#ifdef RTE_NEXT_ABI
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[0] + 1),
+ &dst_port[0], pkt[0]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[1] + 1),
+ &dst_port[1], pkt[1]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[2] + 1),
+ &dst_port[2], pkt[2]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[3] + 1),
+ &dst_port[3], pkt[3]->packet_type);
+#else /* RTE_NEXT_ABI */
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[0] + 1),
&dst_port[0], pkt[0]->ol_flags);
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[1] + 1),
@@ -1210,6 +1301,7 @@ processx4_step3(struct rte_mbuf *pkt[FWDSTEP], uint16_t dst_port[FWDSTEP])
&dst_port[2], pkt[2]->ol_flags);
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[3] + 1),
&dst_port[3], pkt[3]->ol_flags);
+#endif /* RTE_NEXT_ABI */
}
/*
@@ -1396,7 +1488,11 @@ main_loop(__attribute__((unused)) void *dummy)
uint16_t *lp;
uint16_t dst_port[MAX_PKT_BURST];
__m128i dip[MAX_PKT_BURST / FWDSTEP];
+#ifdef RTE_NEXT_ABI
+ uint32_t ipv4_flag[MAX_PKT_BURST / FWDSTEP];
+#else
uint32_t flag[MAX_PKT_BURST / FWDSTEP];
+#endif
uint16_t pnum[MAX_PKT_BURST + 1];
#endif
@@ -1466,6 +1562,18 @@ main_loop(__attribute__((unused)) void *dummy)
*/
int32_t n = RTE_ALIGN_FLOOR(nb_rx, 4);
for (j = 0; j < n ; j+=4) {
+#ifdef RTE_NEXT_ABI
+ uint32_t pkt_type =
+ pkts_burst[j]->packet_type &
+ pkts_burst[j+1]->packet_type &
+ pkts_burst[j+2]->packet_type &
+ pkts_burst[j+3]->packet_type;
+ if (pkt_type & RTE_PTYPE_L3_IPV4) {
+ simple_ipv4_fwd_4pkts(
+ &pkts_burst[j], portid, qconf);
+ } else if (pkt_type &
+ RTE_PTYPE_L3_IPV6) {
+#else /* RTE_NEXT_ABI */
uint32_t ol_flag = pkts_burst[j]->ol_flags
& pkts_burst[j+1]->ol_flags
& pkts_burst[j+2]->ol_flags
@@ -1474,6 +1582,7 @@ main_loop(__attribute__((unused)) void *dummy)
simple_ipv4_fwd_4pkts(&pkts_burst[j],
portid, qconf);
} else if (ol_flag & PKT_RX_IPV6_HDR) {
+#endif /* RTE_NEXT_ABI */
simple_ipv6_fwd_4pkts(&pkts_burst[j],
portid, qconf);
} else {
@@ -1498,13 +1607,21 @@ main_loop(__attribute__((unused)) void *dummy)
for (j = 0; j != k; j += FWDSTEP) {
processx4_step1(&pkts_burst[j],
&dip[j / FWDSTEP],
+#ifdef RTE_NEXT_ABI
+ &ipv4_flag[j / FWDSTEP]);
+#else
&flag[j / FWDSTEP]);
+#endif
}
k = RTE_ALIGN_FLOOR(nb_rx, FWDSTEP);
for (j = 0; j != k; j += FWDSTEP) {
processx4_step2(qconf, dip[j / FWDSTEP],
+#ifdef RTE_NEXT_ABI
+ ipv4_flag[j / FWDSTEP], portid,
+#else
flag[j / FWDSTEP], portid,
+#endif
&pkts_burst[j], &dst_port[j]);
}
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 18/18] mbuf: remove old packet type bit masks
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (15 preceding siblings ...)
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 17/18] examples/l3fwd: " Helin Zhang
@ 2015-06-19 8:14 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
17 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-19 8:14 UTC (permalink / raw)
To: dev
As unified packet types are used instead, those old bit masks and
the relevant macros for packet type indication need to be removed.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
lib/librte_mbuf/rte_mbuf.c | 4 ++++
lib/librte_mbuf/rte_mbuf.h | 4 ++++
2 files changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
* Redefined the bit masks for packet RX offload flags.
v5 changes:
* Rolled back the bit masks of RX flags, for ABI compatibility.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index f506517..4320dd4 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -251,14 +251,18 @@ const char *rte_get_rx_ol_flag_name(uint64_t mask)
/* case PKT_RX_HBUF_OVERFLOW: return "PKT_RX_HBUF_OVERFLOW"; */
/* case PKT_RX_RECIP_ERR: return "PKT_RX_RECIP_ERR"; */
/* case PKT_RX_MAC_ERR: return "PKT_RX_MAC_ERR"; */
+#ifndef RTE_NEXT_ABI
case PKT_RX_IPV4_HDR: return "PKT_RX_IPV4_HDR";
case PKT_RX_IPV4_HDR_EXT: return "PKT_RX_IPV4_HDR_EXT";
case PKT_RX_IPV6_HDR: return "PKT_RX_IPV6_HDR";
case PKT_RX_IPV6_HDR_EXT: return "PKT_RX_IPV6_HDR_EXT";
+#endif /* RTE_NEXT_ABI */
case PKT_RX_IEEE1588_PTP: return "PKT_RX_IEEE1588_PTP";
case PKT_RX_IEEE1588_TMST: return "PKT_RX_IEEE1588_TMST";
+#ifndef RTE_NEXT_ABI
case PKT_RX_TUNNEL_IPV4_HDR: return "PKT_RX_TUNNEL_IPV4_HDR";
case PKT_RX_TUNNEL_IPV6_HDR: return "PKT_RX_TUNNEL_IPV6_HDR";
+#endif /* RTE_NEXT_ABI */
default: return NULL;
}
}
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 5e7cc26..9f32edf 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -91,14 +91,18 @@ 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. */
--
1.9.3
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
@ 2015-06-19 10:26 9% ` Neil Horman
2015-06-19 12:32 9% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-06-19 10:26 UTC (permalink / raw)
To: O'Driscoll, Tim; +Cc: dev
On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
> > -----Original Message-----
> > From: announce [mailto:announce-bounces@dpdk.org] On Behalf Of Thomas
> > Monjalon
> > Sent: Wednesday, June 17, 2015 12:30 AM
> > To: announce@dpdk.org
> > Subject: [dpdk-announce] important design choices - statistics - ABI
> >
> > Hi all,
> >
>
> > During the development of the release 2.0, there was an agreement to
> > keep
> > ABI compatibility or to bring new ABI while keeping old one during one
> > release.
> > In case it's not possible to have this transition, the (exceptional)
> > break
> > should be acknowledged by several developers.
> > http://dpdk.org/doc/guides-2.0/rel_notes/abi.html
> > There were some interesting discussions but not a lot of participants:
> > http://thread.gmane.org/gmane.comp.networking.dpdk.devel/8367/focus
> > =8461
> >
> > During the current development cycle for the release 2.1, the ABI
> > question
> > arises many times in different threads.
> > To add the hash key size field, it is proposed to use a struct padding
> > gap:
> > http://dpdk.org/ml/archives/dev/2015-June/019386.html
> > To support the flow director for VF, there is no proposal yet:
> > http://dpdk.org/ml/archives/dev/2015-June/019343.html
> > To add the speed capability, it is proposed to break ABI in the release
> > 2.2:
> > http://dpdk.org/ml/archives/dev/2015-June/019225.html
> > To support vhost-user multiqueues, it is proposed to break ABI in 2.2:
> > http://dpdk.org/ml/archives/dev/2015-June/019443.html
> > To add the interrupt mode, it is proposed to add a build-time option
> > CONFIG_RTE_EAL_RX_INTR to switch between compatible and ABI breaking
> > binary:
> > http://dpdk.org/ml/archives/dev/2015-June/018947.html
> > To add the packet type, there is a proposal to add a build-time option
> > CONFIG_RTE_NEXT_ABI common to every ABI breaking features:
> > http://dpdk.org/ml/archives/dev/2015-June/019172.html
> > We must also better document how to remove a deprecated ABI:
> > http://dpdk.org/ml/archives/dev/2015-June/019465.html
> > The ABI compatibility is a new constraint and we need to better
> > understand
> > what it means and how to proceed. Even the macros are not yet well
> > documented:
> > http://dpdk.org/ml/archives/dev/2015-June/019357.html
> >
> > Thanks for your attention and your participation in these important
> > choices.
>
> There's been some good discussion on the ABI policy in various responses to this email. I think we now need to reach a conclusion on how we're going to proceed for the 2.1 release. Then, we can have further discussion on the use of versioning or other methods for avoiding the problem in future.
>
> For the 2.1 release, I think we should agree to make patches that change the ABI controllable via a compile-time option. I like Olivier's proposal on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these changes instead of a separate option per patch set (see http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we should rework the affected patch sets to use that approach for 2.1.
>
This is a bad idea. Making ABI dependent on compile time options isn't a
maintainable solution. It breaks the notion of how LIBABIVER is supposed to
work (that is to say you make it impossible to really tell what ABI version you
are building). If you have two compile time options that modify the ABI, you
have to burn through 4 possible LIBABIVER version values to accomodate all
possible combinations, and then you need to remember that when you make them
statically applicable.
Neil
>
> Tim
>
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
@ 2015-06-19 11:08 7% ` Mcnamara, John
0 siblings, 0 replies; 200+ results
From: Mcnamara, John @ 2015-06-19 11:08 UTC (permalink / raw)
To: Richardson, Bruce, Neil Horman, Thomas Monjalon; +Cc: dev
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Richardson, Bruce
> Sent: Wednesday, June 17, 2015 12:07 PM
> To: Neil Horman; Thomas Monjalon
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [dpdk-announce] important design choices -
> statistics - ABI
> Hi Neil,
>
> on my end, some suggestions:
>
> 1. the documentation on changing an API function provided in rte_compat.h
> is really good, but I don't think this is present in our documentation in
> the docs folder or on website is it (apologies if it is and I've missed
> it)? This needs to go into programmers guide or some other doc (perhaps
> the new doc that the coding style went into).
>
> 2. The documentation also needs an example of: this is how you add a new
> function and update the map file, and this is how you a) mark a function
> as deprecated and b) remove it completely. That way we could have one
> guide covering API versioning, how to add, modify and remove functions.
>
> 3. This doc should also cover how to use the API checker tool, something I
> haven't had the chance to look at yet, but should do in the near future!
> :-)
+1 on all three. We need better documentation on how to work with the ABI in DPDK. A new document in doc/guides/guidelines/ would be good.
John
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
2015-06-19 10:26 9% ` Neil Horman
@ 2015-06-19 12:32 9% ` Thomas Monjalon
2015-06-19 13:02 9% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-06-19 12:32 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-19 06:26, Neil Horman:
> On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
> > For the 2.1 release, I think we should agree to make patches that change
> > the ABI controllable via a compile-time option. I like Olivier's proposal
> > on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these
> > changes instead of a separate option per patch set (see
> > http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we
> > should rework the affected patch sets to use that approach for 2.1.
>
> This is a bad idea. Making ABI dependent on compile time options isn't a
> maintainable solution. It breaks the notion of how LIBABIVER is supposed to
> work (that is to say you make it impossible to really tell what ABI version you
> are building).
The idea was to make LIBABIVER increment dependent of CONFIG_RTE_NEXT_ABI.
So one ABI version number refers always to the same ABI.
> If you have two compile time options that modify the ABI, you
> have to burn through 4 possible LIBABIVER version values to accomodate all
> possible combinations, and then you need to remember that when you make them
> statically applicable.
The idea is to have only 1 compile-time option: CONFIG_RTE_NEXT_ABI.
Your intent when introducing ABI policy was to allow smooth porting of
applications from a DPDK version to another. Right?
The adopted solution was to provide backward compatibility during 1 release.
But there are cases where it's not possible. So the policy was to notice
the future change and wait one release cycle to break the ABI (failing
compatibility goals).
The compile-time option may provide an alternative DPDK packaging when the
ABI backward compatibility cannot be provided (case of mbuf changes).
In such case, it's still possible to upgrade DPDK by providing 2 versions of
DPDK libs. So the existing apps continue to link with the previous ABI and
have the possibility of migrating to the new one.
Another advantage of this approach is that we don't have to wait 1 release
to integrate the changes.
The last advantage is to benefit early of these changes with static libraries.
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
2015-06-19 12:32 9% ` Thomas Monjalon
@ 2015-06-19 13:02 9% ` Neil Horman
2015-06-19 13:16 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-06-19 13:02 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Fri, Jun 19, 2015 at 02:32:33PM +0200, Thomas Monjalon wrote:
> 2015-06-19 06:26, Neil Horman:
> > On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
> > > For the 2.1 release, I think we should agree to make patches that change
> > > the ABI controllable via a compile-time option. I like Olivier's proposal
> > > on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these
> > > changes instead of a separate option per patch set (see
> > > http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we
> > > should rework the affected patch sets to use that approach for 2.1.
> >
> > This is a bad idea. Making ABI dependent on compile time options isn't a
> > maintainable solution. It breaks the notion of how LIBABIVER is supposed to
> > work (that is to say you make it impossible to really tell what ABI version you
> > are building).
>
> The idea was to make LIBABIVER increment dependent of CONFIG_RTE_NEXT_ABI.
> So one ABI version number refers always to the same ABI.
>
> > If you have two compile time options that modify the ABI, you
> > have to burn through 4 possible LIBABIVER version values to accomodate all
> > possible combinations, and then you need to remember that when you make them
> > statically applicable.
>
> The idea is to have only 1 compile-time option: CONFIG_RTE_NEXT_ABI.
>
> Your intent when introducing ABI policy was to allow smooth porting of
> applications from a DPDK version to another. Right?
> The adopted solution was to provide backward compatibility during 1 release.
> But there are cases where it's not possible. So the policy was to notice
> the future change and wait one release cycle to break the ABI (failing
> compatibility goals).
> The compile-time option may provide an alternative DPDK packaging when the
> ABI backward compatibility cannot be provided (case of mbuf changes).
> In such case, it's still possible to upgrade DPDK by providing 2 versions of
> DPDK libs. So the existing apps continue to link with the previous ABI and
> have the possibility of migrating to the new one.
> Another advantage of this approach is that we don't have to wait 1 release
> to integrate the changes.
> The last advantage is to benefit early of these changes with static libraries.
>
Hm, ok, thats a bit more reasonable, but it still seems shaky to me.
Implementing an ABI preview option like this implies the notion that, after a
release, you have to remove all the ifdefs that you inserted to create the new
ABI. That seems like an easy task, but it becomes a pain when the ABI delta is
large, and is predicated on the centralization of work effort (that is to say
you need to identify someone to submit the 'remove the NEXT_ABI config ifdefs
from the build' patch every release.
What might be better would be a dpdk-next branch (or even a dpdk-next tree, of
the sort that Thomas Herbert proposed a few weeks ago). Patches that aren't ABI
stable can be put on the next-branch/tree in thier final format. You can
delcare the branch unstable (thereby reserving your right to rebase it). People
can use that to preview the next ABI version (complete with the update LIBABIVER
bump), and when you release dpdk-X, the new ABI for dpdk-X+1 is achieved by
simply merging.
Neil
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
2015-06-19 13:02 9% ` Neil Horman
@ 2015-06-19 13:16 4% ` Thomas Monjalon
2015-06-19 15:27 9% ` Neil Horman
2015-06-19 16:13 9% ` Thomas F Herbert
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2015-06-19 13:16 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-19 09:02, Neil Horman:
> On Fri, Jun 19, 2015 at 02:32:33PM +0200, Thomas Monjalon wrote:
> > 2015-06-19 06:26, Neil Horman:
> > > On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
> > > > For the 2.1 release, I think we should agree to make patches that change
> > > > the ABI controllable via a compile-time option. I like Olivier's proposal
> > > > on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these
> > > > changes instead of a separate option per patch set (see
> > > > http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we
> > > > should rework the affected patch sets to use that approach for 2.1.
> > >
> > > This is a bad idea. Making ABI dependent on compile time options isn't a
> > > maintainable solution. It breaks the notion of how LIBABIVER is supposed to
> > > work (that is to say you make it impossible to really tell what ABI version you
> > > are building).
> >
> > The idea was to make LIBABIVER increment dependent of CONFIG_RTE_NEXT_ABI.
> > So one ABI version number refers always to the same ABI.
> >
> > > If you have two compile time options that modify the ABI, you
> > > have to burn through 4 possible LIBABIVER version values to accomodate all
> > > possible combinations, and then you need to remember that when you make them
> > > statically applicable.
> >
> > The idea is to have only 1 compile-time option: CONFIG_RTE_NEXT_ABI.
> >
> > Your intent when introducing ABI policy was to allow smooth porting of
> > applications from a DPDK version to another. Right?
> > The adopted solution was to provide backward compatibility during 1 release.
> > But there are cases where it's not possible. So the policy was to notice
> > the future change and wait one release cycle to break the ABI (failing
> > compatibility goals).
> > The compile-time option may provide an alternative DPDK packaging when the
> > ABI backward compatibility cannot be provided (case of mbuf changes).
> > In such case, it's still possible to upgrade DPDK by providing 2 versions of
> > DPDK libs. So the existing apps continue to link with the previous ABI and
> > have the possibility of migrating to the new one.
> > Another advantage of this approach is that we don't have to wait 1 release
> > to integrate the changes.
> > The last advantage is to benefit early of these changes with static libraries.
>
> Hm, ok, thats a bit more reasonable, but it still seems shaky to me.
> Implementing an ABI preview option like this implies the notion that, after a
> release, you have to remove all the ifdefs that you inserted to create the new
> ABI. That seems like an easy task, but it becomes a pain when the ABI delta is
> large, and is predicated on the centralization of work effort (that is to say
> you need to identify someone to submit the 'remove the NEXT_ABI config ifdefs
> from the build' patch every release.
It won't be so huge if we reserve the NEXT_ABI solution to changes which cannot
have easy backward compatibility with the compat macros you introduced.
I feel I can do the job of removing the ifdefs NEXT_ABI after each release.
At the same time, the deprecated API, using the compat macros, will be removed.
> What might be better would be a dpdk-next branch (or even a dpdk-next tree, of
> the sort that Thomas Herbert proposed a few weeks ago).
This tree was created after Thomas' request:
http://dpdk.org/browse/next/dpdk-next/
> Patches that aren't ABI stable can be put on the next-branch/tree in thier
> final format. You can delcare the branch unstable (thereby reserving your
> right to rebase it). People can use that to preview the next ABI version
> (complete with the update LIBABIVER bump), and when you release dpdk-X,
> the new ABI for dpdk-X+1 is achieved by simply merging.
Having this tree living would be a nice improvement but it won't provide any
stable (and enough validated) releases to rely on.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
2015-06-19 13:16 4% ` Thomas Monjalon
@ 2015-06-19 15:27 9% ` Neil Horman
2015-06-19 15:51 9% ` Thomas Monjalon
2015-06-19 16:13 9% ` Thomas F Herbert
1 sibling, 1 reply; 200+ results
From: Neil Horman @ 2015-06-19 15:27 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Fri, Jun 19, 2015 at 03:16:53PM +0200, Thomas Monjalon wrote:
> 2015-06-19 09:02, Neil Horman:
> > On Fri, Jun 19, 2015 at 02:32:33PM +0200, Thomas Monjalon wrote:
> > > 2015-06-19 06:26, Neil Horman:
> > > > On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
> > > > > For the 2.1 release, I think we should agree to make patches that change
> > > > > the ABI controllable via a compile-time option. I like Olivier's proposal
> > > > > on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these
> > > > > changes instead of a separate option per patch set (see
> > > > > http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we
> > > > > should rework the affected patch sets to use that approach for 2.1.
> > > >
> > > > This is a bad idea. Making ABI dependent on compile time options isn't a
> > > > maintainable solution. It breaks the notion of how LIBABIVER is supposed to
> > > > work (that is to say you make it impossible to really tell what ABI version you
> > > > are building).
> > >
> > > The idea was to make LIBABIVER increment dependent of CONFIG_RTE_NEXT_ABI.
> > > So one ABI version number refers always to the same ABI.
> > >
> > > > If you have two compile time options that modify the ABI, you
> > > > have to burn through 4 possible LIBABIVER version values to accomodate all
> > > > possible combinations, and then you need to remember that when you make them
> > > > statically applicable.
> > >
> > > The idea is to have only 1 compile-time option: CONFIG_RTE_NEXT_ABI.
> > >
> > > Your intent when introducing ABI policy was to allow smooth porting of
> > > applications from a DPDK version to another. Right?
> > > The adopted solution was to provide backward compatibility during 1 release.
> > > But there are cases where it's not possible. So the policy was to notice
> > > the future change and wait one release cycle to break the ABI (failing
> > > compatibility goals).
> > > The compile-time option may provide an alternative DPDK packaging when the
> > > ABI backward compatibility cannot be provided (case of mbuf changes).
> > > In such case, it's still possible to upgrade DPDK by providing 2 versions of
> > > DPDK libs. So the existing apps continue to link with the previous ABI and
> > > have the possibility of migrating to the new one.
> > > Another advantage of this approach is that we don't have to wait 1 release
> > > to integrate the changes.
> > > The last advantage is to benefit early of these changes with static libraries.
> >
> > Hm, ok, thats a bit more reasonable, but it still seems shaky to me.
> > Implementing an ABI preview option like this implies the notion that, after a
> > release, you have to remove all the ifdefs that you inserted to create the new
> > ABI. That seems like an easy task, but it becomes a pain when the ABI delta is
> > large, and is predicated on the centralization of work effort (that is to say
> > you need to identify someone to submit the 'remove the NEXT_ABI config ifdefs
> > from the build' patch every release.
>
> It won't be so huge if we reserve the NEXT_ABI solution to changes which cannot
> have easy backward compatibility with the compat macros you introduced.
> I feel I can do the job of removing the ifdefs NEXT_ABI after each release.
> At the same time, the deprecated API, using the compat macros, will be removed.
>
I think that is something you can't really predict, as its not an issue of how
stringent we are with its use, but rather a function of how much change
developers want in a given release. That is to say, if you only reserve it for
the most important/urgently needed changes, thats fine, but if you have a
release in which 50 developers want to make urgent and important changes that
breaks ABI, you still have quite a job on your hands to back out the config
changes.
Not to mention the fact that backing those changes out is a manual process.
> > What might be better would be a dpdk-next branch (or even a dpdk-next tree, of
> > the sort that Thomas Herbert proposed a few weeks ago).
>
> This tree was created after Thomas' request:
> http://dpdk.org/browse/next/dpdk-next/
>
Awesome, Though I'm not sure thats entirely the right place either. IIRC that
location was intended to be an early integration site that took unreviewed
patches. I think this really calls for a branch from the mainline tree that
exclusively accepts reviewed ABI changing patches, that can then be merged after
the next release
> > Patches that aren't ABI stable can be put on the next-branch/tree in thier
> > final format. You can delcare the branch unstable (thereby reserving your
> > right to rebase it). People can use that to preview the next ABI version
> > (complete with the update LIBABIVER bump), and when you release dpdk-X,
> > the new ABI for dpdk-X+1 is achieved by simply merging.
>
> Having this tree living would be a nice improvement but it won't provide any
> stable (and enough validated) releases to rely on.
>
I'm not sure I follow you entirely here. If the goal is to find a place to
accept patches that are ABI altering ahead of the main release, why do you need
to provide stable/validated releases? Just base it off the HEAD of the git tree
during the DPDK release X merge window, any testing done in the base branch
should roughly apply, save for functional changes made by the ABI patches you
add in on the branch.
Neil
>
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
2015-06-19 15:27 9% ` Neil Horman
@ 2015-06-19 15:51 9% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-06-19 15:51 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-19 11:27, Neil Horman:
> On Fri, Jun 19, 2015 at 03:16:53PM +0200, Thomas Monjalon wrote:
> > 2015-06-19 09:02, Neil Horman:
> > > On Fri, Jun 19, 2015 at 02:32:33PM +0200, Thomas Monjalon wrote:
> > > > 2015-06-19 06:26, Neil Horman:
> > > > > On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
> > > > > > For the 2.1 release, I think we should agree to make patches that change
> > > > > > the ABI controllable via a compile-time option. I like Olivier's proposal
> > > > > > on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these
> > > > > > changes instead of a separate option per patch set (see
> > > > > > http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we
> > > > > > should rework the affected patch sets to use that approach for 2.1.
> > > > >
> > > > > This is a bad idea. Making ABI dependent on compile time options isn't a
> > > > > maintainable solution. It breaks the notion of how LIBABIVER is supposed to
> > > > > work (that is to say you make it impossible to really tell what ABI version you
> > > > > are building).
> > > >
> > > > The idea was to make LIBABIVER increment dependent of CONFIG_RTE_NEXT_ABI.
> > > > So one ABI version number refers always to the same ABI.
> > > >
> > > > > If you have two compile time options that modify the ABI, you
> > > > > have to burn through 4 possible LIBABIVER version values to accomodate all
> > > > > possible combinations, and then you need to remember that when you make them
> > > > > statically applicable.
> > > >
> > > > The idea is to have only 1 compile-time option: CONFIG_RTE_NEXT_ABI.
> > > >
> > > > Your intent when introducing ABI policy was to allow smooth porting of
> > > > applications from a DPDK version to another. Right?
> > > > The adopted solution was to provide backward compatibility during 1 release.
> > > > But there are cases where it's not possible. So the policy was to notice
> > > > the future change and wait one release cycle to break the ABI (failing
> > > > compatibility goals).
> > > > The compile-time option may provide an alternative DPDK packaging when the
> > > > ABI backward compatibility cannot be provided (case of mbuf changes).
> > > > In such case, it's still possible to upgrade DPDK by providing 2 versions of
> > > > DPDK libs. So the existing apps continue to link with the previous ABI and
> > > > have the possibility of migrating to the new one.
> > > > Another advantage of this approach is that we don't have to wait 1 release
> > > > to integrate the changes.
> > > > The last advantage is to benefit early of these changes with static libraries.
> > >
> > > Hm, ok, thats a bit more reasonable, but it still seems shaky to me.
> > > Implementing an ABI preview option like this implies the notion that, after a
> > > release, you have to remove all the ifdefs that you inserted to create the new
> > > ABI. That seems like an easy task, but it becomes a pain when the ABI delta is
> > > large, and is predicated on the centralization of work effort (that is to say
> > > you need to identify someone to submit the 'remove the NEXT_ABI config ifdefs
> > > from the build' patch every release.
> >
> > It won't be so huge if we reserve the NEXT_ABI solution to changes which cannot
> > have easy backward compatibility with the compat macros you introduced.
> > I feel I can do the job of removing the ifdefs NEXT_ABI after each release.
> > At the same time, the deprecated API, using the compat macros, will be removed.
> >
> I think that is something you can't really predict, as its not an issue of how
> stringent we are with its use, but rather a function of how much change
> developers want in a given release. That is to say, if you only reserve it for
> the most important/urgently needed changes, thats fine, but if you have a
> release in which 50 developers want to make urgent and important changes that
> breaks ABI, you still have quite a job on your hands to back out the config
> changes.
>
> Not to mention the fact that backing those changes out is a manual process.
>
> > > What might be better would be a dpdk-next branch (or even a dpdk-next tree, of
> > > the sort that Thomas Herbert proposed a few weeks ago).
> >
> > This tree was created after Thomas' request:
> > http://dpdk.org/browse/next/dpdk-next/
> >
> Awesome, Though I'm not sure thats entirely the right place either. IIRC that
> location was intended to be an early integration site that took unreviewed
> patches. I think this really calls for a branch from the mainline tree that
> exclusively accepts reviewed ABI changing patches, that can then be merged after
> the next release
>
> > > Patches that aren't ABI stable can be put on the next-branch/tree in thier
> > > final format. You can delcare the branch unstable (thereby reserving your
> > > right to rebase it). People can use that to preview the next ABI version
> > > (complete with the update LIBABIVER bump), and when you release dpdk-X,
> > > the new ABI for dpdk-X+1 is achieved by simply merging.
> >
> > Having this tree living would be a nice improvement but it won't provide any
> > stable (and enough validated) releases to rely on.
> >
> I'm not sure I follow you entirely here. If the goal is to find a place to
> accept patches that are ABI altering ahead of the main release, why do you need
> to provide stable/validated releases? Just base it off the HEAD of the git tree
> during the DPDK release X merge window, any testing done in the base branch
> should roughly apply, save for functional changes made by the ABI patches you
> add in on the branch.
OK, I didn't get you. So you are saying that the changes for the next release
may be prepared in a branch. Yes, it's possible.
But before stating on practical method to execute the policy, we need to agree
on the policy.
This is my proposal:
- The ABI policy must be better explained: what happens to LIBABIVER and .map
when adding a field, adding or removing a function.
- The file doc/guides/rel_notes/abi.rst must contain the ABI notices but the
policy must be moved to doc/guides/guidelines/compat.rst
- The case "backward compatibility broken" must be replaced by the usage of
CONFIG_RTE_NEXT_ABI while describing cases where it can apply.
- The .map files must be generated in order to make it simpler and allows
the use of CONFIG_RTE_NEXT_ABI.
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
2015-06-19 13:16 4% ` Thomas Monjalon
2015-06-19 15:27 9% ` Neil Horman
@ 2015-06-19 16:13 9% ` Thomas F Herbert
2015-06-19 17:02 8% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Thomas F Herbert @ 2015-06-19 16:13 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman; +Cc: dev
On 6/19/15 9:16 AM, Thomas Monjalon wrote:
> 2015-06-19 09:02, Neil Horman:
>> On Fri, Jun 19, 2015 at 02:32:33PM +0200, Thomas Monjalon wrote:
>>> 2015-06-19 06:26, Neil Horman:
>>>> On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
>>>>> For the 2.1 release, I think we should agree to make patches that change
>>>>> the ABI controllable via a compile-time option. I like Olivier's proposal
>>>>> on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these
>>>>> changes instead of a separate option per patch set (see
>>>>> http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we
>>>>> should rework the affected patch sets to use that approach for 2.1.
>>>>
>>>> This is a bad idea. Making ABI dependent on compile time options isn't a
>>>> maintainable solution. It breaks the notion of how LIBABIVER is supposed to
>>>> work (that is to say you make it impossible to really tell what ABI version you
>>>> are building).
>>>
>>> The idea was to make LIBABIVER increment dependent of CONFIG_RTE_NEXT_ABI.
>>> So one ABI version number refers always to the same ABI.
>>>
>>>> If you have two compile time options that modify the ABI, you
>>>> have to burn through 4 possible LIBABIVER version values to accomodate all
>>>> possible combinations, and then you need to remember that when you make them
>>>> statically applicable.
>>>
>>> The idea is to have only 1 compile-time option: CONFIG_RTE_NEXT_ABI.
>>>
>>> Your intent when introducing ABI policy was to allow smooth porting of
>>> applications from a DPDK version to another. Right?
>>> The adopted solution was to provide backward compatibility during 1 release.
>>> But there are cases where it's not possible. So the policy was to notice
>>> the future change and wait one release cycle to break the ABI (failing
>>> compatibility goals).
>>> The compile-time option may provide an alternative DPDK packaging when the
>>> ABI backward compatibility cannot be provided (case of mbuf changes).
>>> In such case, it's still possible to upgrade DPDK by providing 2 versions of
>>> DPDK libs. So the existing apps continue to link with the previous ABI and
>>> have the possibility of migrating to the new one.
>>> Another advantage of this approach is that we don't have to wait 1 release
>>> to integrate the changes.
>>> The last advantage is to benefit early of these changes with static libraries.
>>
>> Hm, ok, thats a bit more reasonable, but it still seems shaky to me.
>> Implementing an ABI preview option like this implies the notion that, after a
>> release, you have to remove all the ifdefs that you inserted to create the new
>> ABI. That seems like an easy task, but it becomes a pain when the ABI delta is
>> large, and is predicated on the centralization of work effort (that is to say
>> you need to identify someone to submit the 'remove the NEXT_ABI config ifdefs
>> from the build' patch every release.
>
> It won't be so huge if we reserve the NEXT_ABI solution to changes which cannot
> have easy backward compatibility with the compat macros you introduced.
> I feel I can do the job of removing the ifdefs NEXT_ABI after each release.
> At the same time, the deprecated API, using the compat macros, will be removed.
>
>> What might be better would be a dpdk-next branch (or even a dpdk-next tree, of
>> the sort that Thomas Herbert proposed a few weeks ago).
>
> This tree was created after Thomas' request:
> http://dpdk.org/browse/next/dpdk-next/
Thomas, I am sorry if I went quiet for awhile but I was on personal
travel with inconsistent access so I almost missed most of this
discussion about ABI changes.
My understanding of the purpose of the dpdk-next tree is to validate
patches by applying and compiling against a "pull" from the main dpdk
tree. I think a good way to handle ABI change while effectively using
the dpdk-next might be to do as follows:
Create a specific branch for the new ABI such as 2.X in the main dpdk
tree. Once that 2.X branch is created, dpdk-next would mirror the 2.X
branch along with master.
Since, dpdk-next would also have the 2.X branch that is in the main dpdk
tree, submitted patches could be applied to either the main branch or
the new-ABI 2.X branch. Providing that patch submitters make it clear
whether a submitted patch is for the new ABI or the old ABI, dpdk-next
could continue to validate the patches for either the main branch or the
new ABI 2.X branch.
>
>> Patches that aren't ABI stable can be put on the next-branch/tree in thier
>> final format. You can delcare the branch unstable (thereby reserving your
>> right to rebase it). People can use that to preview the next ABI version
>> (complete with the update LIBABIVER bump), and when you release dpdk-X,
>> the new ABI for dpdk-X+1 is achieved by simply merging.
>
> Having this tree living would be a nice improvement but it won't provide any
> stable (and enough validated) releases to rely on.
>
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
2015-06-19 16:13 9% ` Thomas F Herbert
@ 2015-06-19 17:02 8% ` Thomas Monjalon
2015-06-19 17:57 9% ` Thomas F Herbert
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-06-19 17:02 UTC (permalink / raw)
To: Thomas F Herbert; +Cc: dev
2015-06-19 12:13, Thomas F Herbert:
>
> On 6/19/15 9:16 AM, Thomas Monjalon wrote:
> > 2015-06-19 09:02, Neil Horman:
> >> On Fri, Jun 19, 2015 at 02:32:33PM +0200, Thomas Monjalon wrote:
> >>> 2015-06-19 06:26, Neil Horman:
> >>>> On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
> >>>>> For the 2.1 release, I think we should agree to make patches that change
> >>>>> the ABI controllable via a compile-time option. I like Olivier's proposal
> >>>>> on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these
> >>>>> changes instead of a separate option per patch set (see
> >>>>> http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we
> >>>>> should rework the affected patch sets to use that approach for 2.1.
> >>>>
> >>>> This is a bad idea. Making ABI dependent on compile time options isn't a
> >>>> maintainable solution. It breaks the notion of how LIBABIVER is supposed to
> >>>> work (that is to say you make it impossible to really tell what ABI version you
> >>>> are building).
> >>>
> >>> The idea was to make LIBABIVER increment dependent of CONFIG_RTE_NEXT_ABI.
> >>> So one ABI version number refers always to the same ABI.
> >>>
> >>>> If you have two compile time options that modify the ABI, you
> >>>> have to burn through 4 possible LIBABIVER version values to accomodate all
> >>>> possible combinations, and then you need to remember that when you make them
> >>>> statically applicable.
> >>>
> >>> The idea is to have only 1 compile-time option: CONFIG_RTE_NEXT_ABI.
> >>>
> >>> Your intent when introducing ABI policy was to allow smooth porting of
> >>> applications from a DPDK version to another. Right?
> >>> The adopted solution was to provide backward compatibility during 1 release.
> >>> But there are cases where it's not possible. So the policy was to notice
> >>> the future change and wait one release cycle to break the ABI (failing
> >>> compatibility goals).
> >>> The compile-time option may provide an alternative DPDK packaging when the
> >>> ABI backward compatibility cannot be provided (case of mbuf changes).
> >>> In such case, it's still possible to upgrade DPDK by providing 2 versions of
> >>> DPDK libs. So the existing apps continue to link with the previous ABI and
> >>> have the possibility of migrating to the new one.
> >>> Another advantage of this approach is that we don't have to wait 1 release
> >>> to integrate the changes.
> >>> The last advantage is to benefit early of these changes with static libraries.
> >>
> >> Hm, ok, thats a bit more reasonable, but it still seems shaky to me.
> >> Implementing an ABI preview option like this implies the notion that, after a
> >> release, you have to remove all the ifdefs that you inserted to create the new
> >> ABI. That seems like an easy task, but it becomes a pain when the ABI delta is
> >> large, and is predicated on the centralization of work effort (that is to say
> >> you need to identify someone to submit the 'remove the NEXT_ABI config ifdefs
> >> from the build' patch every release.
> >
> > It won't be so huge if we reserve the NEXT_ABI solution to changes which cannot
> > have easy backward compatibility with the compat macros you introduced.
> > I feel I can do the job of removing the ifdefs NEXT_ABI after each release.
> > At the same time, the deprecated API, using the compat macros, will be removed.
> >
> >> What might be better would be a dpdk-next branch (or even a dpdk-next tree, of
> >> the sort that Thomas Herbert proposed a few weeks ago).
> >
> > This tree was created after Thomas' request:
> > http://dpdk.org/browse/next/dpdk-next/
>
> Thomas, I am sorry if I went quiet for awhile but I was on personal
> travel with inconsistent access so I almost missed most of this
> discussion about ABI changes.
>
> My understanding of the purpose of the dpdk-next tree is to validate
> patches by applying and compiling against a "pull" from the main dpdk
> tree. I think a good way to handle ABI change while effectively using
> the dpdk-next might be to do as follows:
>
> Create a specific branch for the new ABI such as 2.X in the main dpdk
> tree. Once that 2.X branch is created, dpdk-next would mirror the 2.X
> branch along with master.
>
> Since, dpdk-next would also have the 2.X branch that is in the main dpdk
> tree, submitted patches could be applied to either the main branch or
> the new-ABI 2.X branch. Providing that patch submitters make it clear
> whether a submitted patch is for the new ABI or the old ABI, dpdk-next
> could continue to validate the patches for either the main branch or the
> new ABI 2.X branch.
What is the benefit of a new-ABI branch in the -next tree?
The goal of this discussion is to find a consensus on ABI policy to
smoothly integrate new features without forcing users of shared libraries
to re-build their application when upgrading DPDK, and let them do the
transition before the next upgrade.
^ permalink raw reply [relevance 8%]
* [dpdk-dev] [PATCH v3 2/9] eal: memzone allocated by malloc
2015-06-19 17:21 4% ` [dpdk-dev] [PATCH v3 0/9] Dynamic memzone Sergio Gonzalez Monroy
@ 2015-06-19 17:21 1% ` Sergio Gonzalez Monroy
2015-06-19 17:21 14% ` [dpdk-dev] [PATCH v3 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
1 sibling, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-19 17:21 UTC (permalink / raw)
To: dev
In the current memory hierarchy, memsegs are groups of physically
contiguous hugepages, memzones are slices of memsegs and malloc further
slices memzones into smaller memory chunks.
This patch modifies malloc so it partitions memsegs instead of memzones.
Thus memzones would call malloc internally for memory allocation while
maintaining its ABI.
It would be possible to free memzones and therefore any other structure
based on memzones, ie. mempools
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
lib/librte_eal/common/eal_common_memzone.c | 274 ++++++----------------
lib/librte_eal/common/include/rte_eal_memconfig.h | 2 +-
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/malloc_elem.c | 68 ++++--
lib/librte_eal/common/malloc_elem.h | 14 +-
lib/librte_eal/common/malloc_heap.c | 139 ++++++-----
lib/librte_eal/common/malloc_heap.h | 6 +-
lib/librte_eal/common/rte_malloc.c | 7 +-
8 files changed, 196 insertions(+), 317 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c
index 888f9e5..943012b 100644
--- a/lib/librte_eal/common/eal_common_memzone.c
+++ b/lib/librte_eal/common/eal_common_memzone.c
@@ -50,15 +50,15 @@
#include <rte_string_fns.h>
#include <rte_common.h>
+#include "malloc_heap.h"
+#include "malloc_elem.h"
#include "eal_private.h"
-/* internal copy of free memory segments */
-static struct rte_memseg *free_memseg = NULL;
-
static inline const struct rte_memzone *
memzone_lookup_thread_unsafe(const char *name)
{
const struct rte_mem_config *mcfg;
+ const struct rte_memzone *mz;
unsigned i = 0;
/* get pointer to global configuration */
@@ -68,8 +68,9 @@ memzone_lookup_thread_unsafe(const char *name)
* the algorithm is not optimal (linear), but there are few
* zones and this function should be called at init only
*/
- for (i = 0; i < RTE_MAX_MEMZONE && mcfg->memzone[i].addr != NULL; i++) {
- if (!strncmp(name, mcfg->memzone[i].name, RTE_MEMZONE_NAMESIZE))
+ for (i = 0; i < RTE_MAX_MEMZONE; i++) {
+ mz = &mcfg->memzone[i];
+ if (mz->addr != NULL && !strncmp(name, mz->name, RTE_MEMZONE_NAMESIZE))
return &mcfg->memzone[i];
}
@@ -88,39 +89,45 @@ rte_memzone_reserve(const char *name, size_t len, int socket_id,
len, socket_id, flags, RTE_CACHE_LINE_SIZE);
}
-/*
- * Helper function for memzone_reserve_aligned_thread_unsafe().
- * Calculate address offset from the start of the segment.
- * Align offset in that way that it satisfy istart alignmnet and
- * buffer of the requested length would not cross specified boundary.
- */
-static inline phys_addr_t
-align_phys_boundary(const struct rte_memseg *ms, size_t len, size_t align,
- size_t bound)
+/* Find the heap with the greatest free block size */
+static void
+find_heap_max_free_elem(int *s, size_t *len, unsigned align)
{
- phys_addr_t addr_offset, bmask, end, start;
- size_t step;
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- step = RTE_MAX(align, bound);
- bmask = ~((phys_addr_t)bound - 1);
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate offset to closest alignment */
- start = RTE_ALIGN_CEIL(ms->phys_addr, align);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size > *len) {
+ *len = stats.greatest_free_size;
+ *s = i;
+ }
+ }
+ *len -= (MALLOC_ELEM_OVERHEAD + align);
+}
- while (addr_offset + len < ms->len) {
+/* Find a heap that can allocate the requested size */
+static void
+find_heap_suitable(int *s, size_t len, unsigned align)
+{
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- /* check, do we meet boundary condition */
- end = start + len - (len != 0);
- if ((start & bmask) == (end & bmask))
- break;
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate next offset */
- start = RTE_ALIGN_CEIL(start + 1, step);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size >= len + MALLOC_ELEM_OVERHEAD + align) {
+ *s = i;
+ break;
+ }
}
-
- return (addr_offset);
}
static const struct rte_memzone *
@@ -128,13 +135,7 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
int socket_id, unsigned flags, unsigned align, unsigned bound)
{
struct rte_mem_config *mcfg;
- unsigned i = 0;
- int memseg_idx = -1;
- uint64_t addr_offset, seg_offset = 0;
size_t requested_len;
- size_t memseg_len = 0;
- phys_addr_t memseg_physaddr;
- void *memseg_addr;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
@@ -166,7 +167,6 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
if (align < RTE_CACHE_LINE_SIZE)
align = RTE_CACHE_LINE_SIZE;
-
/* align length on cache boundary. Check for overflow before doing so */
if (len > SIZE_MAX - RTE_CACHE_LINE_MASK) {
rte_errno = EINVAL; /* requested size too big */
@@ -180,129 +180,50 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
requested_len = RTE_MAX((size_t)RTE_CACHE_LINE_SIZE, len);
/* check that boundary condition is valid */
- if (bound != 0 &&
- (requested_len > bound || !rte_is_power_of_2(bound))) {
+ if (bound != 0 && (requested_len > bound || !rte_is_power_of_2(bound))) {
rte_errno = EINVAL;
return NULL;
}
- /* find the smallest segment matching requirements */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- /* last segment */
- if (free_memseg[i].addr == NULL)
- break;
+ if (len == 0) {
+ if (bound != 0)
+ requested_len = bound;
+ else
+ requested_len = 0;
+ }
- /* empty segment, skip it */
- if (free_memseg[i].len == 0)
- continue;
-
- /* bad socket ID */
- if (socket_id != SOCKET_ID_ANY &&
- free_memseg[i].socket_id != SOCKET_ID_ANY &&
- socket_id != free_memseg[i].socket_id)
- continue;
-
- /*
- * calculate offset to closest alignment that
- * meets boundary conditions.
- */
- addr_offset = align_phys_boundary(free_memseg + i,
- requested_len, align, bound);
-
- /* check len */
- if ((requested_len + addr_offset) > free_memseg[i].len)
- continue;
-
- /* check flags for hugepage sizes */
- if ((flags & RTE_MEMZONE_2MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_1G)
- continue;
- if ((flags & RTE_MEMZONE_1GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_2M)
- continue;
- if ((flags & RTE_MEMZONE_16MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16G)
- continue;
- if ((flags & RTE_MEMZONE_16GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16M)
- continue;
-
- /* this segment is the best until now */
- if (memseg_idx == -1) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- /* find the biggest contiguous zone */
- else if (len == 0) {
- if (free_memseg[i].len > memseg_len) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- }
- /*
- * find the smallest (we already checked that current
- * zone length is > len
- */
- else if (free_memseg[i].len + align < memseg_len ||
- (free_memseg[i].len <= memseg_len + align &&
- addr_offset < seg_offset)) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
+ if (socket_id == SOCKET_ID_ANY) {
+ if (requested_len == 0)
+ find_heap_max_free_elem(&socket_id, &requested_len, align);
+ else
+ find_heap_suitable(&socket_id, requested_len, align);
+
+ if (socket_id == SOCKET_ID_ANY) {
+ rte_errno = ENOMEM;
+ return NULL;
}
}
- /* no segment found */
- if (memseg_idx == -1) {
- /*
- * If RTE_MEMZONE_SIZE_HINT_ONLY flag is specified,
- * try allocating again without the size parameter otherwise -fail.
- */
- if ((flags & RTE_MEMZONE_SIZE_HINT_ONLY) &&
- ((flags & RTE_MEMZONE_1GB) || (flags & RTE_MEMZONE_2MB)
- || (flags & RTE_MEMZONE_16MB) || (flags & RTE_MEMZONE_16GB)))
- return memzone_reserve_aligned_thread_unsafe(name,
- len, socket_id, 0, align, bound);
-
+ /* allocate memory on heap */
+ void *mz_addr = malloc_heap_alloc(&mcfg->malloc_heaps[socket_id], NULL,
+ requested_len, flags, align, bound);
+ if (mz_addr == NULL) {
rte_errno = ENOMEM;
return NULL;
}
- /* save aligned physical and virtual addresses */
- memseg_physaddr = free_memseg[memseg_idx].phys_addr + seg_offset;
- memseg_addr = RTE_PTR_ADD(free_memseg[memseg_idx].addr,
- (uintptr_t) seg_offset);
-
- /* if we are looking for a biggest memzone */
- if (len == 0) {
- if (bound == 0)
- requested_len = memseg_len - seg_offset;
- else
- requested_len = RTE_ALIGN_CEIL(memseg_physaddr + 1,
- bound) - memseg_physaddr;
- }
-
- /* set length to correct value */
- len = (size_t)seg_offset + requested_len;
-
- /* update our internal state */
- free_memseg[memseg_idx].len -= len;
- free_memseg[memseg_idx].phys_addr += len;
- free_memseg[memseg_idx].addr =
- (char *)free_memseg[memseg_idx].addr + len;
+ const struct malloc_elem *elem = malloc_elem_from_data(mz_addr);
/* fill the zone in config */
struct rte_memzone *mz = &mcfg->memzone[mcfg->memzone_idx++];
snprintf(mz->name, sizeof(mz->name), "%s", name);
- mz->phys_addr = memseg_physaddr;
- mz->addr = memseg_addr;
- mz->len = requested_len;
- mz->hugepage_sz = free_memseg[memseg_idx].hugepage_sz;
- mz->socket_id = free_memseg[memseg_idx].socket_id;
+ mz->phys_addr = rte_malloc_virt2phy(mz_addr);
+ mz->addr = mz_addr;
+ mz->len = (requested_len == 0 ? elem->size : requested_len);
+ mz->hugepage_sz = elem->ms->hugepage_sz;
+ mz->socket_id = elem->ms->socket_id;
mz->flags = 0;
- mz->memseg_id = memseg_idx;
+ mz->memseg_id = elem->ms - rte_eal_get_configuration()->mem_config->memseg;
return mz;
}
@@ -419,45 +340,6 @@ rte_memzone_dump(FILE *f)
}
/*
- * called by init: modify the free memseg list to have cache-aligned
- * addresses and cache-aligned lengths
- */
-static int
-memseg_sanitize(struct rte_memseg *memseg)
-{
- unsigned phys_align;
- unsigned virt_align;
- unsigned off;
-
- phys_align = memseg->phys_addr & RTE_CACHE_LINE_MASK;
- virt_align = (unsigned long)memseg->addr & RTE_CACHE_LINE_MASK;
-
- /*
- * sanity check: phys_addr and addr must have the same
- * alignment
- */
- if (phys_align != virt_align)
- return -1;
-
- /* memseg is really too small, don't bother with it */
- if (memseg->len < (2 * RTE_CACHE_LINE_SIZE)) {
- memseg->len = 0;
- return 0;
- }
-
- /* align start address */
- off = (RTE_CACHE_LINE_SIZE - phys_align) & RTE_CACHE_LINE_MASK;
- memseg->phys_addr += off;
- memseg->addr = (char *)memseg->addr + off;
- memseg->len -= off;
-
- /* align end address */
- memseg->len &= ~((uint64_t)RTE_CACHE_LINE_MASK);
-
- return 0;
-}
-
-/*
* Init the memzone subsystem
*/
int
@@ -465,14 +347,10 @@ rte_eal_memzone_init(void)
{
struct rte_mem_config *mcfg;
const struct rte_memseg *memseg;
- unsigned i = 0;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
- /* mirror the runtime memsegs from config */
- free_memseg = mcfg->free_memseg;
-
/* secondary processes don't need to initialise anything */
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
return 0;
@@ -485,33 +363,13 @@ rte_eal_memzone_init(void)
rte_rwlock_write_lock(&mcfg->mlock);
- /* fill in uninitialized free_memsegs */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (memseg[i].addr == NULL)
- break;
- if (free_memseg[i].addr != NULL)
- continue;
- memcpy(&free_memseg[i], &memseg[i], sizeof(struct rte_memseg));
- }
-
- /* make all zones cache-aligned */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (free_memseg[i].addr == NULL)
- break;
- if (memseg_sanitize(&free_memseg[i]) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Sanity check failed\n", __func__);
- rte_rwlock_write_unlock(&mcfg->mlock);
- return -1;
- }
- }
-
/* delete all zones */
mcfg->memzone_idx = 0;
memset(mcfg->memzone, 0, sizeof(mcfg->memzone));
rte_rwlock_write_unlock(&mcfg->mlock);
- return 0;
+ return rte_eal_malloc_heap_init();
}
/* Walk all reserved memory zones */
diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h
index 34f5abc..055212a 100644
--- a/lib/librte_eal/common/include/rte_eal_memconfig.h
+++ b/lib/librte_eal/common/include/rte_eal_memconfig.h
@@ -73,7 +73,7 @@ struct rte_mem_config {
struct rte_memseg memseg[RTE_MAX_MEMSEG]; /**< Physmem descriptors. */
struct rte_memzone memzone[RTE_MAX_MEMZONE]; /**< Memzone descriptors. */
- /* Runtime Physmem descriptors. */
+ /* Runtime Physmem descriptors - NOT USED */
struct rte_memseg free_memseg[RTE_MAX_MEMSEG];
struct rte_tailq_head tailq_head[RTE_MAX_TAILQ]; /**< Tailqs for objects */
diff --git a/lib/librte_eal/common/include/rte_malloc_heap.h b/lib/librte_eal/common/include/rte_malloc_heap.h
index 716216f..b270356 100644
--- a/lib/librte_eal/common/include/rte_malloc_heap.h
+++ b/lib/librte_eal/common/include/rte_malloc_heap.h
@@ -40,7 +40,7 @@
#include <rte_memory.h>
/* Number of free lists per heap, grouped by size. */
-#define RTE_HEAP_NUM_FREELISTS 5
+#define RTE_HEAP_NUM_FREELISTS 13
/**
* Structure to hold malloc heap
@@ -48,7 +48,6 @@
struct malloc_heap {
rte_spinlock_t lock;
LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
- unsigned mz_count;
unsigned alloc_count;
size_t total_size;
} __rte_cache_aligned;
diff --git a/lib/librte_eal/common/malloc_elem.c b/lib/librte_eal/common/malloc_elem.c
index a5e1248..b54ee33 100644
--- a/lib/librte_eal/common/malloc_elem.c
+++ b/lib/librte_eal/common/malloc_elem.c
@@ -37,7 +37,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_per_lcore.h>
@@ -56,10 +55,10 @@
*/
void
malloc_elem_init(struct malloc_elem *elem,
- struct malloc_heap *heap, const struct rte_memzone *mz, size_t size)
+ struct malloc_heap *heap, const struct rte_memseg *ms, size_t size)
{
elem->heap = heap;
- elem->mz = mz;
+ elem->ms = ms;
elem->prev = NULL;
memset(&elem->free_list, 0, sizeof(elem->free_list));
elem->state = ELEM_FREE;
@@ -70,12 +69,12 @@ malloc_elem_init(struct malloc_elem *elem,
}
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
{
- malloc_elem_init(elem, prev->heap, prev->mz, 0);
+ malloc_elem_init(elem, prev->heap, prev->ms, 0);
elem->prev = prev;
elem->state = ELEM_BUSY; /* mark busy so its never merged */
}
@@ -86,12 +85,24 @@ malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
* fit, return NULL.
*/
static void *
-elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
+elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- const uintptr_t end_pt = (uintptr_t)elem +
+ const size_t bmask = ~(bound - 1);
+ uintptr_t end_pt = (uintptr_t)elem +
elem->size - MALLOC_ELEM_TRAILER_LEN;
- const uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
- const uintptr_t new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
+ uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ uintptr_t new_elem_start;
+
+ /* check boundary */
+ if ((new_data_start & bmask) != ((end_pt - 1) & bmask)) {
+ end_pt = RTE_ALIGN_FLOOR(end_pt, bound);
+ new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ if (((end_pt - 1) & bmask) != (new_data_start & bmask))
+ return NULL;
+ }
+
+ new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
/* if the new start point is before the exist start, it won't fit */
return (new_elem_start < (uintptr_t)elem) ? NULL : (void *)new_elem_start;
@@ -102,9 +113,10 @@ elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
* alignment request from the current element
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- return elem_start_pt(elem, size, align) != NULL;
+ return elem_start_pt(elem, size, align, bound) != NULL;
}
/*
@@ -115,10 +127,10 @@ static void
split_elem(struct malloc_elem *elem, struct malloc_elem *split_pt)
{
struct malloc_elem *next_elem = RTE_PTR_ADD(elem, elem->size);
- const unsigned old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
- const unsigned new_elem_size = elem->size - old_elem_size;
+ const size_t old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
+ const size_t new_elem_size = elem->size - old_elem_size;
- malloc_elem_init(split_pt, elem->heap, elem->mz, new_elem_size);
+ malloc_elem_init(split_pt, elem->heap, elem->ms, new_elem_size);
split_pt->prev = elem;
next_elem->prev = split_pt;
elem->size = old_elem_size;
@@ -168,8 +180,9 @@ malloc_elem_free_list_index(size_t size)
void
malloc_elem_free_list_insert(struct malloc_elem *elem)
{
- size_t idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
+ size_t idx;
+ idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
elem->state = ELEM_FREE;
LIST_INSERT_HEAD(&elem->heap->free_head[idx], elem, free_list);
}
@@ -190,12 +203,26 @@ elem_free_list_remove(struct malloc_elem *elem)
* is not done here, as it's done there previously.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- struct malloc_elem *new_elem = elem_start_pt(elem, size, align);
- const unsigned old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ struct malloc_elem *new_elem = elem_start_pt(elem, size, align, bound);
+ const size_t old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ const size_t trailer_size = elem->size - old_elem_size - size -
+ MALLOC_ELEM_OVERHEAD;
+
+ elem_free_list_remove(elem);
- if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE){
+ if (trailer_size > MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
+ /* split it, too much free space after elem */
+ struct malloc_elem *new_free_elem =
+ RTE_PTR_ADD(new_elem, size + MALLOC_ELEM_OVERHEAD);
+
+ split_elem(elem, new_free_elem);
+ malloc_elem_free_list_insert(new_free_elem);
+ }
+
+ if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
/* don't split it, pad the element instead */
elem->state = ELEM_BUSY;
elem->pad = old_elem_size;
@@ -208,8 +235,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
new_elem->size = elem->size - elem->pad;
set_header(new_elem);
}
- /* remove element from free list */
- elem_free_list_remove(elem);
return new_elem;
}
@@ -219,7 +244,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
* Re-insert original element, in case its new size makes it
* belong on a different list.
*/
- elem_free_list_remove(elem);
split_elem(elem, new_elem);
new_elem->state = ELEM_BUSY;
malloc_elem_free_list_insert(elem);
diff --git a/lib/librte_eal/common/malloc_elem.h b/lib/librte_eal/common/malloc_elem.h
index 9790b1a..e05d2ea 100644
--- a/lib/librte_eal/common/malloc_elem.h
+++ b/lib/librte_eal/common/malloc_elem.h
@@ -47,9 +47,9 @@ enum elem_state {
struct malloc_elem {
struct malloc_heap *heap;
- struct malloc_elem *volatile prev; /* points to prev elem in memzone */
+ struct malloc_elem *volatile prev; /* points to prev elem in memseg */
LIST_ENTRY(malloc_elem) free_list; /* list of free elements in heap */
- const struct rte_memzone *mz;
+ const struct rte_memseg *ms;
volatile enum elem_state state;
uint32_t pad;
size_t size;
@@ -136,11 +136,11 @@ malloc_elem_from_data(const void *data)
void
malloc_elem_init(struct malloc_elem *elem,
struct malloc_heap *heap,
- const struct rte_memzone *mz,
+ const struct rte_memseg *ms,
size_t size);
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem,
@@ -151,14 +151,16 @@ malloc_elem_mkend(struct malloc_elem *elem,
* of the requested size and with the requested alignment
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* reserve a block of data in an existing malloc_elem. If the malloc_elem
* is much larger than the data block requested, we split the element in two.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_alloc(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* free a malloc_elem block by adding it to the free list. If the
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index defb903..f5fff96 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -39,7 +39,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_launch.h>
@@ -54,123 +53,104 @@
#include "malloc_elem.h"
#include "malloc_heap.h"
-/* since the memzone size starts with a digit, it will appear unquoted in
- * rte_config.h, so quote it so it can be passed to rte_str_to_size */
-#define MALLOC_MEMZONE_SIZE RTE_STR(RTE_MALLOC_MEMZONE_SIZE)
-
-/*
- * returns the configuration setting for the memzone size as a size_t value
- */
-static inline size_t
-get_malloc_memzone_size(void)
+static unsigned
+check_hugepage_sz(unsigned flags, size_t hugepage_sz)
{
- return rte_str_to_size(MALLOC_MEMZONE_SIZE);
+ unsigned ret = 1;
+
+ if ((flags & RTE_MEMZONE_2MB) && hugepage_sz == RTE_PGSIZE_1G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_1GB) && hugepage_sz == RTE_PGSIZE_2M)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16MB) && hugepage_sz == RTE_PGSIZE_16G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16GB) && hugepage_sz == RTE_PGSIZE_16M)
+ ret = 0;
+
+ return ret;
}
/*
- * reserve an extra memory zone and make it available for use by a particular
- * heap. This reserves the zone and sets a dummy malloc_elem header at the end
+ * Expand the heap with a memseg.
+ * This reserves the zone and sets a dummy malloc_elem header at the end
* to prevent overflow. The rest of the zone is added to free list as a single
* large free block
*/
-static int
-malloc_heap_add_memzone(struct malloc_heap *heap, size_t size, unsigned align)
+static void
+malloc_heap_add_memseg(struct malloc_heap *heap, struct rte_memseg *ms)
{
- const unsigned mz_flags = 0;
- const size_t block_size = get_malloc_memzone_size();
- /* ensure the data we want to allocate will fit in the memzone */
- const size_t min_size = size + align + MALLOC_ELEM_OVERHEAD * 2;
- const struct rte_memzone *mz = NULL;
- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- unsigned numa_socket = heap - mcfg->malloc_heaps;
-
- size_t mz_size = min_size;
- if (mz_size < block_size)
- mz_size = block_size;
-
- char mz_name[RTE_MEMZONE_NAMESIZE];
- snprintf(mz_name, sizeof(mz_name), "MALLOC_S%u_HEAP_%u",
- numa_socket, heap->mz_count++);
-
- /* try getting a block. if we fail and we don't need as big a block
- * as given in the config, we can shrink our request and try again
- */
- do {
- mz = rte_memzone_reserve(mz_name, mz_size, numa_socket,
- mz_flags);
- if (mz == NULL)
- mz_size /= 2;
- } while (mz == NULL && mz_size > min_size);
- if (mz == NULL)
- return -1;
-
/* allocate the memory block headers, one at end, one at start */
- struct malloc_elem *start_elem = (struct malloc_elem *)mz->addr;
- struct malloc_elem *end_elem = RTE_PTR_ADD(mz->addr,
- mz_size - MALLOC_ELEM_OVERHEAD);
+ struct malloc_elem *start_elem = (struct malloc_elem *)ms->addr;
+ struct malloc_elem *end_elem = RTE_PTR_ADD(ms->addr,
+ ms->len - MALLOC_ELEM_OVERHEAD);
end_elem = RTE_PTR_ALIGN_FLOOR(end_elem, RTE_CACHE_LINE_SIZE);
+ const size_t elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- const unsigned elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- malloc_elem_init(start_elem, heap, mz, elem_size);
+ malloc_elem_init(start_elem, heap, ms, elem_size);
malloc_elem_mkend(end_elem, start_elem);
malloc_elem_free_list_insert(start_elem);
- /* increase heap total size by size of new memzone */
- heap->total_size+=mz_size - MALLOC_ELEM_OVERHEAD;
- return 0;
+ heap->total_size += elem_size;
}
/*
* Iterates through the freelist for a heap to find a free element
* which can store data of the required size and with the requested alignment.
+ * If size is 0, find the biggest available elem.
* Returns null on failure, or pointer to element on success.
*/
static struct malloc_elem *
-find_suitable_element(struct malloc_heap *heap, size_t size, unsigned align)
+find_suitable_element(struct malloc_heap *heap, size_t size,
+ unsigned flags, size_t align, size_t bound)
{
size_t idx;
- struct malloc_elem *elem;
+ struct malloc_elem *elem, *alt_elem = NULL;
for (idx = malloc_elem_free_list_index(size);
- idx < RTE_HEAP_NUM_FREELISTS; idx++)
- {
+ idx < RTE_HEAP_NUM_FREELISTS; idx++) {
for (elem = LIST_FIRST(&heap->free_head[idx]);
- !!elem; elem = LIST_NEXT(elem, free_list))
- {
- if (malloc_elem_can_hold(elem, size, align))
- return elem;
+ !!elem; elem = LIST_NEXT(elem, free_list)) {
+ if (malloc_elem_can_hold(elem, size, align, bound)) {
+ if (check_hugepage_sz(flags, elem->ms->hugepage_sz))
+ return elem;
+ alt_elem = elem;
+ }
}
}
+
+ if ((alt_elem != NULL) && (flags & RTE_MEMZONE_SIZE_HINT_ONLY))
+ return alt_elem;
+
return NULL;
}
/*
- * Main function called by malloc to allocate a block of memory from the
- * heap. It locks the free list, scans it, and adds a new memzone if the
- * scan fails. Once the new memzone is added, it re-scans and should return
+ * Main function to allocate a block of memory from the heap.
+ * It locks the free list, scans it, and adds a new memseg if the
+ * scan fails. Once the new memseg is added, it re-scans and should return
* the new element after releasing the lock.
*/
void *
malloc_heap_alloc(struct malloc_heap *heap,
- const char *type __attribute__((unused)), size_t size, unsigned align)
+ const char *type __attribute__((unused)), size_t size, unsigned flags,
+ size_t align, size_t bound)
{
+ struct malloc_elem *elem;
+
size = RTE_CACHE_LINE_ROUNDUP(size);
align = RTE_CACHE_LINE_ROUNDUP(align);
+
rte_spinlock_lock(&heap->lock);
- struct malloc_elem *elem = find_suitable_element(heap, size, align);
- if (elem == NULL){
- if ((malloc_heap_add_memzone(heap, size, align)) == 0)
- elem = find_suitable_element(heap, size, align);
- }
- if (elem != NULL){
- elem = malloc_elem_alloc(elem, size, align);
+ elem = find_suitable_element(heap, size, flags, align, bound);
+ if (elem != NULL) {
+ elem = malloc_elem_alloc(elem, size, align, bound);
/* increase heap's count of allocated elements */
heap->alloc_count++;
}
rte_spinlock_unlock(&heap->lock);
- return elem == NULL ? NULL : (void *)(&elem[1]);
+ return elem == NULL ? NULL : (void *)(&elem[1]);
}
/*
@@ -207,3 +187,20 @@ malloc_heap_get_stats(const struct malloc_heap *heap,
return 0;
}
+int
+rte_eal_malloc_heap_init(void)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ unsigned ms_cnt;
+ struct rte_memseg *ms;
+
+ if (mcfg == NULL)
+ return -1;
+
+ for (ms = &mcfg->memseg[0], ms_cnt = 0;
+ (ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0);
+ ms_cnt++, ms++)
+ malloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms);
+
+ return 0;
+}
diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h
index a47136d..3ccbef0 100644
--- a/lib/librte_eal/common/malloc_heap.h
+++ b/lib/librte_eal/common/malloc_heap.h
@@ -53,15 +53,15 @@ malloc_get_numa_socket(void)
}
void *
-malloc_heap_alloc(struct malloc_heap *heap, const char *type,
- size_t size, unsigned align);
+malloc_heap_alloc(struct malloc_heap *heap, const char *type, size_t size,
+ unsigned flags, size_t align, size_t bound);
int
malloc_heap_get_stats(const struct malloc_heap *heap,
struct rte_malloc_socket_stats *socket_stats);
int
-rte_eal_heap_memzone_init(void);
+rte_eal_malloc_heap_init(void);
#ifdef __cplusplus
}
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index c313a57..54c2bd8 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -39,7 +39,6 @@
#include <rte_memcpy.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_branch_prediction.h>
@@ -87,7 +86,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
return NULL;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[socket], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL || socket_arg != SOCKET_ID_ANY)
return ret;
@@ -98,7 +97,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
continue;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[i], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL)
return ret;
}
@@ -256,5 +255,5 @@ rte_malloc_virt2phy(const void *addr)
const struct malloc_elem *elem = malloc_elem_from_data(addr);
if (elem == NULL)
return 0;
- return elem->mz->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->mz->addr);
+ return elem->ms->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->ms->addr);
}
--
1.9.3
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v3 0/9] Dynamic memzone
@ 2015-06-19 17:21 4% ` Sergio Gonzalez Monroy
2015-06-19 17:21 1% ` [dpdk-dev] [PATCH v3 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-06-19 17:21 14% ` [dpdk-dev] [PATCH v3 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
2015-06-25 14:05 4% ` [dpdk-dev] [PATCH v4 0/9] Dynamic memzone Sergio Gonzalez Monroy
` (2 subsequent siblings)
3 siblings, 2 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-19 17:21 UTC (permalink / raw)
To: dev
Current implemetation allows reserving/creating memzones but not the opposite
(unreserve/free). This affects mempools and other memzone based objects.
>From my point of view, implementing free functionality for memzones would look
like malloc over memsegs.
Thus, this approach moves malloc inside eal (which in turn removes a circular
dependency), where malloc heaps are composed of memsegs.
We keep both malloc and memzone APIs as they are, but memzones allocate its
memory by calling malloc_heap_alloc.
Some extra functionality is required in malloc to allow for boundary constrained
memory requests.
In summary, currently malloc is based on memzones, and with this approach
memzones are based on malloc.
v3:
- Create dummy librte_malloc
- Add deprecation notice
- Rework some of the code
- Doc update
- checkpatch
v2:
- New rte_memzone_free
- Support memzone len = 0
- Add all available memsegs to malloc heap at init
- Update memzone/malloc unit tests
Sergio Gonzalez Monroy (9):
eal: move librte_malloc to eal/common
eal: memzone allocated by malloc
app/test: update malloc/memzone unit tests
config: remove CONFIG_RTE_MALLOC_MEMZONE_SIZE
eal: remove free_memseg and references to it
eal: new rte_memzone_free
app/test: update unit test with rte_memzone_free
doc: announce ABI change of librte_malloc
doc: update malloc documentation
MAINTAINERS | 9 +-
app/test/test_malloc.c | 86 -----
app/test/test_memzone.c | 441 +++-------------------
config/common_bsdapp | 8 +-
config/common_linuxapp | 8 +-
doc/guides/prog_guide/env_abstraction_layer.rst | 220 ++++++++++-
doc/guides/prog_guide/img/malloc_heap.png | Bin 81329 -> 80952 bytes
doc/guides/prog_guide/index.rst | 1 -
doc/guides/prog_guide/malloc_lib.rst | 233 ------------
doc/guides/prog_guide/overview.rst | 11 +-
doc/guides/rel_notes/abi.rst | 1 +
drivers/net/af_packet/Makefile | 1 -
drivers/net/bonding/Makefile | 1 -
drivers/net/e1000/Makefile | 2 +-
drivers/net/enic/Makefile | 2 +-
drivers/net/fm10k/Makefile | 2 +-
drivers/net/i40e/Makefile | 2 +-
drivers/net/ixgbe/Makefile | 2 +-
drivers/net/mlx4/Makefile | 1 -
drivers/net/null/Makefile | 1 -
drivers/net/pcap/Makefile | 1 -
drivers/net/virtio/Makefile | 2 +-
drivers/net/vmxnet3/Makefile | 2 +-
drivers/net/xenvirt/Makefile | 2 +-
lib/Makefile | 2 +-
lib/librte_acl/Makefile | 2 +-
lib/librte_eal/bsdapp/eal/Makefile | 4 +-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 19 +
lib/librte_eal/common/Makefile | 1 +
lib/librte_eal/common/eal_common_memzone.c | 329 ++++++----------
lib/librte_eal/common/include/rte_eal_memconfig.h | 5 +-
lib/librte_eal/common/include/rte_malloc.h | 342 +++++++++++++++++
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/include/rte_memzone.h | 11 +
lib/librte_eal/common/malloc_elem.c | 344 +++++++++++++++++
lib/librte_eal/common/malloc_elem.h | 192 ++++++++++
lib/librte_eal/common/malloc_heap.c | 206 ++++++++++
lib/librte_eal/common/malloc_heap.h | 70 ++++
lib/librte_eal/common/rte_malloc.c | 259 +++++++++++++
lib/librte_eal/linuxapp/eal/Makefile | 4 +-
lib/librte_eal/linuxapp/eal/eal_ivshmem.c | 17 +-
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 19 +
lib/librte_hash/Makefile | 2 +-
lib/librte_lpm/Makefile | 2 +-
lib/librte_malloc/Makefile | 6 +-
lib/librte_malloc/malloc_elem.c | 320 ----------------
lib/librte_malloc/malloc_elem.h | 190 ----------
lib/librte_malloc/malloc_heap.c | 209 ----------
lib/librte_malloc/malloc_heap.h | 70 ----
lib/librte_malloc/rte_malloc.c | 228 +----------
lib/librte_malloc/rte_malloc.h | 342 -----------------
lib/librte_malloc/rte_malloc_version.map | 16 -
lib/librte_mempool/Makefile | 2 -
lib/librte_port/Makefile | 1 -
lib/librte_ring/Makefile | 3 +-
lib/librte_table/Makefile | 1 -
56 files changed, 1897 insertions(+), 2363 deletions(-)
delete mode 100644 doc/guides/prog_guide/malloc_lib.rst
create mode 100644 lib/librte_eal/common/include/rte_malloc.h
create mode 100644 lib/librte_eal/common/malloc_elem.c
create mode 100644 lib/librte_eal/common/malloc_elem.h
create mode 100644 lib/librte_eal/common/malloc_heap.c
create mode 100644 lib/librte_eal/common/malloc_heap.h
create mode 100644 lib/librte_eal/common/rte_malloc.c
delete mode 100644 lib/librte_malloc/malloc_elem.c
delete mode 100644 lib/librte_malloc/malloc_elem.h
delete mode 100644 lib/librte_malloc/malloc_heap.c
delete mode 100644 lib/librte_malloc/malloc_heap.h
delete mode 100644 lib/librte_malloc/rte_malloc.h
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3 8/9] doc: announce ABI change of librte_malloc
2015-06-19 17:21 4% ` [dpdk-dev] [PATCH v3 0/9] Dynamic memzone Sergio Gonzalez Monroy
2015-06-19 17:21 1% ` [dpdk-dev] [PATCH v3 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
@ 2015-06-19 17:21 14% ` Sergio Gonzalez Monroy
1 sibling, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-19 17:21 UTC (permalink / raw)
To: dev
Announce the creation of dummy malloc library for 2.1 and removal of
such library, now integrated in librte_eal, for 2.2 release.
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
doc/guides/rel_notes/abi.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..2aaf900 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,4 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* librte_malloc library has been integrated into librte_eal. The 2.1 release creates a dummy/empty malloc library to fulfill binaries with dynamic linking dependencies on librte_malloc.so. Such dummy library will not be created from release 2.2 so binaries will need to be rebuilt.
--
1.9.3
^ permalink raw reply [relevance 14%]
* Re: [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI
2015-06-19 17:02 8% ` Thomas Monjalon
@ 2015-06-19 17:57 9% ` Thomas F Herbert
0 siblings, 0 replies; 200+ results
From: Thomas F Herbert @ 2015-06-19 17:57 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On 6/19/15 1:02 PM, Thomas Monjalon wrote:
> 2015-06-19 12:13, Thomas F Herbert:
>>
>> On 6/19/15 9:16 AM, Thomas Monjalon wrote:
>>> 2015-06-19 09:02, Neil Horman:
>>>> On Fri, Jun 19, 2015 at 02:32:33PM +0200, Thomas Monjalon wrote:
>>>>> 2015-06-19 06:26, Neil Horman:
>>>>>> On Thu, Jun 18, 2015 at 04:55:45PM +0000, O'Driscoll, Tim wrote:
>>>>>>> For the 2.1 release, I think we should agree to make patches that change
>>>>>>> the ABI controllable via a compile-time option. I like Olivier's proposal
>>>>>>> on using a single option (CONFIG_RTE_NEXT_ABI) to control all of these
>>>>>>> changes instead of a separate option per patch set (see
>>>>>>> http://dpdk.org/ml/archives/dev/2015-June/019147.html), so I think we
>>>>>>> should rework the affected patch sets to use that approach for 2.1.
>>>>>>
>>>>>> This is a bad idea. Making ABI dependent on compile time options isn't a
>>>>>> maintainable solution. It breaks the notion of how LIBABIVER is supposed to
>>>>>> work (that is to say you make it impossible to really tell what ABI version you
>>>>>> are building).
>>>>>
>>>>> The idea was to make LIBABIVER increment dependent of CONFIG_RTE_NEXT_ABI.
>>>>> So one ABI version number refers always to the same ABI.
>>>>>
>>>>>> If you have two compile time options that modify the ABI, you
>>>>>> have to burn through 4 possible LIBABIVER version values to accomodate all
>>>>>> possible combinations, and then you need to remember that when you make them
>>>>>> statically applicable.
>>>>>
>>>>> The idea is to have only 1 compile-time option: CONFIG_RTE_NEXT_ABI.
>>>>>
>>>>> Your intent when introducing ABI policy was to allow smooth porting of
>>>>> applications from a DPDK version to another. Right?
>>>>> The adopted solution was to provide backward compatibility during 1 release.
>>>>> But there are cases where it's not possible. So the policy was to notice
>>>>> the future change and wait one release cycle to break the ABI (failing
>>>>> compatibility goals).
>>>>> The compile-time option may provide an alternative DPDK packaging when the
>>>>> ABI backward compatibility cannot be provided (case of mbuf changes).
>>>>> In such case, it's still possible to upgrade DPDK by providing 2 versions of
>>>>> DPDK libs. So the existing apps continue to link with the previous ABI and
>>>>> have the possibility of migrating to the new one.
>>>>> Another advantage of this approach is that we don't have to wait 1 release
>>>>> to integrate the changes.
>>>>> The last advantage is to benefit early of these changes with static libraries.
>>>>
>>>> Hm, ok, thats a bit more reasonable, but it still seems shaky to me.
>>>> Implementing an ABI preview option like this implies the notion that, after a
>>>> release, you have to remove all the ifdefs that you inserted to create the new
>>>> ABI. That seems like an easy task, but it becomes a pain when the ABI delta is
>>>> large, and is predicated on the centralization of work effort (that is to say
>>>> you need to identify someone to submit the 'remove the NEXT_ABI config ifdefs
>>>> from the build' patch every release.
>>>
>>> It won't be so huge if we reserve the NEXT_ABI solution to changes which cannot
>>> have easy backward compatibility with the compat macros you introduced.
>>> I feel I can do the job of removing the ifdefs NEXT_ABI after each release.
>>> At the same time, the deprecated API, using the compat macros, will be removed.
>>>
>>>> What might be better would be a dpdk-next branch (or even a dpdk-next tree, of
>>>> the sort that Thomas Herbert proposed a few weeks ago).
>>>
>>> This tree was created after Thomas' request:
>>> http://dpdk.org/browse/next/dpdk-next/
>>
>> Thomas, I am sorry if I went quiet for awhile but I was on personal
>> travel with inconsistent access so I almost missed most of this
>> discussion about ABI changes.
>>
>> My understanding of the purpose of the dpdk-next tree is to validate
>> patches by applying and compiling against a "pull" from the main dpdk
>> tree. I think a good way to handle ABI change while effectively using
>> the dpdk-next might be to do as follows:
>>
>> Create a specific branch for the new ABI such as 2.X in the main dpdk
>> tree. Once that 2.X branch is created, dpdk-next would mirror the 2.X
>> branch along with master.
>>
>> Since, dpdk-next would also have the 2.X branch that is in the main dpdk
>> tree, submitted patches could be applied to either the main branch or
>> the new-ABI 2.X branch. Providing that patch submitters make it clear
>> whether a submitted patch is for the new ABI or the old ABI, dpdk-next
>> could continue to validate the patches for either the main branch or the
>> new ABI 2.X branch.
>
> What is the benefit of a new-ABI branch in the -next tree?
I don't think that there is any specific benefit to an new-ABI branch in
the dpdk-next tree. I was responding to the suggestion above and perhaps
I missread it. It sounded like what was being proposed was to use the
dpdk-next tree specifically for pre-integration of new-ABI. I don't
think this is of any benefit either.
However if it should be decided to integrate new-ABI patches in a branch
of dpdk rather then in a separate new-ABI tree, then net-next can
"mirror" that branch along with the master branch so patches can be
smoke tested whether they are submitted to the master or to the new-ABI
branch.
>
> The goal of this discussion is to find a consensus on ABI policy to
> smoothly integrate new features without forcing users of shared libraries
> to re-build their application when upgrading DPDK, and let them do the
> transition before the next upgrade.
I understand this and I think it is a good suggestion to have a
mechanism to ease the transition.
>
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] DPDK v2.0.0 has different rte_eal_pci_probe() behavior
[not found] ` <CAO1kT8_C2QJUrNk-fqOQd=WmOkpvNw5jCvxEhfPdHwyCwBuyKA@mail.gmail.com>
@ 2015-06-22 0:32 4% ` Matthew Hall
0 siblings, 0 replies; 200+ results
From: Matthew Hall @ 2015-06-22 0:32 UTC (permalink / raw)
To: <dev@dpdk.org>
On Jun 21, 2015, at 3:54 PM, Tom Barbette <tom.barbette@ulg.ac.be> wrote:
> Application call to rte_eal_pci_probe() is not needed anymore since DPDK 1.8.
>
> http://dpdk.org/ml/archives/dev/2014-September/005890.html
>
> You were not wrong before, it is just a change in DPDK. I came across the same problem a few days ago.
>
> Tom Barbette
So, we have a good practical example below about ABI compatibility.
The prototype and name of the rte_eal_pci_probe() was kept exactly the same, and it compiled fine with no change, but it fails at runtime because it causes a dual-init of all the PCI devices and hits a resource conflict in the process.
Thus it's important to remember you can break compatibility even if the ABI stays the same, if the APIs themselves don't behave the same over time...
Matthew.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] lib: fix RTE_MBUF_METADATA macros
@ 2015-06-22 20:16 0% ` Thomas Monjalon
2015-06-22 20:23 0% ` Cyril Chemparathy
2015-06-22 20:34 0% ` Cyril Chemparathy
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2015-06-22 20:16 UTC (permalink / raw)
To: Mrzyglod, DanielX T; +Cc: dev
2015-06-05 15:31, Dumitrescu, Cristian:
> > Fix RTE_MBUF_METADATA macros to allow for unaligned accesses to
> > meta-data fields.
> > Forcing aligned accesses is not really required, so this is removing an
> > unneeded constraint.
> > This issue was met during testing of the new version of the ip_pipeline
> > application. There is no performance impact.
> > This change has no ABI impact, as the previous code that uses aligned
> > accesses continues to run without any issues.
> >
> > Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
>
> Ack-ed by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Applied, thanks
Cyril, feel free to fix it if it breaks with Tile arch.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] lib: fix RTE_MBUF_METADATA macros
2015-06-22 20:16 0% ` Thomas Monjalon
@ 2015-06-22 20:23 0% ` Cyril Chemparathy
2015-06-22 20:34 0% ` Cyril Chemparathy
1 sibling, 0 replies; 200+ results
From: Cyril Chemparathy @ 2015-06-22 20:23 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Mon, 22 Jun 2015 22:16:59 +0200
Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
> 2015-06-05 15:31, Dumitrescu, Cristian:
> > > Fix RTE_MBUF_METADATA macros to allow for unaligned accesses to
> > > meta-data fields.
> > > Forcing aligned accesses is not really required, so this is
> > > removing an unneeded constraint.
> > > This issue was met during testing of the new version of the
> > > ip_pipeline application. There is no performance impact.
> > > This change has no ABI impact, as the previous code that uses
> > > aligned accesses continues to run without any issues.
> > >
> > > Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
> >
> > Ack-ed by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>
> Applied, thanks
>
> Cyril, feel free to fix it if it breaks with Tile arch.
Why define these locally within rte_port.h? Shouldn't these macros
really be in rte_mbuf.h?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] lib: fix RTE_MBUF_METADATA macros
2015-06-22 20:16 0% ` Thomas Monjalon
2015-06-22 20:23 0% ` Cyril Chemparathy
@ 2015-06-22 20:34 0% ` Cyril Chemparathy
1 sibling, 0 replies; 200+ results
From: Cyril Chemparathy @ 2015-06-22 20:34 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Mon, 22 Jun 2015 22:16:59 +0200
Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
> 2015-06-05 15:31, Dumitrescu, Cristian:
> > > Fix RTE_MBUF_METADATA macros to allow for unaligned accesses to
> > > meta-data fields.
> > > Forcing aligned accesses is not really required, so this is
> > > removing an unneeded constraint.
> > > This issue was met during testing of the new version of the
> > > ip_pipeline application. There is no performance impact.
> > > This change has no ABI impact, as the previous code that uses
> > > aligned accesses continues to run without any issues.
> > >
> > > Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
> >
> > Ack-ed by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>
> Applied, thanks
>
> Cyril, feel free to fix it if it breaks with Tile arch.
Also, in the code, doesn't the following break when mbuf_priv_size != 0?
> #define RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset) \
> (&((uint8_t *) &(mbuf)[1])[offset])
Thanks
-- Cyril.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 08/12] mempool: allow config override on element alignment
@ 2015-06-23 0:31 3% ` Ananyev, Konstantin
2015-06-23 20:43 4% ` Cyril Chemparathy
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2015-06-23 0:31 UTC (permalink / raw)
To: Cyril Chemparathy, dev
Hi Cyril,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Cyril Chemparathy
> Sent: Monday, June 22, 2015 7:59 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2 08/12] mempool: allow config override on element alignment
>
> On TILE-Gx and TILE-Mx platforms, the buffers fed into the hardware
> buffer manager require a 128-byte alignment. With this change, we
> allow configuration based override of the element alignment, and
> default to RTE_CACHE_LINE_SIZE if left unspecified.
>
> Change-Id: I9cd789d92b0bc9c8f44a633de59bb04d45d927a7
> Signed-off-by: Cyril Chemparathy <cchemparathy@ezchip.com>
> ---
> lib/librte_mempool/rte_mempool.c | 16 +++++++++-------
> lib/librte_mempool/rte_mempool.h | 6 ++++++
> 2 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> index 002d3a8..7656b0f 100644
> --- a/lib/librte_mempool/rte_mempool.c
> +++ b/lib/librte_mempool/rte_mempool.c
> @@ -120,10 +120,10 @@ static unsigned optimize_object_size(unsigned obj_size)
> nrank = 1;
>
> /* process new object size */
> - new_obj_size = (obj_size + RTE_CACHE_LINE_MASK) / RTE_CACHE_LINE_SIZE;
> + new_obj_size = (obj_size + RTE_MEMPOOL_ALIGN_MASK) / RTE_MEMPOOL_ALIGN;
> while (get_gcd(new_obj_size, nrank * nchan) != 1)
> new_obj_size++;
> - return new_obj_size * RTE_CACHE_LINE_SIZE;
> + return new_obj_size * RTE_MEMPOOL_ALIGN;
> }
>
> static void
> @@ -267,7 +267,7 @@ rte_mempool_calc_obj_size(uint32_t elt_size, uint32_t flags,
> #endif
> if ((flags & MEMPOOL_F_NO_CACHE_ALIGN) == 0)
> sz->header_size = RTE_ALIGN_CEIL(sz->header_size,
> - RTE_CACHE_LINE_SIZE);
> + RTE_MEMPOOL_ALIGN);
>
> /* trailer contains the cookie in debug mode */
> sz->trailer_size = 0;
> @@ -281,9 +281,9 @@ rte_mempool_calc_obj_size(uint32_t elt_size, uint32_t flags,
> if ((flags & MEMPOOL_F_NO_CACHE_ALIGN) == 0) {
> sz->total_size = sz->header_size + sz->elt_size +
> sz->trailer_size;
> - sz->trailer_size += ((RTE_CACHE_LINE_SIZE -
> - (sz->total_size & RTE_CACHE_LINE_MASK)) &
> - RTE_CACHE_LINE_MASK);
> + sz->trailer_size += ((RTE_MEMPOOL_ALIGN -
> + (sz->total_size & RTE_MEMPOOL_ALIGN_MASK)) &
> + RTE_MEMPOOL_ALIGN_MASK);
> }
>
> /*
> @@ -498,7 +498,7 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> * cache-aligned
> */
> private_data_size = (private_data_size +
> - RTE_CACHE_LINE_MASK) & (~RTE_CACHE_LINE_MASK);
> + RTE_MEMPOOL_ALIGN_MASK) & (~RTE_MEMPOOL_ALIGN_MASK);
>
> if (! rte_eal_has_hugepages()) {
> /*
> @@ -525,6 +525,7 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> * enough to hold mempool header and metadata plus mempool objects.
> */
> mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
> + mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
> if (vaddr == NULL)
> mempool_size += (size_t)objsz.total_size * n;
>
> @@ -580,6 +581,7 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
> /* calculate address of the first element for continuous mempool. */
> obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
> private_data_size;
> + obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
>
> /* populate address translation fields. */
> mp->pg_num = pg_num;
> diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
> index 380d60b..9321b86 100644
> --- a/lib/librte_mempool/rte_mempool.h
> +++ b/lib/librte_mempool/rte_mempool.h
> @@ -142,6 +142,12 @@ struct rte_mempool_objsz {
> /** Mempool over one chunk of physically continuous memory */
> #define MEMPOOL_PG_NUM_DEFAULT 1
>
> +#ifndef RTE_MEMPOOL_ALIGN
> +#define RTE_MEMPOOL_ALIGN RTE_CACHE_LINE_SIZE
> +#endif
> +
> +#define RTE_MEMPOOL_ALIGN_MASK (RTE_MEMPOOL_ALIGN - 1)
I am probably a bit late with my comments, but why not make it a runtime decision then?
I know we can't add a new parameter to mempool_xmem_create() without ABI breakage,
but we can make some global variable for now, that could be setup at init time or something similar.
> +
> /**
> * Mempool object header structure
> *
> --
> 2.1.2
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v8 00/18] unified packet type
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
` (16 preceding siblings ...)
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 18/18] mbuf: remove old packet type bit masks Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 01/18] mbuf: redefine packet_type in rte_mbuf Helin Zhang
` (19 more replies)
17 siblings, 20 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
Currently only 6 bits which are stored in ol_flags are used to indicate the
packet types. This is not enough, as some NIC hardware can recognize quite
a lot of packet types, e.g i40e hardware can recognize more than 150 packet
types. Hiding those packet types hides hardware offload capabilities which
could be quite useful for improving performance and for end users.
So an unified packet types are needed to support all possible PMDs. A 16
bits packet_type in mbuf structure can be changed to 32 bits and used for
this purpose. In addition, all packet types stored in ol_flag field should
be deleted at all, and 6 bits of ol_flags can be save as the benifit.
Initially, 32 bits of packet_type can be divided into several sub fields to
indicate different packet type information of a packet. The initial design
is to divide those bits into fields for L2 types, L3 types, L4 types, tunnel
types, inner L2 types, inner L3 types and inner L4 types. All PMDs should
translate the offloaded packet types into these 7 fields of information, for
user applications.
To avoid breaking ABI compatibility, currently all the code changes for
unified packet type are disabled at compile time by default. Users can enable
it manually by defining the macro of RTE_NEXT_ABI. The code changes will be
valid by default in a future release, and the old version will be deleted
accordingly, after the ABI change process is done.
Note that this patch set should be integrated after another patch set for
'[PATCH v3 0/7] support i40e QinQ stripping and insertion', to clearly solve
the conflict during integration. As both patch sets modified 'struct rte_mbuf',
and the final layout of the 'struct rte_mbuf' is key to vectorized ixgbe PMD.
v2 changes:
* Enlarged the packet_type field from 16 bits to 32 bits.
* Redefined the packet type sub-fields.
* Updated the 'struct rte_kni_mbuf' for KNI according to the mbuf changes.
* Used redefined packet types and enlarged packet_type field for all PMDs
and corresponding applications.
* Removed changes in bond and its relevant application, as there is no need
at all according to the recent bond changes.
v3 changes:
* Put the mbuf layout changes into a single patch.
* Put vector ixgbe changes right after mbuf changes.
* Disabled vector ixgbe PMD by default, as mbuf layout changed, and then
re-enabled it after vector ixgbe PMD updated.
* Put the definitions of unified packet type into a single patch.
* Minor bug fixes and enhancements in l3fwd example.
v4 changes:
* Added detailed description of each packet types.
* Supported unified packet type of fm10k.
* Added printing logs of packet types of each received packet for rxonly
mode in testpmd.
* Removed several useless code lines which block packet type unification from
app/test/packet_burst_generator.c.
v5 changes:
* Added more detailed description for each packet types, together with examples.
* Rolled back the macro definitions of RX packet flags, for ABI compitability.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
* Integrated with patch set for '[PATCH v3 0/7] support i40e QinQ stripping
and insertion', to clearly solve the conflicts during merging.
v8 changes:
* Moved the field of 'vlan_tci_outer' in 'struct rte_mbuf' to the end of the 1st
cache line, to avoid breaking any vectorized PMD storing, as fields of
'packet_type, pkt_len, data_len, vlan_tci, rss' should be in an contiguous 128
bits.
Helin Zhang (18):
mbuf: redefine packet_type in rte_mbuf
ixgbe: support unified packet type in vectorized PMD
mbuf: add definitions of unified packet types
e1000: replace bit mask based packet type with unified packet type
ixgbe: replace bit mask based packet type with unified packet type
i40e: replace bit mask based packet type with unified packet type
enic: replace bit mask based packet type with unified packet type
vmxnet3: replace bit mask based packet type with unified packet type
fm10k: replace bit mask based packet type with unified packet type
app/test-pipeline: replace bit mask based packet type with unified
packet type
app/testpmd: replace bit mask based packet type with unified packet
type
app/test: Remove useless code
examples/ip_fragmentation: replace bit mask based packet type with
unified packet type
examples/ip_reassembly: replace bit mask based packet type with
unified packet type
examples/l3fwd-acl: replace bit mask based packet type with unified
packet type
examples/l3fwd-power: replace bit mask based packet type with unified
packet type
examples/l3fwd: replace bit mask based packet type with unified packet
type
mbuf: remove old packet type bit masks
app/test-pipeline/pipeline_hash.c | 13 +
app/test-pmd/csumonly.c | 14 +
app/test-pmd/rxonly.c | 183 +++++++
app/test/packet_burst_generator.c | 6 +-
drivers/net/e1000/igb_rxtx.c | 102 ++++
drivers/net/enic/enic_main.c | 26 +
drivers/net/fm10k/fm10k_rxtx.c | 27 ++
drivers/net/i40e/i40e_rxtx.c | 528 +++++++++++++++++++++
drivers/net/ixgbe/ixgbe_rxtx.c | 163 +++++++
drivers/net/ixgbe/ixgbe_rxtx_vec.c | 75 ++-
drivers/net/vmxnet3/vmxnet3_rxtx.c | 8 +
examples/ip_fragmentation/main.c | 9 +
examples/ip_reassembly/main.c | 9 +
examples/l3fwd-acl/main.c | 29 +-
examples/l3fwd-power/main.c | 8 +
examples/l3fwd/main.c | 123 ++++-
.../linuxapp/eal/include/exec-env/rte_kni_common.h | 6 +
lib/librte_mbuf/rte_mbuf.c | 4 +
lib/librte_mbuf/rte_mbuf.h | 517 ++++++++++++++++++++
19 files changed, 1837 insertions(+), 13 deletions(-)
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 01/18] mbuf: redefine packet_type in rte_mbuf
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 02/18] ixgbe: support unified packet type in vectorized PMD Helin Zhang
` (18 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
In order to unify the packet type, the field of 'packet_type' in
'struct rte_mbuf' needs to be extended from 16 to 32 bits.
Accordingly, some fields in 'struct rte_mbuf' are re-organized to
support this change for Vector PMD. As 'struct rte_kni_mbuf' for
KNI should be right mapped to 'struct rte_mbuf', it should be
modified accordingly. In addition, Vector PMD of ixgbe is disabled
by default, as 'struct rte_mbuf' changed.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Signed-off-by: Cunming Liang <cunming.liang@intel.com>
---
config/common_linuxapp | 2 +-
.../linuxapp/eal/include/exec-env/rte_kni_common.h | 6 +++++
lib/librte_mbuf/rte_mbuf.h | 26 ++++++++++++++++++++++
3 files changed, 33 insertions(+), 1 deletion(-)
v2 changes:
* Enlarged the packet_type field from 16 bits to 32 bits.
* Redefined the packet type sub-fields.
* Updated the 'struct rte_kni_mbuf' for KNI according to the mbuf changes.
v3 changes:
* Put the mbuf layout changes into a single patch.
* Disabled vector ixgbe PMD by default, as mbuf layout changed.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
* Integrated with changes of QinQ stripping/insertion.
v8 changes:
* Moved the field of 'vlan_tci_outer' in 'struct rte_mbuf' to the end
of the 1st cache line, to avoid breaking any vectorized PMD storing.
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 5deb55a..617d4a1 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -167,7 +167,7 @@ CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_IXGBE_INC_VECTOR=y
+CONFIG_RTE_IXGBE_INC_VECTOR=n
CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
#
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
index 1e55c2d..e9f38bd 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
@@ -117,9 +117,15 @@ struct rte_kni_mbuf {
uint16_t data_off; /**< Start address of data in segment buffer. */
char pad1[4];
uint64_t ol_flags; /**< Offload features. */
+#ifdef RTE_NEXT_ABI
+ char pad2[4];
+ uint32_t pkt_len; /**< Total pkt len: sum of all segment data_len. */
+ uint16_t data_len; /**< Amount of data in segment buffer. */
+#else
char pad2[2];
uint16_t data_len; /**< Amount of data in segment buffer. */
uint32_t pkt_len; /**< Total pkt len: sum of all segment data_len. */
+#endif
/* fields on second cache line */
char pad3[8] __attribute__((__aligned__(RTE_CACHE_LINE_SIZE)));
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index a0f3d3b..0315561 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -275,6 +275,28 @@ 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.
+ */
+ union {
+ uint32_t packet_type; /**< L2/L3/L4 and tunnel information. */
+ struct {
+ uint32_t l2_type:4; /**< (Outer) L2 type. */
+ uint32_t l3_type:4; /**< (Outer) L3 type. */
+ uint32_t l4_type:4; /**< (Outer) L4 type. */
+ uint32_t tun_type:4; /**< Tunnel type. */
+ uint32_t inner_l2_type:4; /**< Inner L2 type. */
+ uint32_t inner_l3_type:4; /**< Inner L3 type. */
+ uint32_t inner_l4_type:4; /**< Inner L4 type. */
+ };
+ };
+
+ 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
@@ -286,6 +308,7 @@ struct rte_mbuf {
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 {
@@ -306,6 +329,9 @@ struct rte_mbuf {
} 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;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 02/18] ixgbe: support unified packet type in vectorized PMD
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 01/18] mbuf: redefine packet_type in rte_mbuf Helin Zhang
@ 2015-06-23 1:50 3% ` Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types Helin Zhang
` (17 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify the packet type, bit masks of packet type for ol_flags are
replaced. In addition, more packet types (UDP, TCP and SCTP) are
supported in vectorized ixgbe PMD.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Note that around 2% performance drop (64B) was observed of doing 4
ports (1 port per 82599 card) IO forwarding on the same SNB core.
Signed-off-by: Cunming Liang <cunming.liang@intel.com>
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
config/common_linuxapp | 2 +-
drivers/net/ixgbe/ixgbe_rxtx_vec.c | 75 +++++++++++++++++++++++++++++++++++++-
2 files changed, 74 insertions(+), 3 deletions(-)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v3 changes:
* Put vector ixgbe changes right after mbuf changes.
* Enabled vector ixgbe PMD by default together with changes for updated
vector PMD.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 617d4a1..5deb55a 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -167,7 +167,7 @@ CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_IXGBE_INC_VECTOR=n
+CONFIG_RTE_IXGBE_INC_VECTOR=y
CONFIG_RTE_IXGBE_RX_OLFLAGS_ENABLE=y
#
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec.c b/drivers/net/ixgbe/ixgbe_rxtx_vec.c
index abd10f6..ccea7cd 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec.c
@@ -134,6 +134,12 @@ ixgbe_rxq_rearm(struct ixgbe_rx_queue *rxq)
*/
#ifdef RTE_IXGBE_RX_OLFLAGS_ENABLE
+#ifdef RTE_NEXT_ABI
+#define OLFLAGS_MASK_V (((uint64_t)PKT_RX_VLAN_PKT << 48) | \
+ ((uint64_t)PKT_RX_VLAN_PKT << 32) | \
+ ((uint64_t)PKT_RX_VLAN_PKT << 16) | \
+ ((uint64_t)PKT_RX_VLAN_PKT))
+#else
#define OLFLAGS_MASK ((uint16_t)(PKT_RX_VLAN_PKT | PKT_RX_IPV4_HDR |\
PKT_RX_IPV4_HDR_EXT | PKT_RX_IPV6_HDR |\
PKT_RX_IPV6_HDR_EXT))
@@ -142,11 +148,26 @@ ixgbe_rxq_rearm(struct ixgbe_rx_queue *rxq)
((uint64_t)OLFLAGS_MASK << 16) | \
((uint64_t)OLFLAGS_MASK))
#define PTYPE_SHIFT (1)
+#endif /* RTE_NEXT_ABI */
+
#define VTAG_SHIFT (3)
static inline void
desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
{
+#ifdef RTE_NEXT_ABI
+ __m128i vtag0, vtag1;
+ union {
+ uint16_t e[4];
+ uint64_t dword;
+ } vol;
+
+ vtag0 = _mm_unpackhi_epi16(descs[0], descs[1]);
+ vtag1 = _mm_unpackhi_epi16(descs[2], descs[3]);
+ vtag1 = _mm_unpacklo_epi32(vtag0, vtag1);
+ vtag1 = _mm_srli_epi16(vtag1, VTAG_SHIFT);
+ vol.dword = _mm_cvtsi128_si64(vtag1) & OLFLAGS_MASK_V;
+#else
__m128i ptype0, ptype1, vtag0, vtag1;
union {
uint16_t e[4];
@@ -166,6 +187,7 @@ desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
ptype1 = _mm_or_si128(ptype1, vtag1);
vol.dword = _mm_cvtsi128_si64(ptype1) & OLFLAGS_MASK_V;
+#endif /* RTE_NEXT_ABI */
rx_pkts[0]->ol_flags = vol.e[0];
rx_pkts[1]->ol_flags = vol.e[1];
@@ -196,6 +218,18 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
int pos;
uint64_t var;
__m128i shuf_msk;
+#ifdef RTE_NEXT_ABI
+ __m128i crc_adjust = _mm_set_epi16(
+ 0, 0, 0, /* ignore non-length fields */
+ -rxq->crc_len, /* sub crc on data_len */
+ 0, /* ignore high-16bits of pkt_len */
+ -rxq->crc_len, /* sub crc on pkt_len */
+ 0, 0 /* ignore pkt_type field */
+ );
+ __m128i dd_check, eop_check;
+ __m128i desc_mask = _mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFF07F0);
+#else
__m128i crc_adjust = _mm_set_epi16(
0, 0, 0, 0, /* ignore non-length fields */
0, /* ignore high-16bits of pkt_len */
@@ -204,6 +238,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
0 /* ignore pkt_type field */
);
__m128i dd_check, eop_check;
+#endif /* RTE_NEXT_ABI */
if (unlikely(nb_pkts < RTE_IXGBE_VPMD_RX_BURST))
return 0;
@@ -232,6 +267,18 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
eop_check = _mm_set_epi64x(0x0000000200000002LL, 0x0000000200000002LL);
/* mask to shuffle from desc. to mbuf */
+#ifdef RTE_NEXT_ABI
+ shuf_msk = _mm_set_epi8(
+ 7, 6, 5, 4, /* octet 4~7, 32bits rss */
+ 15, 14, /* octet 14~15, low 16 bits vlan_macip */
+ 13, 12, /* octet 12~13, 16 bits data_len */
+ 0xFF, 0xFF, /* skip high 16 bits pkt_len, zero out */
+ 13, 12, /* octet 12~13, low 16 bits pkt_len */
+ 0xFF, 0xFF, /* skip high 16 bits pkt_type */
+ 1, /* octet 1, 8 bits pkt_type field */
+ 0 /* octet 0, 4 bits offset 4 pkt_type field */
+ );
+#else
shuf_msk = _mm_set_epi8(
7, 6, 5, 4, /* octet 4~7, 32bits rss */
0xFF, 0xFF, /* skip high 16 bits vlan_macip, zero out */
@@ -241,18 +288,28 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
13, 12, /* octet 12~13, 16 bits data_len */
0xFF, 0xFF /* skip pkt_type field */
);
+#endif /* RTE_NEXT_ABI */
/* Cache is empty -> need to scan the buffer rings, but first move
* the next 'n' mbufs into the cache */
sw_ring = &rxq->sw_ring[rxq->rx_tail];
- /*
- * A. load 4 packet in one loop
+#ifdef RTE_NEXT_ABI
+ /* A. load 4 packet in one loop
+ * [A*. mask out 4 unused dirty field in desc]
* B. copy 4 mbuf point from swring to rx_pkts
* C. calc the number of DD bits among the 4 packets
* [C*. extract the end-of-packet bit, if requested]
* D. fill info. from desc to mbuf
*/
+#else
+ /* A. load 4 packet in one loop
+ * B. copy 4 mbuf point from swring to rx_pkts
+ * C. calc the number of DD bits among the 4 packets
+ * [C*. extract the end-of-packet bit, if requested]
+ * D. fill info. from desc to mbuf
+ */
+#endif /* RTE_NEXT_ABI */
for (pos = 0, nb_pkts_recd = 0; pos < RTE_IXGBE_VPMD_RX_BURST;
pos += RTE_IXGBE_DESCS_PER_LOOP,
rxdp += RTE_IXGBE_DESCS_PER_LOOP) {
@@ -289,6 +346,16 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
/* B.2 copy 2 mbuf point into rx_pkts */
_mm_storeu_si128((__m128i *)&rx_pkts[pos+2], mbp2);
+#ifdef RTE_NEXT_ABI
+ /* A* mask out 0~3 bits RSS type */
+ descs[3] = _mm_and_si128(descs[3], desc_mask);
+ descs[2] = _mm_and_si128(descs[2], desc_mask);
+
+ /* A* mask out 0~3 bits RSS type */
+ descs[1] = _mm_and_si128(descs[1], desc_mask);
+ descs[0] = _mm_and_si128(descs[0], desc_mask);
+#endif /* RTE_NEXT_ABI */
+
/* avoid compiler reorder optimization */
rte_compiler_barrier();
@@ -301,7 +368,11 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
/* C.1 4=>2 filter staterr info only */
sterr_tmp1 = _mm_unpackhi_epi32(descs[1], descs[0]);
+#ifdef RTE_NEXT_ABI
+ /* set ol_flags with vlan packet type */
+#else
/* set ol_flags with packet type and vlan tag */
+#endif /* RTE_NEXT_ABI */
desc_to_olflags_v(descs, &rx_pkts[pos]);
/* D.2 pkt 3,4 set in_port/nb_seg and remove crc */
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 01/18] mbuf: redefine packet_type in rte_mbuf Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 02/18] ixgbe: support unified packet type in vectorized PMD Helin Zhang
@ 2015-06-23 1:50 3% ` Helin Zhang
2015-06-30 8:43 0% ` Olivier MATZ
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 04/18] e1000: replace bit mask based packet type with unified packet type Helin Zhang
` (16 subsequent siblings)
19 siblings, 1 reply; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
As there are only 6 bit flags in ol_flags for indicating packet
types, which is not enough to describe all the possible packet
types hardware can recognize. For example, i40e hardware can
recognize more than 150 packet types. Unified packet type is
composed of L2 type, L3 type, L4 type, tunnel type, inner L2 type,
inner L3 type and inner L4 type fields, and can be stored in
'struct rte_mbuf' of 32 bits field 'packet_type'.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
lib/librte_mbuf/rte_mbuf.h | 487 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 487 insertions(+)
v3 changes:
* Put the definitions of unified packet type into a single patch.
v4 changes:
* Added detailed description of each packet types.
v5 changes:
* Re-worded the commit logs.
* Added more detailed description for all packet types, together with examples.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 0315561..0ee0c55 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -201,6 +201,493 @@ extern "C" {
/* 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.
+ * - Bit 3:0 is for L2 types.
+ * - Bit 7:4 is for L3 or outer L3 (for tunneling case) types.
+ * - Bit 11:8 is for L4 or outer L4 (for tunneling case) types.
+ * - Bit 15:12 is for tunnel types.
+ * - Bit 19:16 is for inner L2 types.
+ * - Bit 23:20 is for inner L3 types.
+ * - Bit 27:24 is for inner L4 types.
+ * - Bit 31:28 is reserved.
+ *
+ * To be compatible with Vector PMD, RTE_PTYPE_L3_IPV4, RTE_PTYPE_L3_IPV4_EXT,
+ * RTE_PTYPE_L3_IPV6, RTE_PTYPE_L3_IPV6_EXT, RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP
+ * and RTE_PTYPE_L4_SCTP should be kept as below in a contiguous 7 bits.
+ *
+ * Note that L3 types values are selected for checking IPV4/IPV6 header from
+ * performance point of view. Reading annotations of RTE_ETH_IS_IPV4_HDR and
+ * RTE_ETH_IS_IPV6_HDR is needed for any future changes of L3 type values.
+ *
+ * Note that the packet types of the same packet recognized by different
+ * hardware may be different, as different hardware may have different
+ * capability of packet type recognition.
+ *
+ * examples:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=0x29
+ * | 'version'=6, 'next header'=0x3A
+ * | 'ICMPv6 header'>
+ * will be recognized on i40e hardware as packet type combination of,
+ * RTE_PTYPE_L2_MAC |
+ * RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ * RTE_PTYPE_TUNNEL_IP |
+ * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_INNER_L4_ICMP.
+ *
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x2F
+ * | 'GRE header'
+ * | 'version'=6, 'next header'=0x11
+ * | 'UDP header'>
+ * will be recognized on i40e hardware as packet type combination of,
+ * RTE_PTYPE_L2_MAC |
+ * RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_TUNNEL_GRENAT |
+ * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_INNER_L4_UDP.
+ */
+#define RTE_PTYPE_UNKNOWN 0x00000000
+/**
+ * MAC (Media Access Control) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=[0x0800|0x86DD|others]>
+ */
+#define RTE_PTYPE_L2_MAC 0x00000001
+/**
+ * MAC (Media Access Control) packet type for time sync.
+ *
+ * Packet format:
+ * <'ether type'=0x88F7>
+ */
+#define RTE_PTYPE_L2_MAC_TIMESYNC 0x00000002
+/**
+ * ARP (Address Resolution Protocol) packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0806>
+ */
+#define RTE_PTYPE_L2_ARP 0x00000003
+/**
+ * LLDP (Link Layer Discovery Protocol) packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x88CC>
+ */
+#define RTE_PTYPE_L2_LLDP 0x00000004
+/**
+ * Mask of layer 2 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L2_MASK 0x0000000f
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and does not contain any
+ * header option.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=5>
+ */
+#define RTE_PTYPE_L3_IPV4 0x00000010
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and contains header
+ * options.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[6-15], 'options'>
+ */
+#define RTE_PTYPE_L3_IPV4_EXT 0x00000030
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and does not contain any
+ * extension header.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x3B>
+ */
+#define RTE_PTYPE_L3_IPV6 0x00000040
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and may or maynot contain
+ * header options.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[5-15], <'options'>>
+ */
+#define RTE_PTYPE_L3_IPV4_EXT_UNKNOWN 0x00000090
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and contains extension
+ * headers.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * 'extension headers'>
+ */
+#define RTE_PTYPE_L3_IPV6_EXT 0x000000c0
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and may or maynot contain
+ * extension headers.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * <'extension headers'>>
+ */
+#define RTE_PTYPE_L3_IPV6_EXT_UNKNOWN 0x000000e0
+/**
+ * Mask of layer 3 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L3_MASK 0x000000f0
+/**
+ * TCP (Transmission Control Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=6, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=6>
+ */
+#define RTE_PTYPE_L4_TCP 0x00000100
+/**
+ * UDP (User Datagram Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17>
+ */
+#define RTE_PTYPE_L4_UDP 0x00000200
+/**
+ * Fragmented IP (Internet Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * It refers to those packets of any IP types, which can be recognized as
+ * fragmented. A fragmented packet cannot be recognized as any other L4 types
+ * (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP,
+ * RTE_PTYPE_L4_NONFRAG).
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'MF'=1>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=44>
+ */
+#define RTE_PTYPE_L4_FRAG 0x00000300
+/**
+ * SCTP (Stream Control Transmission Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=132, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=132>
+ */
+#define RTE_PTYPE_L4_SCTP 0x00000400
+/**
+ * ICMP (Internet Control Message Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=1, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=1>
+ */
+#define RTE_PTYPE_L4_ICMP 0x00000500
+/**
+ * Non-fragmented IP (Internet Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * It refers to those packets of any IP types, while cannot be recognized as
+ * any of above L4 types (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP,
+ * RTE_PTYPE_L4_FRAG, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP).
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'!=[6|17|44|132|1]>
+ */
+#define RTE_PTYPE_L4_NONFRAG 0x00000600
+/**
+ * Mask of layer 4 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L4_MASK 0x00000f00
+/**
+ * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=[4|41]>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[4|41]>
+ */
+#define RTE_PTYPE_TUNNEL_IP 0x00001000
+/**
+ * GRE (Generic Routing Encapsulation) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=47>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=47>
+ */
+#define RTE_PTYPE_TUNNEL_GRE 0x00002000
+/**
+ * VXLAN (Virtual eXtensible Local Area Network) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17
+ * | 'destination port'=4798>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17
+ * | 'destination port'=4798>
+ */
+#define RTE_PTYPE_TUNNEL_VXLAN 0x00003000
+/**
+ * NVGRE (Network Virtualization using Generic Routing Encapsulation) tunneling
+ * packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=47
+ * | 'protocol type'=0x6558>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=47
+ * | 'protocol type'=0x6558'>
+ */
+#define RTE_PTYPE_TUNNEL_NVGRE 0x00004000
+/**
+ * GENEVE (Generic Network Virtualization Encapsulation) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17
+ * | 'destination port'=6081>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17
+ * | 'destination port'=6081>
+ */
+#define RTE_PTYPE_TUNNEL_GENEVE 0x00005000
+/**
+ * Tunneling packet type of Teredo, VXLAN (Virtual eXtensible Local Area
+ * Network) or GRE (Generic Routing Encapsulation) could be recognized as this
+ * packet type, if they can not be recognized independently as of hardware
+ * capability.
+ */
+#define RTE_PTYPE_TUNNEL_GRENAT 0x00006000
+/**
+ * Mask of tunneling packet types.
+ */
+#define RTE_PTYPE_TUNNEL_MASK 0x0000f000
+/**
+ * MAC (Media Access Control) packet type.
+ * It is used for inner packet type only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=[0x800|0x86DD]>
+ */
+#define RTE_PTYPE_INNER_L2_MAC 0x00010000
+/**
+ * MAC (Media Access Control) packet type with VLAN (Virtual Local Area
+ * Network) tag.
+ *
+ * Packet format (inner only):
+ * <'ether type'=[0x800|0x86DD], vlan=[1-4095]>
+ */
+#define RTE_PTYPE_INNER_L2_MAC_VLAN 0x00020000
+/**
+ * Mask of inner layer 2 packet types.
+ */
+#define RTE_PTYPE_INNER_L2_MASK 0x000f0000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and does not contain any header option.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=5>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4 0x00100000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and contains header options.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[6-15], 'options'>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4_EXT 0x00200000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and does not contain any extension header.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x3B>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6 0x00300000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and may or maynot contain header options.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[5-15], <'options'>>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN 0x00400000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and contains extension headers.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * 'extension headers'>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6_EXT 0x00500000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and may or maynot contain extension
+ * headers.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * <'extension headers'>>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN 0x00600000
+/**
+ * Mask of inner layer 3 packet types.
+ */
+#define RTE_PTYPE_INNER_INNER_L3_MASK 0x00f00000
+/**
+ * TCP (Transmission Control Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=6, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=6>
+ */
+#define RTE_PTYPE_INNER_L4_TCP 0x01000000
+/**
+ * UDP (User Datagram Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17>
+ */
+#define RTE_PTYPE_INNER_L4_UDP 0x02000000
+/**
+ * Fragmented IP (Internet Protocol) packet type.
+ * It is used for inner packet only, and may or maynot have layer 4 packet.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'MF'=1>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=44>
+ */
+#define RTE_PTYPE_INNER_L4_FRAG 0x03000000
+/**
+ * SCTP (Stream Control Transmission Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=132, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=132>
+ */
+#define RTE_PTYPE_INNER_L4_SCTP 0x04000000
+/**
+ * ICMP (Internet Control Message Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=1, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=1>
+ */
+#define RTE_PTYPE_INNER_L4_ICMP 0x05000000
+/**
+ * Non-fragmented IP (Internet Protocol) packet type.
+ * It is used for inner packet only, and may or maynot have other unknown layer
+ * 4 packet types.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'!=[6|17|44|132|1]>
+ */
+#define RTE_PTYPE_INNER_L4_NONFRAG 0x06000000
+/**
+ * Mask of inner layer 4 packet types.
+ */
+#define RTE_PTYPE_INNER_L4_MASK 0x0f000000
+
+/**
+ * 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.
+ */
+#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.
+ */
+#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 */
+
/**
* Get the name of a RX offload flag
*
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v8 04/18] e1000: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (2 preceding siblings ...)
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 05/18] ixgbe: " Helin Zhang
` (15 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/e1000/igb_rxtx.c | 102 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index 43d6703..d1c2ef8 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -590,6 +590,99 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
* RX functions
*
**********************************************************************/
+#ifdef RTE_NEXT_ABI
+#define IGB_PACKET_TYPE_IPV4 0X01
+#define IGB_PACKET_TYPE_IPV4_TCP 0X11
+#define IGB_PACKET_TYPE_IPV4_UDP 0X21
+#define IGB_PACKET_TYPE_IPV4_SCTP 0X41
+#define IGB_PACKET_TYPE_IPV4_EXT 0X03
+#define IGB_PACKET_TYPE_IPV4_EXT_SCTP 0X43
+#define IGB_PACKET_TYPE_IPV6 0X04
+#define IGB_PACKET_TYPE_IPV6_TCP 0X14
+#define IGB_PACKET_TYPE_IPV6_UDP 0X24
+#define IGB_PACKET_TYPE_IPV6_EXT 0X0C
+#define IGB_PACKET_TYPE_IPV6_EXT_TCP 0X1C
+#define IGB_PACKET_TYPE_IPV6_EXT_UDP 0X2C
+#define IGB_PACKET_TYPE_IPV4_IPV6 0X05
+#define IGB_PACKET_TYPE_IPV4_IPV6_TCP 0X15
+#define IGB_PACKET_TYPE_IPV4_IPV6_UDP 0X25
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT 0X0D
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT_TCP 0X1D
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT_UDP 0X2D
+#define IGB_PACKET_TYPE_MAX 0X80
+#define IGB_PACKET_TYPE_MASK 0X7F
+#define IGB_PACKET_TYPE_SHIFT 0X04
+static inline uint32_t
+igb_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
+{
+ static const uint32_t
+ ptype_table[IGB_PACKET_TYPE_MAX] __rte_cache_aligned = {
+ [IGB_PACKET_TYPE_IPV4] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4,
+ [IGB_PACKET_TYPE_IPV4_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [IGB_PACKET_TYPE_IPV6] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6,
+ [IGB_PACKET_TYPE_IPV4_IPV6] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6,
+ [IGB_PACKET_TYPE_IPV6_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT,
+ [IGB_PACKET_TYPE_IPV4_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV6_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_TCP,
+ [IGB_PACKET_TYPE_IPV6_EXT_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV6_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_UDP,
+ [IGB_PACKET_TYPE_IPV6_EXT_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_SCTP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP,
+ [IGB_PACKET_TYPE_IPV4_EXT_SCTP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_SCTP,
+ };
+ if (unlikely(pkt_info & E1000_RXDADV_PKTTYPE_ETQF))
+ return RTE_PTYPE_UNKNOWN;
+
+ pkt_info = (pkt_info >> IGB_PACKET_TYPE_SHIFT) & IGB_PACKET_TYPE_MASK;
+
+ return ptype_table[pkt_info];
+}
+
+static inline uint64_t
+rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
+{
+ uint64_t pkt_flags = ((hl_tp_rs & 0x0F) == 0) ? 0 : PKT_RX_RSS_HASH;
+
+#if defined(RTE_LIBRTE_IEEE1588)
+ static uint32_t ip_pkt_etqf_map[8] = {
+ 0, 0, 0, PKT_RX_IEEE1588_PTP,
+ 0, 0, 0, 0,
+ };
+
+ pkt_flags |= ip_pkt_etqf_map[(hl_tp_rs >> 4) & 0x07];
+#endif
+
+ return pkt_flags;
+}
+#else /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
{
@@ -617,6 +710,7 @@ rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
#endif
return pkt_flags | (((hl_tp_rs & 0x0F) == 0) ? 0 : PKT_RX_RSS_HASH);
}
+#endif /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_status_to_pkt_flags(uint32_t rx_status)
@@ -790,6 +884,10 @@ eth_igb_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
rxm->ol_flags = pkt_flags;
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = igb_rxd_pkt_info_to_pkt_type(rxd.wb.lower.
+ lo_dword.hs_rss.pkt_info);
+#endif
/*
* Store the mbuf address into the next entry of the array
@@ -1024,6 +1122,10 @@ eth_igb_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
first_seg->ol_flags = pkt_flags;
+#ifdef RTE_NEXT_ABI
+ first_seg->packet_type = igb_rxd_pkt_info_to_pkt_type(rxd.wb.
+ lower.lo_dword.hs_rss.pkt_info);
+#endif
/* Prefetch data of first segment, if configured to do so. */
rte_packet_prefetch((char *)first_seg->buf_addr +
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 05/18] ixgbe: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (3 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 04/18] e1000: replace bit mask based packet type with unified packet type Helin Zhang
@ 2015-06-23 1:50 3% ` Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 06/18] i40e: " Helin Zhang
` (14 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet type among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Note that around 2.5% performance drop (64B) was observed of doing
4 ports (1 port per 82599 card) IO forwarding on the same SNB core.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/ixgbe/ixgbe_rxtx.c | 163 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 163 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index a211096..83a869f 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -860,6 +860,110 @@ end_of_tx:
* RX functions
*
**********************************************************************/
+#ifdef RTE_NEXT_ABI
+#define IXGBE_PACKET_TYPE_IPV4 0X01
+#define IXGBE_PACKET_TYPE_IPV4_TCP 0X11
+#define IXGBE_PACKET_TYPE_IPV4_UDP 0X21
+#define IXGBE_PACKET_TYPE_IPV4_SCTP 0X41
+#define IXGBE_PACKET_TYPE_IPV4_EXT 0X03
+#define IXGBE_PACKET_TYPE_IPV4_EXT_SCTP 0X43
+#define IXGBE_PACKET_TYPE_IPV6 0X04
+#define IXGBE_PACKET_TYPE_IPV6_TCP 0X14
+#define IXGBE_PACKET_TYPE_IPV6_UDP 0X24
+#define IXGBE_PACKET_TYPE_IPV6_EXT 0X0C
+#define IXGBE_PACKET_TYPE_IPV6_EXT_TCP 0X1C
+#define IXGBE_PACKET_TYPE_IPV6_EXT_UDP 0X2C
+#define IXGBE_PACKET_TYPE_IPV4_IPV6 0X05
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_TCP 0X15
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_UDP 0X25
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT 0X0D
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_TCP 0X1D
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_UDP 0X2D
+#define IXGBE_PACKET_TYPE_MAX 0X80
+#define IXGBE_PACKET_TYPE_MASK 0X7F
+#define IXGBE_PACKET_TYPE_SHIFT 0X04
+static inline uint32_t
+ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
+{
+ static const uint32_t
+ ptype_table[IXGBE_PACKET_TYPE_MAX] __rte_cache_aligned = {
+ [IXGBE_PACKET_TYPE_IPV4] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4,
+ [IXGBE_PACKET_TYPE_IPV4_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [IXGBE_PACKET_TYPE_IPV6] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6,
+ [IXGBE_PACKET_TYPE_IPV6_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT,
+ [IXGBE_PACKET_TYPE_IPV4_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV6_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV6_EXT_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV6_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV6_EXT_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_SCTP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP,
+ [IXGBE_PACKET_TYPE_IPV4_EXT_SCTP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_SCTP,
+ };
+ if (unlikely(pkt_info & IXGBE_RXDADV_PKTTYPE_ETQF))
+ return RTE_PTYPE_UNKNOWN;
+
+ pkt_info = (pkt_info >> IXGBE_PACKET_TYPE_SHIFT) &
+ IXGBE_PACKET_TYPE_MASK;
+
+ return ptype_table[pkt_info];
+}
+
+static inline uint64_t
+ixgbe_rxd_pkt_info_to_pkt_flags(uint16_t pkt_info)
+{
+ static uint64_t ip_rss_types_map[16] __rte_cache_aligned = {
+ 0, PKT_RX_RSS_HASH, PKT_RX_RSS_HASH, PKT_RX_RSS_HASH,
+ 0, PKT_RX_RSS_HASH, 0, PKT_RX_RSS_HASH,
+ PKT_RX_RSS_HASH, 0, 0, 0,
+ 0, 0, 0, PKT_RX_FDIR,
+ };
+#ifdef RTE_LIBRTE_IEEE1588
+ static uint64_t ip_pkt_etqf_map[8] = {
+ 0, 0, 0, PKT_RX_IEEE1588_PTP,
+ 0, 0, 0, 0,
+ };
+
+ if (likely(pkt_info & IXGBE_RXDADV_PKTTYPE_ETQF))
+ return ip_pkt_etqf_map[(pkt_info >> 4) & 0X07] |
+ ip_rss_types_map[pkt_info & 0XF];
+ else
+ return ip_rss_types_map[pkt_info & 0XF];
+#else
+ return ip_rss_types_map[pkt_info & 0XF];
+#endif
+}
+#else /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
{
@@ -895,6 +999,7 @@ rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
#endif
return pkt_flags | ip_rss_types_map[hl_tp_rs & 0xF];
}
+#endif /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_status_to_pkt_flags(uint32_t rx_status)
@@ -950,7 +1055,13 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
struct rte_mbuf *mb;
uint16_t pkt_len;
uint64_t pkt_flags;
+#ifdef RTE_NEXT_ABI
+ int nb_dd;
+ uint32_t s[LOOK_AHEAD];
+ uint16_t pkt_info[LOOK_AHEAD];
+#else
int s[LOOK_AHEAD], nb_dd;
+#endif /* RTE_NEXT_ABI */
int i, j, nb_rx = 0;
@@ -973,6 +1084,12 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
for (j = LOOK_AHEAD-1; j >= 0; --j)
s[j] = rxdp[j].wb.upper.status_error;
+#ifdef RTE_NEXT_ABI
+ for (j = LOOK_AHEAD-1; j >= 0; --j)
+ pkt_info[j] = rxdp[j].wb.lower.lo_dword.
+ hs_rss.pkt_info;
+#endif /* RTE_NEXT_ABI */
+
/* Compute how many status bits were set */
nb_dd = 0;
for (j = 0; j < LOOK_AHEAD; ++j)
@@ -989,12 +1106,22 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
mb->vlan_tci = rte_le_to_cpu_16(rxdp[j].wb.upper.vlan);
/* convert descriptor fields to rte mbuf flags */
+#ifdef RTE_NEXT_ABI
+ pkt_flags = rx_desc_status_to_pkt_flags(s[j]);
+ pkt_flags |= rx_desc_error_to_pkt_flags(s[j]);
+ pkt_flags |=
+ ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info[j]);
+ mb->ol_flags = pkt_flags;
+ mb->packet_type =
+ ixgbe_rxd_pkt_info_to_pkt_type(pkt_info[j]);
+#else /* RTE_NEXT_ABI */
pkt_flags = rx_desc_hlen_type_rss_to_pkt_flags(
rxdp[j].wb.lower.lo_dword.data);
/* reuse status field from scan list */
pkt_flags |= rx_desc_status_to_pkt_flags(s[j]);
pkt_flags |= rx_desc_error_to_pkt_flags(s[j]);
mb->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
mb->hash.rss = rxdp[j].wb.lower.hi_dword.rss;
@@ -1211,7 +1338,11 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
union ixgbe_adv_rx_desc rxd;
uint64_t dma_addr;
uint32_t staterr;
+#ifdef RTE_NEXT_ABI
+ uint32_t pkt_info;
+#else
uint32_t hlen_type_rss;
+#endif
uint16_t pkt_len;
uint16_t rx_id;
uint16_t nb_rx;
@@ -1329,6 +1460,19 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
rxm->data_len = pkt_len;
rxm->port = rxq->port_id;
+#ifdef RTE_NEXT_ABI
+ pkt_info = rte_le_to_cpu_32(rxd.wb.lower.lo_dword.hs_rss.
+ pkt_info);
+ /* Only valid if PKT_RX_VLAN_PKT set in pkt_flags */
+ rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan);
+
+ pkt_flags = rx_desc_status_to_pkt_flags(staterr);
+ pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
+ pkt_flags = pkt_flags |
+ ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info);
+ rxm->ol_flags = pkt_flags;
+ rxm->packet_type = ixgbe_rxd_pkt_info_to_pkt_type(pkt_info);
+#else /* RTE_NEXT_ABI */
hlen_type_rss = rte_le_to_cpu_32(rxd.wb.lower.lo_dword.data);
/* Only valid if PKT_RX_VLAN_PKT set in pkt_flags */
rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan);
@@ -1337,6 +1481,7 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
rxm->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
rxm->hash.rss = rxd.wb.lower.hi_dword.rss;
@@ -1410,6 +1555,23 @@ ixgbe_fill_cluster_head_buf(
uint8_t port_id,
uint32_t staterr)
{
+#ifdef RTE_NEXT_ABI
+ uint16_t pkt_info;
+ uint64_t pkt_flags;
+
+ head->port = port_id;
+
+ /* The vlan_tci field is only valid when PKT_RX_VLAN_PKT is
+ * set in the pkt_flags field.
+ */
+ head->vlan_tci = rte_le_to_cpu_16(desc->wb.upper.vlan);
+ pkt_info = rte_le_to_cpu_32(desc->wb.lower.lo_dword.hs_rss.pkt_info);
+ pkt_flags = rx_desc_status_to_pkt_flags(staterr);
+ pkt_flags |= rx_desc_error_to_pkt_flags(staterr);
+ pkt_flags |= ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info);
+ head->ol_flags = pkt_flags;
+ head->packet_type = ixgbe_rxd_pkt_info_to_pkt_type(pkt_info);
+#else /* RTE_NEXT_ABI */
uint32_t hlen_type_rss;
uint64_t pkt_flags;
@@ -1425,6 +1587,7 @@ ixgbe_fill_cluster_head_buf(
pkt_flags |= rx_desc_status_to_pkt_flags(staterr);
pkt_flags |= rx_desc_error_to_pkt_flags(staterr);
head->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
head->hash.rss = rte_le_to_cpu_32(desc->wb.lower.hi_dword.rss);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v8 06/18] i40e: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (4 preceding siblings ...)
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 05/18] ixgbe: " Helin Zhang
@ 2015-06-23 1:50 3% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 07/18] enic: " Helin Zhang
` (13 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/i40e/i40e_rxtx.c | 528 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 528 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index b2e1d6d..b951da0 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -176,6 +176,514 @@ i40e_rxd_error_to_pkt_flags(uint64_t qword)
return flags;
}
+#ifdef RTE_NEXT_ABI
+/* For each value it means, datasheet of hardware can tell more details */
+static inline uint32_t
+i40e_rxd_pkt_type_mapping(uint8_t ptype)
+{
+ static const uint32_t ptype_table[UINT8_MAX] __rte_cache_aligned = {
+ /* L2 types */
+ /* [0] reserved */
+ [1] = RTE_PTYPE_L2_MAC,
+ [2] = RTE_PTYPE_L2_MAC_TIMESYNC,
+ /* [3] - [5] reserved */
+ [6] = RTE_PTYPE_L2_LLDP,
+ /* [7] - [10] reserved */
+ [11] = RTE_PTYPE_L2_ARP,
+ /* [12] - [21] reserved */
+
+ /* Non tunneled IPv4 */
+ [22] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [23] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [24] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [25] reserved */
+ [26] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [27] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [28] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+
+ /* IPv4 --> IPv4 */
+ [29] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [30] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [31] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [32] reserved */
+ [33] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [34] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [35] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> IPv6 */
+ [36] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [37] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [38] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [39] reserved */
+ [40] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [41] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [42] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN */
+ [43] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> IPv4 */
+ [44] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [45] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [46] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [47] reserved */
+ [48] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [49] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [50] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> IPv6 */
+ [51] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [52] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [53] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [54] reserved */
+ [55] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [56] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [57] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC */
+ [58] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC --> IPv4 */
+ [59] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [60] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [61] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [62] reserved */
+ [63] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [64] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [65] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC --> IPv6 */
+ [66] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [67] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [68] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [69] reserved */
+ [70] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [71] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [72] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN */
+ [73] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv4 */
+ [74] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [75] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [76] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [77] reserved */
+ [78] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [79] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [80] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv6 */
+ [81] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [82] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [83] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [84] reserved */
+ [85] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [86] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [87] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* Non tunneled IPv6 */
+ [88] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [89] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [90] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [91] reserved */
+ [92] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [93] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [94] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+
+ /* IPv6 --> IPv4 */
+ [95] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [96] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [97] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [98] reserved */
+ [99] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [100] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [101] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> IPv6 */
+ [102] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [103] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [104] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [105] reserved */
+ [106] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [107] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [108] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN */
+ [109] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> IPv4 */
+ [110] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [111] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [112] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [113] reserved */
+ [114] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [115] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [116] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> IPv6 */
+ [117] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [118] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [119] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [120] reserved */
+ [121] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [122] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [123] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC */
+ [124] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC --> IPv4 */
+ [125] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [126] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [127] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [128] reserved */
+ [129] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [130] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [131] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC --> IPv6 */
+ [132] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [133] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [134] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [135] reserved */
+ [136] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [137] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [138] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN */
+ [139] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv4 */
+ [140] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [141] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [142] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [143] reserved */
+ [144] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [145] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [146] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv6 */
+ [147] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [148] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [149] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [150] reserved */
+ [151] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [152] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [153] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_MAC_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* All others reserved */
+ };
+
+ return ptype_table[ptype];
+}
+#else /* RTE_NEXT_ABI */
/* Translate pkt types to pkt flags */
static inline uint64_t
i40e_rxd_ptype_to_pkt_flags(uint64_t qword)
@@ -443,6 +951,7 @@ i40e_rxd_ptype_to_pkt_flags(uint64_t qword)
return ip_ptype_map[ptype];
}
+#endif /* RTE_NEXT_ABI */
#define I40E_RX_DESC_EXT_STATUS_FLEXBH_MASK 0x03
#define I40E_RX_DESC_EXT_STATUS_FLEXBH_FD_ID 0x01
@@ -730,11 +1239,18 @@ i40e_rx_scan_hw_ring(struct i40e_rx_queue *rxq)
i40e_rxd_to_vlan_tci(mb, &rxdp[j]);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ mb->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >>
+ I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
mb->packet_type = (uint16_t)((qword1 &
I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
mb->hash.rss = rte_le_to_cpu_32(\
rxdp[j].wb.qword0.hi_dword.rss);
@@ -971,9 +1487,15 @@ i40e_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
i40e_rxd_to_vlan_tci(rxm, &rxd);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
rxm->packet_type = (uint16_t)((qword1 & I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
rxm->hash.rss =
rte_le_to_cpu_32(rxd.wb.qword0.hi_dword.rss);
@@ -1129,10 +1651,16 @@ i40e_recv_scattered_pkts(void *rx_queue,
i40e_rxd_to_vlan_tci(first_seg, &rxd);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ first_seg->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
first_seg->packet_type = (uint16_t)((qword1 &
I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
rxm->hash.rss =
rte_le_to_cpu_32(rxd.wb.qword0.hi_dword.rss);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v8 08/18] vmxnet3: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (6 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 07/18] enic: " Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 09/18] fm10k: " Helin Zhang
` (11 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/vmxnet3/vmxnet3_rxtx.c | 8 ++++++++
1 file changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index a1eac45..25ae2f6 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -649,9 +649,17 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = RTE_PTYPE_L3_IPV4_EXT;
+#else
rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
+#endif
else
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rxm->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!rcd->cnc) {
if (!rcd->ipc)
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 07/18] enic: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (5 preceding siblings ...)
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 06/18] i40e: " Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 08/18] vmxnet3: " Helin Zhang
` (12 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/enic/enic_main.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 15313c2..f47e96c 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -423,7 +423,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
rx_pkt->pkt_len = bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
rx_pkt->ol_flags |= PKT_RX_IP_CKSUM_BAD;
@@ -432,7 +436,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
rx_pkt->ol_flags |= PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV6;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
} else {
/* Header split */
if (sop && !eop) {
@@ -445,7 +453,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
*rx_pkt_bucket = rx_pkt;
rx_pkt->pkt_len = bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
rx_pkt->ol_flags |=
@@ -457,13 +469,22 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV6;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
} else {
/* Payload */
hdr_rx_pkt = *rx_pkt_bucket;
hdr_rx_pkt->pkt_len += bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ hdr_rx_pkt->packet_type =
+ RTE_PTYPE_L3_IPV4;
+#else
hdr_rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
hdr_rx_pkt->ol_flags |=
@@ -475,7 +496,12 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ hdr_rx_pkt->packet_type =
+ RTE_PTYPE_L3_IPV6;
+#else
hdr_rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
}
}
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 09/18] fm10k: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (7 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 08/18] vmxnet3: " Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 10/18] app/test-pipeline: " Helin Zhang
` (10 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/fm10k/fm10k_rxtx.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
v4 changes:
* Supported unified packet type of fm10k from v4.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index f5d1ad0..4b00f5c 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -68,12 +68,37 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
static inline void
rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
{
+#ifdef RTE_NEXT_ABI
+ static const uint32_t
+ ptype_table[FM10K_RXD_PKTTYPE_MASK >> FM10K_RXD_PKTTYPE_SHIFT]
+ __rte_cache_aligned = {
+ [FM10K_PKTTYPE_OTHER] = RTE_PTYPE_L2_MAC,
+ [FM10K_PKTTYPE_IPV4] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV4,
+ [FM10K_PKTTYPE_IPV4_EX] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [FM10K_PKTTYPE_IPV6] = RTE_PTYPE_L2_MAC | RTE_PTYPE_L3_IPV6,
+ [FM10K_PKTTYPE_IPV6_EX] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [FM10K_PKTTYPE_IPV4 | FM10K_PKTTYPE_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [FM10K_PKTTYPE_IPV6 | FM10K_PKTTYPE_TCP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [FM10K_PKTTYPE_IPV4 | FM10K_PKTTYPE_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [FM10K_PKTTYPE_IPV6 | FM10K_PKTTYPE_UDP] = RTE_PTYPE_L2_MAC |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ };
+
+ m->packet_type = ptype_table[(d->w.pkt_info & FM10K_RXD_PKTTYPE_MASK)
+ >> FM10K_RXD_PKTTYPE_SHIFT];
+#else /* RTE_NEXT_ABI */
uint16_t ptype;
static const uint16_t pt_lut[] = { 0,
PKT_RX_IPV4_HDR, PKT_RX_IPV4_HDR_EXT,
PKT_RX_IPV6_HDR, PKT_RX_IPV6_HDR_EXT,
0, 0, 0
};
+#endif /* RTE_NEXT_ABI */
if (d->w.pkt_info & FM10K_RXD_RSSTYPE_MASK)
m->ol_flags |= PKT_RX_RSS_HASH;
@@ -97,9 +122,11 @@ rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
if (unlikely(d->d.staterr & FM10K_RXD_STATUS_RXE))
m->ol_flags |= PKT_RX_RECIP_ERR;
+#ifndef RTE_NEXT_ABI
ptype = (d->d.data & FM10K_RXD_PKTTYPE_MASK_L3) >>
FM10K_RXD_PKTTYPE_SHIFT;
m->ol_flags |= pt_lut[(uint8_t)ptype];
+#endif
}
uint16_t
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 10/18] app/test-pipeline: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (8 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 09/18] fm10k: " Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 11/18] app/testpmd: " Helin Zhang
` (9 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
app/test-pipeline/pipeline_hash.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
index 4598ad4..aa3f9e5 100644
--- a/app/test-pipeline/pipeline_hash.c
+++ b/app/test-pipeline/pipeline_hash.c
@@ -459,20 +459,33 @@ app_main_loop_rx_metadata(void) {
signature = RTE_MBUF_METADATA_UINT32_PTR(m, 0);
key = RTE_MBUF_METADATA_UINT8_PTR(m, 32);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
ip_hdr = (struct ipv4_hdr *)
&m_data[sizeof(struct ether_hdr)];
ip_dst = ip_hdr->dst_addr;
k32 = (uint32_t *) key;
k32[0] = ip_dst & 0xFFFFFF00;
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
} else {
+#endif
ipv6_hdr = (struct ipv6_hdr *)
&m_data[sizeof(struct ether_hdr)];
ipv6_dst = ipv6_hdr->dst_addr;
memcpy(key, ipv6_dst, 16);
+#ifdef RTE_NEXT_ABI
+ } else
+ continue;
+#else
}
+#endif
*signature = test_hash(key, 0, 0);
}
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 11/18] app/testpmd: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (9 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 10/18] app/test-pipeline: " Helin Zhang
@ 2015-06-23 1:50 3% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 12/18] app/test: Remove useless code Helin Zhang
` (8 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
---
app/test-pmd/csumonly.c | 14 ++++
app/test-pmd/rxonly.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 197 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v4 changes:
* Added printing logs of packet types of each received packet in rxonly mode.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 950ea82..fab9600 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -202,8 +202,14 @@ parse_ethernet(struct ether_hdr *eth_hdr, struct testpmd_offload_info *info)
/* Parse a vxlan header */
static void
+#ifdef RTE_NEXT_ABI
+parse_vxlan(struct udp_hdr *udp_hdr,
+ struct testpmd_offload_info *info,
+ uint32_t pkt_type)
+#else
parse_vxlan(struct udp_hdr *udp_hdr, struct testpmd_offload_info *info,
uint64_t mbuf_olflags)
+#endif
{
struct ether_hdr *eth_hdr;
@@ -211,8 +217,12 @@ parse_vxlan(struct udp_hdr *udp_hdr, struct testpmd_offload_info *info,
* (rfc7348) or that the rx offload flag is set (i40e only
* currently) */
if (udp_hdr->dst_port != _htons(4789) &&
+#ifdef RTE_NEXT_ABI
+ RTE_ETH_IS_TUNNEL_PKT(pkt_type) == 0)
+#else
(mbuf_olflags & (PKT_RX_TUNNEL_IPV4_HDR |
PKT_RX_TUNNEL_IPV6_HDR)) == 0)
+#endif
return;
info->is_tunnel = 1;
@@ -549,7 +559,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
struct udp_hdr *udp_hdr;
udp_hdr = (struct udp_hdr *)((char *)l3_hdr +
info.l3_len);
+#ifdef RTE_NEXT_ABI
+ parse_vxlan(udp_hdr, &info, m->packet_type);
+#else
parse_vxlan(udp_hdr, &info, m->ol_flags);
+#endif
} else if (info.l4_proto == IPPROTO_GRE) {
struct simple_gre_hdr *gre_hdr;
gre_hdr = (struct simple_gre_hdr *)
diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
index f6a2f84..5a30347 100644
--- a/app/test-pmd/rxonly.c
+++ b/app/test-pmd/rxonly.c
@@ -91,7 +91,11 @@ pkt_burst_receive(struct fwd_stream *fs)
uint64_t ol_flags;
uint16_t nb_rx;
uint16_t i, packet_type;
+#ifdef RTE_NEXT_ABI
+ uint16_t is_encapsulation;
+#else
uint64_t is_encapsulation;
+#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t start_tsc;
@@ -135,8 +139,12 @@ pkt_burst_receive(struct fwd_stream *fs)
ol_flags = mb->ol_flags;
packet_type = mb->packet_type;
+#ifdef RTE_NEXT_ABI
+ is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
+#else
is_encapsulation = ol_flags & (PKT_RX_TUNNEL_IPV4_HDR |
PKT_RX_TUNNEL_IPV6_HDR);
+#endif
print_ether_addr(" src=", ð_hdr->s_addr);
print_ether_addr(" - dst=", ð_hdr->d_addr);
@@ -163,6 +171,177 @@ pkt_burst_receive(struct fwd_stream *fs)
if (ol_flags & PKT_RX_QINQ_PKT)
printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x",
mb->vlan_tci, mb->vlan_tci_outer);
+#ifdef RTE_NEXT_ABI
+ if (mb->packet_type) {
+ uint32_t ptype;
+
+ /* (outer) L2 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L2_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L2_MAC:
+ printf(" - (outer) L2 type: MAC");
+ break;
+ case RTE_PTYPE_L2_MAC_TIMESYNC:
+ printf(" - (outer) L2 type: MAC Timesync");
+ break;
+ case RTE_PTYPE_L2_ARP:
+ printf(" - (outer) L2 type: ARP");
+ break;
+ case RTE_PTYPE_L2_LLDP:
+ printf(" - (outer) L2 type: LLDP");
+ break;
+ default:
+ printf(" - (outer) L2 type: Unknown");
+ break;
+ }
+
+ /* (outer) L3 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L3_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L3_IPV4:
+ printf(" - (outer) L3 type: IPV4");
+ break;
+ case RTE_PTYPE_L3_IPV4_EXT:
+ printf(" - (outer) L3 type: IPV4_EXT");
+ break;
+ case RTE_PTYPE_L3_IPV6:
+ printf(" - (outer) L3 type: IPV6");
+ break;
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ printf(" - (outer) L3 type: IPV4_EXT_UNKNOWN");
+ break;
+ case RTE_PTYPE_L3_IPV6_EXT:
+ printf(" - (outer) L3 type: IPV6_EXT");
+ break;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ printf(" - (outer) L3 type: IPV6_EXT_UNKNOWN");
+ break;
+ default:
+ printf(" - (outer) L3 type: Unknown");
+ break;
+ }
+
+ /* (outer) L4 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L4_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L4_TCP:
+ printf(" - (outer) L4 type: TCP");
+ break;
+ case RTE_PTYPE_L4_UDP:
+ printf(" - (outer) L4 type: UDP");
+ break;
+ case RTE_PTYPE_L4_FRAG:
+ printf(" - (outer) L4 type: L4_FRAG");
+ break;
+ case RTE_PTYPE_L4_SCTP:
+ printf(" - (outer) L4 type: SCTP");
+ break;
+ case RTE_PTYPE_L4_ICMP:
+ printf(" - (outer) L4 type: ICMP");
+ break;
+ case RTE_PTYPE_L4_NONFRAG:
+ printf(" - (outer) L4 type: L4_NONFRAG");
+ break;
+ default:
+ printf(" - (outer) L4 type: Unknown");
+ break;
+ }
+
+ /* packet tunnel type */
+ ptype = mb->packet_type & RTE_PTYPE_TUNNEL_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_TUNNEL_IP:
+ printf(" - Tunnel type: IP");
+ break;
+ case RTE_PTYPE_TUNNEL_GRE:
+ printf(" - Tunnel type: GRE");
+ break;
+ case RTE_PTYPE_TUNNEL_VXLAN:
+ printf(" - Tunnel type: VXLAN");
+ break;
+ case RTE_PTYPE_TUNNEL_NVGRE:
+ printf(" - Tunnel type: NVGRE");
+ break;
+ case RTE_PTYPE_TUNNEL_GENEVE:
+ printf(" - Tunnel type: GENEVE");
+ break;
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ printf(" - Tunnel type: GRENAT");
+ break;
+ default:
+ printf(" - Tunnel type: Unkown");
+ break;
+ }
+
+ /* inner L2 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L2_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L2_MAC:
+ printf(" - Inner L2 type: MAC");
+ break;
+ case RTE_PTYPE_INNER_L2_MAC_VLAN:
+ printf(" - Inner L2 type: MAC_VLAN");
+ break;
+ default:
+ printf(" - Inner L2 type: Unknown");
+ break;
+ }
+
+ /* inner L3 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_INNER_L3_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L3_IPV4:
+ printf(" - Inner L3 type: IPV4");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV4_EXT:
+ printf(" - Inner L3 type: IPV4_EXT");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6:
+ printf(" - Inner L3 type: IPV6");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ printf(" - Inner L3 type: IPV4_EXT_UNKNOWN");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT:
+ printf(" - Inner L3 type: IPV6_EXT");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ printf(" - Inner L3 type: IPV6_EXT_UNKOWN");
+ break;
+ default:
+ printf(" - Inner L3 type: Unkown");
+ break;
+ }
+
+ /* inner L4 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L4_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ printf(" - Inner L4 type: TCP");
+ break;
+ case RTE_PTYPE_INNER_L4_UDP:
+ printf(" - Inner L4 type: UDP");
+ break;
+ case RTE_PTYPE_INNER_L4_FRAG:
+ printf(" - Inner L4 type: L4_FRAG");
+ break;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ printf(" - Inner L4 type: SCTP");
+ break;
+ case RTE_PTYPE_INNER_L4_ICMP:
+ printf(" - Inner L4 type: ICMP");
+ break;
+ case RTE_PTYPE_INNER_L4_NONFRAG:
+ printf(" - Inner L4 type: L4_NONFRAG");
+ break;
+ default:
+ printf(" - Inner L4 type: Unknown");
+ break;
+ }
+ printf("\n");
+ } else
+ printf("Unknown packet type\n");
+#endif /* RTE_NEXT_ABI */
if (is_encapsulation) {
struct ipv4_hdr *ipv4_hdr;
struct ipv6_hdr *ipv6_hdr;
@@ -176,7 +355,11 @@ pkt_burst_receive(struct fwd_stream *fs)
l2_len = sizeof(struct ether_hdr);
/* Do not support ipv4 option field */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(packet_type)) {
+#else
if (ol_flags & PKT_RX_TUNNEL_IPV4_HDR) {
+#endif
l3_len = sizeof(struct ipv4_hdr);
ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v8 12/18] app/test: Remove useless code
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (10 preceding siblings ...)
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 11/18] app/testpmd: " Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 13/18] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
` (7 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
Severl useless code lines are added accidently, which blocks packet
type unification. They should be deleted at all.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
app/test/packet_burst_generator.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
v4 changes:
* Removed several useless code lines which block packet type unification.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c
index b46eed7..61e6340 100644
--- a/app/test/packet_burst_generator.c
+++ b/app/test/packet_burst_generator.c
@@ -272,19 +272,21 @@ nomore_mbuf:
if (ipv4) {
pkt->vlan_tci = ETHER_TYPE_IPv4;
pkt->l3_len = sizeof(struct ipv4_hdr);
-
+#ifndef RTE_NEXT_ABI
if (vlan_enabled)
pkt->ol_flags = PKT_RX_IPV4_HDR | PKT_RX_VLAN_PKT;
else
pkt->ol_flags = PKT_RX_IPV4_HDR;
+#endif
} else {
pkt->vlan_tci = ETHER_TYPE_IPv6;
pkt->l3_len = sizeof(struct ipv6_hdr);
-
+#ifndef RTE_NEXT_ABI
if (vlan_enabled)
pkt->ol_flags = PKT_RX_IPV6_HDR | PKT_RX_VLAN_PKT;
else
pkt->ol_flags = PKT_RX_IPV6_HDR;
+#endif
}
pkts_burst[nb_pkt] = pkt;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 13/18] examples/ip_fragmentation: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (11 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 12/18] app/test: Remove useless code Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 14/18] examples/ip_reassembly: " Helin Zhang
` (6 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/ip_fragmentation/main.c | 9 +++++++++
1 file changed, 9 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 0922ba6..b71d05f 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -283,7 +283,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf,
len = qconf->tx_mbufs[port_out].len;
/* if this is an IPv4 packet */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
struct ipv4_hdr *ip_hdr;
uint32_t ip_dst;
/* Read the lookup key (i.e. ip_dst) from the input packet */
@@ -317,9 +321,14 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf,
if (unlikely (len2 < 0))
return;
}
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+ /* if this is an IPv6 packet */
+#else
}
/* if this is an IPv6 packet */
else if (m->ol_flags & PKT_RX_IPV6_HDR) {
+#endif
struct ipv6_hdr *ip_hdr;
ipv6 = 1;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 14/18] examples/ip_reassembly: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (12 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 13/18] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 15/18] examples/l3fwd-acl: " Helin Zhang
` (5 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/ip_reassembly/main.c | 9 +++++++++
1 file changed, 9 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 9ecb6f9..f1c47ad 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -356,7 +356,11 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue,
dst_port = portid;
/* if packet is IPv4 */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & (PKT_RX_IPV4_HDR)) {
+#endif
struct ipv4_hdr *ip_hdr;
uint32_t ip_dst;
@@ -396,9 +400,14 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue,
}
eth_hdr->ether_type = rte_be_to_cpu_16(ETHER_TYPE_IPv4);
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+ /* if packet is IPv6 */
+#else
}
/* if packet is IPv6 */
else if (m->ol_flags & (PKT_RX_IPV6_HDR | PKT_RX_IPV6_HDR_EXT)) {
+#endif
struct ipv6_extension_fragment *frag_hdr;
struct ipv6_hdr *ip_hdr;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 15/18] examples/l3fwd-acl: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (13 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 14/18] examples/ip_reassembly: " Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 16/18] examples/l3fwd-power: " Helin Zhang
` (4 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd-acl/main.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index a5d4f25..78b6df2 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -645,10 +645,13 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
struct ipv4_hdr *ipv4_hdr;
struct rte_mbuf *pkt = pkts_in[index];
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
int type = pkt->ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_IPV6_HDR);
if (type == PKT_RX_IPV4_HDR) {
-
+#endif
ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(pkt,
unsigned char *) + sizeof(struct ether_hdr));
@@ -667,9 +670,11 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
/* Not a valid IPv4 packet */
rte_pktmbuf_free(pkt);
}
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (type == PKT_RX_IPV6_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv6[acl->num_ipv6] = MBUF_IPV6_2PROTO(pkt);
acl->m_ipv6[(acl->num_ipv6)++] = pkt;
@@ -687,17 +692,22 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
{
struct rte_mbuf *pkt = pkts_in[index];
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
int type = pkt->ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_IPV6_HDR);
if (type == PKT_RX_IPV4_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv4[acl->num_ipv4] = MBUF_IPV4_2PROTO(pkt);
acl->m_ipv4[(acl->num_ipv4)++] = pkt;
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (type == PKT_RX_IPV6_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv6[acl->num_ipv6] = MBUF_IPV6_2PROTO(pkt);
acl->m_ipv6[(acl->num_ipv6)++] = pkt;
@@ -745,10 +755,17 @@ send_one_packet(struct rte_mbuf *m, uint32_t res)
/* in the ACL list, drop it */
#ifdef L3FWDACL_DEBUG
if ((res & ACL_DENY_SIGNATURE) != 0) {
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type))
+ dump_acl4_rule(m, res);
+ else if (RTE_ETH_IS_IPV6_HDR(m->packet_type))
+ dump_acl6_rule(m, res);
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR)
dump_acl4_rule(m, res);
else
dump_acl6_rule(m, res);
+#endif /* RTE_NEXT_ABI */
}
#endif
rte_pktmbuf_free(m);
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 16/18] examples/l3fwd-power: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (14 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 15/18] examples/l3fwd-acl: " Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 17/18] examples/l3fwd: " Helin Zhang
` (3 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd-power/main.c | 8 ++++++++
1 file changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 6057059..705188f 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -635,7 +635,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
/* Handle IPv4 headers.*/
ipv4_hdr =
(struct ipv4_hdr *)(rte_pktmbuf_mtod(m, unsigned char*)
@@ -670,8 +674,12 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
}
else {
+#endif
/* Handle IPv6 headers.*/
#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
struct ipv6_hdr *ipv6_hdr;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 17/18] examples/l3fwd: replace bit mask based packet type with unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (15 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 16/18] examples/l3fwd-power: " Helin Zhang
@ 2015-06-23 1:50 3% ` Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 18/18] mbuf: remove old packet type bit masks Helin Zhang
` (2 subsequent siblings)
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd/main.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 120 insertions(+), 3 deletions(-)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v3 changes:
* Minor bug fixes and enhancements.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 7e4bbfd..eff9580 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -948,7 +948,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
/* Handle IPv4 headers.*/
ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m, unsigned char *) +
sizeof(struct ether_hdr));
@@ -979,8 +983,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
} else {
+#endif
/* Handle IPv6 headers.*/
struct ipv6_hdr *ipv6_hdr;
@@ -999,8 +1006,13 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
+#ifdef RTE_NEXT_ABI
+ } else
+ /* Free the mbuf that contains non-IPV4/IPV6 packet */
+ rte_pktmbuf_free(m);
+#else
}
-
+#endif
}
#ifdef DO_RFC_1812_CHECKS
@@ -1024,12 +1036,19 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
* to BAD_PORT value.
*/
static inline __attribute__((always_inline)) void
+#ifdef RTE_NEXT_ABI
+rfc1812_process(struct ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t ptype)
+#else
rfc1812_process(struct ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t flags)
+#endif
{
uint8_t ihl;
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(ptype)) {
+#else
if ((flags & PKT_RX_IPV4_HDR) != 0) {
-
+#endif
ihl = ipv4_hdr->version_ihl - IPV4_MIN_VER_IHL;
ipv4_hdr->time_to_live--;
@@ -1059,11 +1078,19 @@ get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
struct ipv6_hdr *ipv6_hdr;
struct ether_hdr *eth_hdr;
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
if (pkt->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
if (rte_lpm_lookup(qconf->ipv4_lookup_struct, dst_ipv4,
&next_hop) != 0)
next_hop = portid;
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (pkt->ol_flags & PKT_RX_IPV6_HDR) {
+#endif
eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
ipv6_hdr = (struct ipv6_hdr *)(eth_hdr + 1);
if (rte_lpm6_lookup(qconf->ipv6_lookup_struct,
@@ -1097,12 +1124,52 @@ process_packet(struct lcore_conf *qconf, struct rte_mbuf *pkt,
ve = val_eth[dp];
dst_port[0] = dp;
+#ifdef RTE_NEXT_ABI
+ rfc1812_process(ipv4_hdr, dst_port, pkt->packet_type);
+#else
rfc1812_process(ipv4_hdr, dst_port, pkt->ol_flags);
+#endif
te = _mm_blend_epi16(te, ve, MASK_ETH);
_mm_store_si128((__m128i *)eth_hdr, te);
}
+#ifdef RTE_NEXT_ABI
+/*
+ * Read packet_type and destination IPV4 addresses from 4 mbufs.
+ */
+static inline void
+processx4_step1(struct rte_mbuf *pkt[FWDSTEP],
+ __m128i *dip,
+ uint32_t *ipv4_flag)
+{
+ struct ipv4_hdr *ipv4_hdr;
+ struct ether_hdr *eth_hdr;
+ uint32_t x0, x1, x2, x3;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[0], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x0 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] = pkt[0]->packet_type & RTE_PTYPE_L3_IPV4;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[1], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x1 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[1]->packet_type;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[2], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x2 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[2]->packet_type;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[3], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x3 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[3]->packet_type;
+
+ dip[0] = _mm_set_epi32(x3, x2, x1, x0);
+}
+#else /* RTE_NEXT_ABI */
/*
* Read ol_flags and destination IPV4 addresses from 4 mbufs.
*/
@@ -1135,14 +1202,24 @@ processx4_step1(struct rte_mbuf *pkt[FWDSTEP], __m128i *dip, uint32_t *flag)
dip[0] = _mm_set_epi32(x3, x2, x1, x0);
}
+#endif /* RTE_NEXT_ABI */
/*
* Lookup into LPM for destination port.
* If lookup fails, use incoming port (portid) as destination port.
*/
static inline void
+#ifdef RTE_NEXT_ABI
+processx4_step2(const struct lcore_conf *qconf,
+ __m128i dip,
+ uint32_t ipv4_flag,
+ uint8_t portid,
+ struct rte_mbuf *pkt[FWDSTEP],
+ uint16_t dprt[FWDSTEP])
+#else
processx4_step2(const struct lcore_conf *qconf, __m128i dip, uint32_t flag,
uint8_t portid, struct rte_mbuf *pkt[FWDSTEP], uint16_t dprt[FWDSTEP])
+#endif /* RTE_NEXT_ABI */
{
rte_xmm_t dst;
const __m128i bswap_mask = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11,
@@ -1152,7 +1229,11 @@ processx4_step2(const struct lcore_conf *qconf, __m128i dip, uint32_t flag,
dip = _mm_shuffle_epi8(dip, bswap_mask);
/* if all 4 packets are IPV4. */
+#ifdef RTE_NEXT_ABI
+ if (likely(ipv4_flag)) {
+#else
if (likely(flag != 0)) {
+#endif
rte_lpm_lookupx4(qconf->ipv4_lookup_struct, dip, dprt, portid);
} else {
dst.x = dip;
@@ -1202,6 +1283,16 @@ processx4_step3(struct rte_mbuf *pkt[FWDSTEP], uint16_t dst_port[FWDSTEP])
_mm_store_si128(p[2], te[2]);
_mm_store_si128(p[3], te[3]);
+#ifdef RTE_NEXT_ABI
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[0] + 1),
+ &dst_port[0], pkt[0]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[1] + 1),
+ &dst_port[1], pkt[1]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[2] + 1),
+ &dst_port[2], pkt[2]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[3] + 1),
+ &dst_port[3], pkt[3]->packet_type);
+#else /* RTE_NEXT_ABI */
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[0] + 1),
&dst_port[0], pkt[0]->ol_flags);
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[1] + 1),
@@ -1210,6 +1301,7 @@ processx4_step3(struct rte_mbuf *pkt[FWDSTEP], uint16_t dst_port[FWDSTEP])
&dst_port[2], pkt[2]->ol_flags);
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[3] + 1),
&dst_port[3], pkt[3]->ol_flags);
+#endif /* RTE_NEXT_ABI */
}
/*
@@ -1396,7 +1488,11 @@ main_loop(__attribute__((unused)) void *dummy)
uint16_t *lp;
uint16_t dst_port[MAX_PKT_BURST];
__m128i dip[MAX_PKT_BURST / FWDSTEP];
+#ifdef RTE_NEXT_ABI
+ uint32_t ipv4_flag[MAX_PKT_BURST / FWDSTEP];
+#else
uint32_t flag[MAX_PKT_BURST / FWDSTEP];
+#endif
uint16_t pnum[MAX_PKT_BURST + 1];
#endif
@@ -1466,6 +1562,18 @@ main_loop(__attribute__((unused)) void *dummy)
*/
int32_t n = RTE_ALIGN_FLOOR(nb_rx, 4);
for (j = 0; j < n ; j+=4) {
+#ifdef RTE_NEXT_ABI
+ uint32_t pkt_type =
+ pkts_burst[j]->packet_type &
+ pkts_burst[j+1]->packet_type &
+ pkts_burst[j+2]->packet_type &
+ pkts_burst[j+3]->packet_type;
+ if (pkt_type & RTE_PTYPE_L3_IPV4) {
+ simple_ipv4_fwd_4pkts(
+ &pkts_burst[j], portid, qconf);
+ } else if (pkt_type &
+ RTE_PTYPE_L3_IPV6) {
+#else /* RTE_NEXT_ABI */
uint32_t ol_flag = pkts_burst[j]->ol_flags
& pkts_burst[j+1]->ol_flags
& pkts_burst[j+2]->ol_flags
@@ -1474,6 +1582,7 @@ main_loop(__attribute__((unused)) void *dummy)
simple_ipv4_fwd_4pkts(&pkts_burst[j],
portid, qconf);
} else if (ol_flag & PKT_RX_IPV6_HDR) {
+#endif /* RTE_NEXT_ABI */
simple_ipv6_fwd_4pkts(&pkts_burst[j],
portid, qconf);
} else {
@@ -1498,13 +1607,21 @@ main_loop(__attribute__((unused)) void *dummy)
for (j = 0; j != k; j += FWDSTEP) {
processx4_step1(&pkts_burst[j],
&dip[j / FWDSTEP],
+#ifdef RTE_NEXT_ABI
+ &ipv4_flag[j / FWDSTEP]);
+#else
&flag[j / FWDSTEP]);
+#endif
}
k = RTE_ALIGN_FLOOR(nb_rx, FWDSTEP);
for (j = 0; j != k; j += FWDSTEP) {
processx4_step2(qconf, dip[j / FWDSTEP],
+#ifdef RTE_NEXT_ABI
+ ipv4_flag[j / FWDSTEP], portid,
+#else
flag[j / FWDSTEP], portid,
+#endif
&pkts_burst[j], &dst_port[j]);
}
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v8 18/18] mbuf: remove old packet type bit masks
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (16 preceding siblings ...)
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 17/18] examples/l3fwd: " Helin Zhang
@ 2015-06-23 1:50 4% ` Helin Zhang
2015-06-23 16:13 0% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Ananyev, Konstantin
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
19 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-06-23 1:50 UTC (permalink / raw)
To: dev
As unified packet types are used instead, those old bit masks and
the relevant macros for packet type indication need to be removed.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
lib/librte_mbuf/rte_mbuf.c | 4 ++++
lib/librte_mbuf/rte_mbuf.h | 4 ++++
2 files changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
* Redefined the bit masks for packet RX offload flags.
v5 changes:
* Rolled back the bit masks of RX flags, for ABI compatibility.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index f506517..4320dd4 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -251,14 +251,18 @@ const char *rte_get_rx_ol_flag_name(uint64_t mask)
/* case PKT_RX_HBUF_OVERFLOW: return "PKT_RX_HBUF_OVERFLOW"; */
/* case PKT_RX_RECIP_ERR: return "PKT_RX_RECIP_ERR"; */
/* case PKT_RX_MAC_ERR: return "PKT_RX_MAC_ERR"; */
+#ifndef RTE_NEXT_ABI
case PKT_RX_IPV4_HDR: return "PKT_RX_IPV4_HDR";
case PKT_RX_IPV4_HDR_EXT: return "PKT_RX_IPV4_HDR_EXT";
case PKT_RX_IPV6_HDR: return "PKT_RX_IPV6_HDR";
case PKT_RX_IPV6_HDR_EXT: return "PKT_RX_IPV6_HDR_EXT";
+#endif /* RTE_NEXT_ABI */
case PKT_RX_IEEE1588_PTP: return "PKT_RX_IEEE1588_PTP";
case PKT_RX_IEEE1588_TMST: return "PKT_RX_IEEE1588_TMST";
+#ifndef RTE_NEXT_ABI
case PKT_RX_TUNNEL_IPV4_HDR: return "PKT_RX_TUNNEL_IPV4_HDR";
case PKT_RX_TUNNEL_IPV6_HDR: return "PKT_RX_TUNNEL_IPV6_HDR";
+#endif /* RTE_NEXT_ABI */
default: return NULL;
}
}
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 0ee0c55..74a7f41 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -91,14 +91,18 @@ 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. */
--
1.9.3
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v5 01/13] port: added structures for port stats and config option
@ 2015-06-23 13:55 3% ` Thomas Monjalon
2015-06-23 14:30 3% ` Dumitrescu, Cristian
2015-06-23 15:16 3% ` Neil Horman
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2015-06-23 13:55 UTC (permalink / raw)
To: Maciej Gajdzica; +Cc: dev
2015-06-19 11:41, Maciej Gajdzica:
> /** Input port interface defining the input port operation */
> struct rte_port_in_ops {
> rte_port_in_op_create f_create; /**< Create */
> rte_port_in_op_free f_free; /**< Free */
> rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
> + rte_port_in_op_stats_read f_stats; /**< Stats */
> };
Isn't it breaking an ABI?
> struct rte_port_out_ops {
> - rte_port_out_op_create f_create; /**< Create */
> - rte_port_out_op_free f_free; /**< Free */
> - rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
> - rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
> - rte_port_out_op_flush f_flush; /**< Flush */
> + rte_port_out_op_create f_create; /**< Create */
> + rte_port_out_op_free f_free; /**< Free */
> + rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
> + rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
> + rte_port_out_op_flush f_flush; /**< Flush */
What is the goal of this change? Breaking the alignment?
> + rte_port_out_op_stats_read f_stats; /**< Stats */
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v5 01/13] port: added structures for port stats and config option
2015-06-23 13:55 3% ` Thomas Monjalon
@ 2015-06-23 14:30 3% ` Dumitrescu, Cristian
2015-06-23 14:54 0% ` Thomas Monjalon
2015-06-23 15:16 3% ` Neil Horman
1 sibling, 1 reply; 200+ results
From: Dumitrescu, Cristian @ 2015-06-23 14:30 UTC (permalink / raw)
To: Thomas Monjalon, Gajdzica, MaciejX T; +Cc: dev
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Tuesday, June 23, 2015 2:55 PM
> To: Gajdzica, MaciejX T
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v5 01/13] port: added structures for port
> stats and config option
>
> 2015-06-19 11:41, Maciej Gajdzica:
> > /** Input port interface defining the input port operation */
> > struct rte_port_in_ops {
> > rte_port_in_op_create f_create; /**< Create */
> > rte_port_in_op_free f_free; /**< Free */
> > rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
> > + rte_port_in_op_stats_read f_stats; /**< Stats */
> > };
>
> Isn't it breaking an ABI?
This is simply adding a field at the end of the API structure. This structure is instantiated per each port type and its role is very similar to a driver ops structure, for example:
in file "rte_port_ethdev.h": extern struct rte_port_out_ops rte_port_ethdev_writer_ops;
in file "rte_port_ring.h": extern struct rte_port_out_ops rte_port_ring_writer_nodrop_ops;
Typically, instances of these structures are only referenced through pointers by application code (and other libraries, like librte_pipeline), so code that is not aware of this last field in the structure will still continue to work.
The only case I see possible when code will break is if somebody would create an array of such structures, but I think this is not a realistic scenario. Instances of this structure are infrequent: once per port type in librte_port, and new instances are only created when the user wants to create new port type. Basically, instances of this structure are created in isolation and not in bulk (arrays).
Due to this, I do not see this as breaking the API. I think this is the most it could be done to minimize the effect on the ABI will still adding new functionality. Please let me know what you think.
>
> > struct rte_port_out_ops {
> > - rte_port_out_op_create f_create; /**< Create */
> > - rte_port_out_op_free f_free; /**< Free */
> > - rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
> > - rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst)
> */
> > - rte_port_out_op_flush f_flush; /**< Flush */
> > + rte_port_out_op_create f_create; /**< Create */
> > + rte_port_out_op_free f_free; /**< Free */
> > + rte_port_out_op_tx f_tx; /**< Packet
> TX (single packet) */
> > + rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX
> (packet burst) */
> > + rte_port_out_op_flush f_flush; /**< Flush */
>
> What is the goal of this change? Breaking the alignment?
Shall we submit a new patch revision to fix the alignment of the comments?
>
> > + rte_port_out_op_stats_read f_stats; /**< Stats */
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v5 01/13] port: added structures for port stats and config option
2015-06-23 14:30 3% ` Dumitrescu, Cristian
@ 2015-06-23 14:54 0% ` Thomas Monjalon
2015-06-23 15:21 0% ` Dumitrescu, Cristian
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-06-23 14:54 UTC (permalink / raw)
To: Dumitrescu, Cristian; +Cc: dev
2015-06-23 14:30, Dumitrescu, Cristian:
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> > 2015-06-19 11:41, Maciej Gajdzica:
> > > /** Input port interface defining the input port operation */
> > > struct rte_port_in_ops {
> > > rte_port_in_op_create f_create; /**< Create */
> > > rte_port_in_op_free f_free; /**< Free */
> > > rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
> > > + rte_port_in_op_stats_read f_stats; /**< Stats */
> > > };
> >
> > Isn't it breaking an ABI?
>
> This is simply adding a field at the end of the API structure. This structure is instantiated per each port type and its role is very similar to a driver ops structure, for example:
>
> in file "rte_port_ethdev.h": extern struct rte_port_out_ops rte_port_ethdev_writer_ops;
> in file "rte_port_ring.h": extern struct rte_port_out_ops rte_port_ring_writer_nodrop_ops;
>
> Typically, instances of these structures are only referenced through pointers by application code (and other libraries, like librte_pipeline), so code that is not aware of this last field in the structure will still continue to work.
>
> The only case I see possible when code will break is if somebody would create an array of such structures, but I think this is not a realistic scenario. Instances of this structure are infrequent: once per port type in librte_port, and new instances are only created when the user wants to create new port type. Basically, instances of this structure are created in isolation and not in bulk (arrays).
Why wouldn't it be a problem even for single instance?
If the application allocates one with old sizeof and the lib is trying to write
in the new field, there can be a problem, no?
Maybe Neil has an opinion?
> Due to this, I do not see this as breaking the API. I think this is the most it could be done to minimize the effect on the ABI will still adding new functionality. Please let me know what you think.
>
> >
> > > struct rte_port_out_ops {
> > > - rte_port_out_op_create f_create; /**< Create */
> > > - rte_port_out_op_free f_free; /**< Free */
> > > - rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
> > > - rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst)
> > */
> > > - rte_port_out_op_flush f_flush; /**< Flush */
> > > + rte_port_out_op_create f_create; /**< Create */
> > > + rte_port_out_op_free f_free; /**< Free */
> > > + rte_port_out_op_tx f_tx; /**< Packet
> > TX (single packet) */
> > > + rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX
> > (packet burst) */
> > > + rte_port_out_op_flush f_flush; /**< Flush */
> >
> > What is the goal of this change? Breaking the alignment?
>
> Shall we submit a new patch revision to fix the alignment of the comments?
Yes using spaces for alignment would be better.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v5 01/13] port: added structures for port stats and config option
2015-06-23 13:55 3% ` Thomas Monjalon
2015-06-23 14:30 3% ` Dumitrescu, Cristian
@ 2015-06-23 15:16 3% ` Neil Horman
1 sibling, 0 replies; 200+ results
From: Neil Horman @ 2015-06-23 15:16 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Tue, Jun 23, 2015 at 03:55:25PM +0200, Thomas Monjalon wrote:
> 2015-06-19 11:41, Maciej Gajdzica:
> > /** Input port interface defining the input port operation */
> > struct rte_port_in_ops {
> > rte_port_in_op_create f_create; /**< Create */
> > rte_port_in_op_free f_free; /**< Free */
> > rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
> > + rte_port_in_op_stats_read f_stats; /**< Stats */
> > };
>
> Isn't it breaking an ABI?
>
This is an interesting question. Strictly speaking, yes it breaks ABI because
we're adding space, and if older applications statically allocate this
structure, it will be smaller than the port library expects, potentially
scribbling over someone elses memory. That said, I'm not sure this structure is
meant to be accessed outside of the library. If it isn't, then we can feel
comfortable that no one is going to access the data structure from code that was
compiled out of sync with the defining library.
The implication if thats true of course is that we should make this structure
opaque outside of the library with a structure prototype and move its definition
into the library private namespace, but I'm fine with doing that at a later date
if the intention is not to have applications touch this structure.
Regards
Neil
> > struct rte_port_out_ops {
> > - rte_port_out_op_create f_create; /**< Create */
> > - rte_port_out_op_free f_free; /**< Free */
> > - rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
> > - rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
> > - rte_port_out_op_flush f_flush; /**< Flush */
> > + rte_port_out_op_create f_create; /**< Create */
> > + rte_port_out_op_free f_free; /**< Free */
> > + rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
> > + rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
> > + rte_port_out_op_flush f_flush; /**< Flush */
>
> What is the goal of this change? Breaking the alignment?
>
> > + rte_port_out_op_stats_read f_stats; /**< Stats */
>
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v7 0/4] User-space Ethtool
@ 2015-06-23 15:19 0% ` Wang, Liang-min
0 siblings, 0 replies; 200+ results
From: Wang, Liang-min @ 2015-06-23 15:19 UTC (permalink / raw)
To: 'Stephen Hemminger'; +Cc: 'dev@dpdk.org'
Stephen,
From: Wang, Liang-min
Sent: Thursday, June 18, 2015 8:47 AM
To: Stephen Hemminger
Cc: dev@dpdk.org
Subject: RE: [dpdk-dev] [PATCH v7 0/4] User-space Ethtool
>>I agree with having a more complete API, but have some nits to pick.
>>Could the API be more abstract to reduce ABI issues in future?
>Which API? Are you referring to the APIs over ethdev level, or something else?
>More abstract on input/output data structure definition or else? Could you be more specific?
>>I know choosing names is hard, but as a Linux developer ethtool has a very specific meaning to me.
>>This API encompasses things broader than Linux ethtool and has different semantics therefore
>>not sure having something in DPDK with same name is really a good idea.
>>
>>It would be better to call it something else like netdev_?? Or dpnet_??
>Just to clarify the naming suggestion, in this patch, the prefix “ethtool” only appears on example and on this patch description.
>Are you suggesting changing the name over example/l2fwd-ethtool or on this patch description, or may be both?
Have not heard your feedback on last request?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v5 01/13] port: added structures for port stats and config option
2015-06-23 14:54 0% ` Thomas Monjalon
@ 2015-06-23 15:21 0% ` Dumitrescu, Cristian
0 siblings, 0 replies; 200+ results
From: Dumitrescu, Cristian @ 2015-06-23 15:21 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Tuesday, June 23, 2015 3:55 PM
> To: Dumitrescu, Cristian
> Cc: Gajdzica, MaciejX T; dev@dpdk.org; nhorman@tuxdriver.com
> Subject: Re: [dpdk-dev] [PATCH v5 01/13] port: added structures for port
> stats and config option
>
> 2015-06-23 14:30, Dumitrescu, Cristian:
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> > > 2015-06-19 11:41, Maciej Gajdzica:
> > > > /** Input port interface defining the input port operation */
> > > > struct rte_port_in_ops {
> > > > rte_port_in_op_create f_create; /**< Create */
> > > > rte_port_in_op_free f_free; /**< Free */
> > > > rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
> > > > + rte_port_in_op_stats_read f_stats; /**< Stats */
> > > > };
> > >
> > > Isn't it breaking an ABI?
> >
> > This is simply adding a field at the end of the API structure. This structure is
> instantiated per each port type and its role is very similar to a driver ops
> structure, for example:
> >
> > in file "rte_port_ethdev.h": extern struct rte_port_out_ops
> rte_port_ethdev_writer_ops;
> > in file "rte_port_ring.h": extern struct rte_port_out_ops
> rte_port_ring_writer_nodrop_ops;
> >
> > Typically, instances of these structures are only referenced through
> pointers by application code (and other libraries, like librte_pipeline), so code
> that is not aware of this last field in the structure will still continue to work.
> >
> > The only case I see possible when code will break is if somebody would
> create an array of such structures, but I think this is not a realistic scenario.
> Instances of this structure are infrequent: once per port type in librte_port,
> and new instances are only created when the user wants to create new port
> type. Basically, instances of this structure are created in isolation and not in
> bulk (arrays).
>
> Why wouldn't it be a problem even for single instance?
> If the application allocates one with old sizeof and the lib is trying to write
> in the new field, there can be a problem, no?
>
The only case when the application is required to create a new instance of this structure is when the application is defining a new port type (unlikely). In this case, the application using the old structure layout is not aware about the statistics functionality, so it will not invoke it, so the library will not attempt to read the f_stats structure field. Since this field is immediately after the old structure layout, the other fields in the structure are not disturbed, so the application works just fine.
The only case when the application using the old structure layout is impacted is when the position of the old structure fields changes, and this can only happen when an array of such structures is created. To my earlier point, this is not realistic, as instances of this structure are created in isolation (single instance, not array of instances) and are accessed through pointers.
> Maybe Neil has an opinion?
>
> > Due to this, I do not see this as breaking the API. I think this is the most it
> could be done to minimize the effect on the ABI will still adding new
> functionality. Please let me know what you think.
> >
> > >
> > > > struct rte_port_out_ops {
> > > > - rte_port_out_op_create f_create; /**< Create */
> > > > - rte_port_out_op_free f_free; /**< Free */
> > > > - rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
> > > > - rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst)
> > > */
> > > > - rte_port_out_op_flush f_flush; /**< Flush */
> > > > + rte_port_out_op_create f_create; /**< Create */
> > > > + rte_port_out_op_free f_free; /**< Free */
> > > > + rte_port_out_op_tx f_tx; /**< Packet
> > > TX (single packet) */
> > > > + rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX
> > > (packet burst) */
> > > > + rte_port_out_op_flush f_flush; /**< Flush */
> > >
> > > What is the goal of this change? Breaking the alignment?
> >
> > Shall we submit a new patch revision to fix the alignment of the
> comments?
>
> Yes using spaces for alignment would be better.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8 00/18] unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (17 preceding siblings ...)
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 18/18] mbuf: remove old packet type bit masks Helin Zhang
@ 2015-06-23 16:13 0% ` Ananyev, Konstantin
2015-07-02 8:45 0% ` Liu, Yong
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
19 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2015-06-23 16:13 UTC (permalink / raw)
To: Zhang, Helin, dev
> -----Original Message-----
> From: Zhang, Helin
> Sent: Tuesday, June 23, 2015 2:50 AM
> To: dev@dpdk.org
> Cc: Cao, Waterman; Liang, Cunming; Liu, Jijiang; Ananyev, Konstantin; Richardson, Bruce; yongwang@vmware.com;
> olivier.matz@6wind.com; Wu, Jingjing; Zhang, Helin
> Subject: [PATCH v8 00/18] unified packet type
>
> Currently only 6 bits which are stored in ol_flags are used to indicate the
> packet types. This is not enough, as some NIC hardware can recognize quite
> a lot of packet types, e.g i40e hardware can recognize more than 150 packet
> types. Hiding those packet types hides hardware offload capabilities which
> could be quite useful for improving performance and for end users.
> So an unified packet types are needed to support all possible PMDs. A 16
> bits packet_type in mbuf structure can be changed to 32 bits and used for
> this purpose. In addition, all packet types stored in ol_flag field should
> be deleted at all, and 6 bits of ol_flags can be save as the benifit.
>
> Initially, 32 bits of packet_type can be divided into several sub fields to
> indicate different packet type information of a packet. The initial design
> is to divide those bits into fields for L2 types, L3 types, L4 types, tunnel
> types, inner L2 types, inner L3 types and inner L4 types. All PMDs should
> translate the offloaded packet types into these 7 fields of information, for
> user applications.
>
> To avoid breaking ABI compatibility, currently all the code changes for
> unified packet type are disabled at compile time by default. Users can enable
> it manually by defining the macro of RTE_NEXT_ABI. The code changes will be
> valid by default in a future release, and the old version will be deleted
> accordingly, after the ABI change process is done.
>
> Note that this patch set should be integrated after another patch set for
> '[PATCH v3 0/7] support i40e QinQ stripping and insertion', to clearly solve
> the conflict during integration. As both patch sets modified 'struct rte_mbuf',
> and the final layout of the 'struct rte_mbuf' is key to vectorized ixgbe PMD.
>
> v2 changes:
> * Enlarged the packet_type field from 16 bits to 32 bits.
> * Redefined the packet type sub-fields.
> * Updated the 'struct rte_kni_mbuf' for KNI according to the mbuf changes.
> * Used redefined packet types and enlarged packet_type field for all PMDs
> and corresponding applications.
> * Removed changes in bond and its relevant application, as there is no need
> at all according to the recent bond changes.
>
> v3 changes:
> * Put the mbuf layout changes into a single patch.
> * Put vector ixgbe changes right after mbuf changes.
> * Disabled vector ixgbe PMD by default, as mbuf layout changed, and then
> re-enabled it after vector ixgbe PMD updated.
> * Put the definitions of unified packet type into a single patch.
> * Minor bug fixes and enhancements in l3fwd example.
>
> v4 changes:
> * Added detailed description of each packet types.
> * Supported unified packet type of fm10k.
> * Added printing logs of packet types of each received packet for rxonly
> mode in testpmd.
> * Removed several useless code lines which block packet type unification from
> app/test/packet_burst_generator.c.
>
> v5 changes:
> * Added more detailed description for each packet types, together with examples.
> * Rolled back the macro definitions of RX packet flags, for ABI compitability.
>
> v6 changes:
> * Disabled the code changes for unified packet type by default, to
> avoid breaking ABI compatibility.
>
> v7 changes:
> * Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
> * Integrated with patch set for '[PATCH v3 0/7] support i40e QinQ stripping
> and insertion', to clearly solve the conflicts during merging.
>
> v8 changes:
> * Moved the field of 'vlan_tci_outer' in 'struct rte_mbuf' to the end of the 1st
> cache line, to avoid breaking any vectorized PMD storing, as fields of
> 'packet_type, pkt_len, data_len, vlan_tci, rss' should be in an contiguous 128
> bits.
>
> Helin Zhang (18):
> mbuf: redefine packet_type in rte_mbuf
> ixgbe: support unified packet type in vectorized PMD
> mbuf: add definitions of unified packet types
> e1000: replace bit mask based packet type with unified packet type
> ixgbe: replace bit mask based packet type with unified packet type
> i40e: replace bit mask based packet type with unified packet type
> enic: replace bit mask based packet type with unified packet type
> vmxnet3: replace bit mask based packet type with unified packet type
> fm10k: replace bit mask based packet type with unified packet type
> app/test-pipeline: replace bit mask based packet type with unified
> packet type
> app/testpmd: replace bit mask based packet type with unified packet
> type
> app/test: Remove useless code
> examples/ip_fragmentation: replace bit mask based packet type with
> unified packet type
> examples/ip_reassembly: replace bit mask based packet type with
> unified packet type
> examples/l3fwd-acl: replace bit mask based packet type with unified
> packet type
> examples/l3fwd-power: replace bit mask based packet type with unified
> packet type
> examples/l3fwd: replace bit mask based packet type with unified packet
> type
> mbuf: remove old packet type bit masks
>
> app/test-pipeline/pipeline_hash.c | 13 +
> app/test-pmd/csumonly.c | 14 +
> app/test-pmd/rxonly.c | 183 +++++++
> app/test/packet_burst_generator.c | 6 +-
> drivers/net/e1000/igb_rxtx.c | 102 ++++
> drivers/net/enic/enic_main.c | 26 +
> drivers/net/fm10k/fm10k_rxtx.c | 27 ++
> drivers/net/i40e/i40e_rxtx.c | 528 +++++++++++++++++++++
> drivers/net/ixgbe/ixgbe_rxtx.c | 163 +++++++
> drivers/net/ixgbe/ixgbe_rxtx_vec.c | 75 ++-
> drivers/net/vmxnet3/vmxnet3_rxtx.c | 8 +
> examples/ip_fragmentation/main.c | 9 +
> examples/ip_reassembly/main.c | 9 +
> examples/l3fwd-acl/main.c | 29 +-
> examples/l3fwd-power/main.c | 8 +
> examples/l3fwd/main.c | 123 ++++-
> .../linuxapp/eal/include/exec-env/rte_kni_common.h | 6 +
> lib/librte_mbuf/rte_mbuf.c | 4 +
> lib/librte_mbuf/rte_mbuf.h | 517 ++++++++++++++++++++
> 19 files changed, 1837 insertions(+), 13 deletions(-)
>
> --
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> 1.9.3
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH 2/2] ABI: Add some documentation
@ 2015-06-23 19:33 14% ` Neil Horman
2015-06-24 11:21 4% ` Mcnamara, John
` (2 subsequent siblings)
3 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-06-23 19:33 UTC (permalink / raw)
To: dev
People have been asking for ways to use the ABI macros, heres some docs to
clarify their use. Included is:
* An overview of what ABI is
* Details of the ABI deprecation process
* Details of the versioning macros
* Examples of their use
* Details of how to use the ABI validator
Thanks to John Mcnamara, who duplicated much of this effort at Intel while I was
working on it. Much of the introductory material was gathered and cleaned up by
him
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: john.mcnamara@intel.com
CC: thomas.monjalon@6wind.com
---
doc/guides/guidelines/index.rst | 1 +
doc/guides/guidelines/versioning.rst | 456 +++++++++++++++++++++++++++++++++++
2 files changed, 457 insertions(+)
create mode 100644 doc/guides/guidelines/versioning.rst
diff --git a/doc/guides/guidelines/index.rst b/doc/guides/guidelines/index.rst
index b2b0a92..251062e 100644
--- a/doc/guides/guidelines/index.rst
+++ b/doc/guides/guidelines/index.rst
@@ -6,3 +6,4 @@ Guidelines
:numbered:
coding_style
+ versioning
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
new file mode 100644
index 0000000..79af924
--- /dev/null
+++ b/doc/guides/guidelines/versioning.rst
@@ -0,0 +1,456 @@
+Managing ABI updates
+====================
+
+Description
+-----------
+
+This document details some methods for handling ABI management in the DPDK.
+Note this document is not exhaustive, in that C library versioning is flexible
+allowing multiple methods to acheive various goals, but it will provide the user
+with some introductory methods
+
+General Guidelines
+------------------
+
+#. Whenever possible, ABI should be preserved
+#. The addition of symbols is generally not problematic
+#. The modification of symbols can generally be managed with versioning
+#. The removal of symbols generally is an ABI break and requires bumping of the
+ LIBABIVER macro
+
+What is an ABI
+--------------
+
+An ABI (Application Binary Interface) is the set of runtime interfaces exposed
+by a library. It is similar to an API (Application Programming Interface) but
+is the result of compilation. It is also effectively cloned when applications
+link to dynamic libraries. That is to say when an application is compiled to
+link against dynamic libraries, it is assumed that the ABI remains constant
+between the time the application is compiled/linked, and the time that it runs.
+Therefore, in the case of dynamic linking, it is critical that an ABI is
+preserved, or (when modified), done in such a way that the application is unable
+to behave improperly or in an unexpected fashion.
+
+The DPDK ABI policy
+-------------------
+
+ABI versions are set at the time of major release labeling, and the ABI may
+change multiple times, without warning, between the last release label and the
+HEAD label of the git tree.
+
+ABI versions, once released, are available until such time as their
+deprecation has been noted in the Release Notes for at least one major release
+cycle. For example consider the case where the ABI for DPDK 2.0 has been
+shipped and then a decision is made to modify it during the development of
+DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
+release and the modification will be made available in the DPDK 2.2 release.
+
+ABI versions may be deprecated in whole or in part as needed by a given
+update.
+
+Some ABI changes may be too significant to reasonably maintain multiple
+versions. In those cases ABI's may be updated without backward compatibility
+being provided. The requirements for doing so are:
+
+#. At least 3 acknowledgments of the need to do so must be made on the
+ dpdk.org mailing list.
+
+#. A full deprecation cycle, as explained above, must be made to offer
+ downstream consumers sufficient warning of the change.
+
+#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
+ incorporated must be incremented in parallel with the ABI changes
+ themselves.
+
+Note that the above process for ABI deprecation should not be undertaken
+lightly. ABI stability is extremely important for downstream consumers of the
+DPDK, especially when distributed in shared object form. Every effort should
+be made to preserve the ABI whenever possible. The ABI should only be changed
+for significant reasons, such as performance enhancements. ABI breakage due to
+changes such as reorganizing public structure fields for aesthetic or
+readability purposes should be avoided.
+
+Examples of Deprecation Notices
+-------------------------------
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+ to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+ in version 2.0. Backwards compatibility will be maintained for this function
+ until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+ performance reasons. Existing binary applications will have backwards
+ compatibility in release 2.0, while newly built binaries will need to
+ reference the new structure variant ``struct rte_foo2``. Compatibility will
+ be removed in release 2.2, and all applications will require updating and
+ rebuilding to the new structure at that time, which will be renamed to the
+ original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+ upcoming release 2.0 will not contain these changes, but release 2.1 will,
+ and no backwards compatibility is planned due to the extensive nature of
+ these changes. Binaries using this library built prior to version 2.1 will
+ require updating and recompilation.
+
+Versioning Macros
+-----------------
+
+When a symbol is exported from a library to provide an API, it also provides a
+calling convention (ABI) that is embodied in its name, return type and
+arguments. Occasionally that function may need to change to accommodate new
+functionality or behavior. When that occurs, it is desirable to allow for
+backward compatibility for a time with older binaries that are dynamically
+linked to the DPDK.
+
+To support backward compatibility the ``lib/librte_compat/rte_compat.h``
+header file provides macros to use when updating exported functions. These
+macros are used in conjunction with the ``rte_<library>_version.map`` file for
+a given library to allow multiple versions of a symbol to exist in a shared
+library so that older binaries need not be immediately recompiled.
+
+The macros exported are:
+
+* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
+ unversioned symbol ``b`` to the internal function ``b_e``.
+
+
+* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
+ unversioned symbol ``b`` to the internal function ``b_e``.
+
+* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
+ the linker to bind references to symbol ``b`` to the internal symbol
+ ``b_e``.
+
+
+Examples of ABI Macro use
+-------------------------
+
+Updating a public API
+~~~~~~~~~~~~~~~~~~~~~
+
+Assume we have a function as follows
+
+.. code-block:: c
+
+ /*
+ * Create an acl context object for apps to
+ * manipulate
+ */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param)
+ {
+ ...
+ }
+
+
+Assume that struct rte_acl_ctx is a private structure, and that a developer
+wishes to enhance the acl api so that a debugging flag can be enabled on a
+per-context basis. This requires an addition to the structure (which, being
+private, is safe), but it also requries modifying the code as follows
+
+.. code-block:: c
+
+ /*
+ * Create an acl context object for apps to
+ * manipulate
+ */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param, int debug)
+ {
+ ...
+ }
+
+
+Note also that, being a public function, the header file prototype must also be
+changed, as must all the call sites, to reflect the new ABI footprint. We will
+maintain previous ABI versions that are accessible only to previously compiled
+binaries
+
+The addition of a parameter to the function is ABI breaking as the function is
+public, and existing application may use it in its current form. However, the
+compatibility macros in DPDK alow a developer to use symbol versioning so that
+multiple functions can be mapped to the same public symbol based on when an
+application was linked to it. To see how this is done, we start with the
+requisite libraries version map file. Initially the version map file for the
+acl library looks like this
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_create;
+ rte_acl_dump;
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+This file needs to be modified as follows
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_create;
+ rte_acl_dump;
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+ DPDK_2.1 {
+ global:
+ rte_acl_create;
+
+ } DPDK_2.0;
+
+The addition of the new block tells the linker that a new version node is
+available (DPDK_2.1), whcih contains the symbol rte_acl_create, and inherits the
+symbols from the DPDK_2.0 node. This list is directly translated into a list of
+exported symbols when DPDK is compiled as a shared library
+
+Next, we need to specify in the code which function map to the rte_acl_create
+symbol at which versions. First, at the site of the initial symbol definition,
+we need to update the function so that it is uniquely named, and not in conflict
+with the public symbol name
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param)
+ +rte_acl_create_v20(const struct rte_acl_param *param)
+ {
+ size_t sz;
+ struct rte_acl_ctx *ctx;
+ ...
+
+Note that the base name of the symbol was kept in tact, as this is condusive to
+the macros used for versioning symbols. That is our next step, mapping this new
+symbol name to the initial symbol name at version node 2.0. Immediately after
+the function, we add this line of code
+
+.. code-block:: c
+
+ VERSION_SYMBOL(rte_acl_create, _v20, 2.0);VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+Remembering to also add the rte_compat.h header to the requisite c file where
+these changes are being made. The above macro instructs the linker to create a
+new symbol rte_acl_create@DPDK_2.0, which matches the symbol created in older
+builds, but now points to the above newly named function. We have now mapped
+the origional rte_acl_create symbol to the origional function (but with a new
+name)
+
+Next, we need to create the 2.1 version of the symbol. We create a new function
+name, with a different suffix, and implement it appropriately
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+ {
+ struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
+
+ ctx->debug = debug;
+
+ return ctx;
+ }
+
+This code serves as our new API call. Its the same as our old call, but adds
+the new parameter in place. Next we need to map this function to the symbol
+rte_acl_create@DPDK_2.1. To do this, we modify the public prototype of the call
+in the header file, adding the macro there to inform all including applications,
+that on re-link, the default rte_acl_create symbol should point to this
+function. Note that we could do this by simply naming the fuction above
+rte_acl_create, and the linker would chose the most recent version tag to apply
+in the version script, but we can also do this in the header file
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param);
+ +rte_acl_create(const struct rte_acl_param *param, int debug);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
+header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
+version node to it. This method is more explicit and flexible than just
+reimplementing the exact symbol name, and allows for other features (such as
+linking to the old symbol version by default, when the new ABI is to be opt-in
+for a period.
+
+Thats it, on the next shared library rebuild, there will be two versions of
+rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
+and a new DPDK_2.1 version, used by future built applications.
+
+
+Deprecating part of a public API
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Lets assume that you've done the above update, and after a few releases have
+passed you decide you would like to retire the old version of the function.
+After having gone through the ABI deprecation annoucement process, removal is
+easy. Start by removing the symbol from the requisite version map file:
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_dump;
+ - rte_acl_create
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+ DPDK_2.1 {
+ global:
+ rte_acl_create;
+ } DPDK_2.0;
+
+
+Next remove the corresponding versioned export
+.. code-block:: c
+
+ -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+
+Note that the internal function definition could also be removed, but its used
+in our example by the newer version _v21, so we leave it in place. This is a
+coding style choice.
+
+Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
+indicate to applications doing dynamic linking that this is a later, and
+possibly incompatible library version:
+
+.. code-block:: c
+
+ -LIBABIVER := 1
+ +LIBABIVER := 2
+
+Deprecating an entire ABI version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+While removing a symbol from and ABI may be useful, it is often more practical
+to remove an entire version node at once. If a version node completely
+specifies an API, then removing part of it, typically makes it incomplete. In
+those cases it is better to remove the entire node
+
+To do this, start by modifying the version map file, such that all symbols from
+the node to be removed are merged into the next node in the map
+
+In the case of our map above, it would transform to look as follows
+
+.. code-block:: none
+
+ DPDK_2.1 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_dump;
+ rte_acl_create
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+Then any uses of BIND_DEFAULT_SYMBOL that ponited to the old node should be
+updated to point to the new version node in any header files for all affected
+symbols.
+
+.. code-block:: c
+
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+Lastly, any VERSION_SYMBOL macros that point to the old version node should be
+removed, taking care to keep, where neeed old code in place to support newer
+versions of the symbol.
+
+Running the ABI Validator
+-------------------------
+
+The ``scripts`` directory in the DPDK source tree contains a utility program,
+``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
+Compliance Checker
+<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
+
+This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
+utilities which can be installed via a package manager. For example::
+
+ sudo yum install abi-compliance-checker
+ sudo yum install abi-dumper
+
+The syntax of the ``validate-abi.sh`` utility is::
+
+ ./scripts/validate-abi.sh <TAG1> <TAG2> <TARGET>
+
+Where ``TAG1`` and ``TAG2`` are valid git tags on the local repo and target is
+the usual DPDK compilation target.
+
+For example to test the current committed HEAD against a previous release tag
+we could add a temporary tag and run the utility as follows::
+
+ git tag MY_TEMP_TAG
+ ./scripts/validate-abi.sh v2.0.0 MY_TEMP_TAG x86_64-native-linuxapp-gcc
+
+After the validation script completes (it can take a while since it need to
+compile both tags) it will create compatibility reports in the
+``./compat_report`` directory. Listed incompatibilities can be found as
+follows::
+
+ grep -lr Incompatible compat_reports/
--
2.1.0
^ permalink raw reply [relevance 14%]
* Re: [dpdk-dev] [PATCH v2 08/12] mempool: allow config override on element alignment
2015-06-23 0:31 3% ` Ananyev, Konstantin
@ 2015-06-23 20:43 4% ` Cyril Chemparathy
2015-06-23 21:21 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Cyril Chemparathy @ 2015-06-23 20:43 UTC (permalink / raw)
To: Ananyev, Konstantin; +Cc: dev
On Tue, 23 Jun 2015 00:31:06 +0000
"Ananyev, Konstantin" <konstantin.ananyev@intel.com> wrote:
> > +#define RTE_MEMPOOL_ALIGN_MASK (RTE_MEMPOOL_ALIGN - 1)
>
> I am probably a bit late with my comments, but why not make it a
> runtime decision then? I know we can't add a new parameter to
> mempool_xmem_create() without ABI breakage, but we can make some
> global variable for now, that could be setup at init time or
> something similar.
But then, a global variable that is modified by an application _is_ a
part of the ABI, and a bad one at that.
I agree with the desire to make it runtime configurable, but I think we
should do so in the right spirit, with the appropriate interfaces, and
when we're open to changing the ABI accordingly.
Thanks
-- Cyril.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2 08/12] mempool: allow config override on element alignment
2015-06-23 20:43 4% ` Cyril Chemparathy
@ 2015-06-23 21:21 0% ` Ananyev, Konstantin
0 siblings, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2015-06-23 21:21 UTC (permalink / raw)
To: Cyril Chemparathy; +Cc: dev
> -----Original Message-----
> From: Cyril Chemparathy [mailto:cchemparathy@ezchip.com]
> Sent: Tuesday, June 23, 2015 9:43 PM
> To: Ananyev, Konstantin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 08/12] mempool: allow config override on element alignment
>
> On Tue, 23 Jun 2015 00:31:06 +0000
> "Ananyev, Konstantin" <konstantin.ananyev@intel.com> wrote:
>
> > > +#define RTE_MEMPOOL_ALIGN_MASK (RTE_MEMPOOL_ALIGN - 1)
> >
> > I am probably a bit late with my comments, but why not make it a
> > runtime decision then? I know we can't add a new parameter to
> > mempool_xmem_create() without ABI breakage, but we can make some
> > global variable for now, that could be setup at init time or
> > something similar.
>
> But then, a global variable that is modified by an application _is_ a
> part of the ABI, and a bad one at that.
>
> I agree with the desire to make it runtime configurable, but I think we
> should do so in the right spirit, with the appropriate interfaces, and
> when we're open to changing the ABI accordingly.
Ok, let's wait till next release then.
Konstantin
>
> Thanks
> -- Cyril.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 2/2] ABI: Add some documentation
2015-06-23 19:33 14% ` [dpdk-dev] [PATCH 2/2] ABI: Add some documentation Neil Horman
@ 2015-06-24 11:21 4% ` Mcnamara, John
0 siblings, 0 replies; 200+ results
From: Mcnamara, John @ 2015-06-24 11:21 UTC (permalink / raw)
To: Neil Horman, dev
> -----Original Message-----
> From: Neil Horman [mailto:nhorman@tuxdriver.com]
> Sent: Tuesday, June 23, 2015 8:34 PM
> To: dev@dpdk.org
> Cc: Neil Horman; Mcnamara, John; thomas.monjalon@6wind.com
> Subject: [PATCH 2/2] ABI: Add some documentation
>
> People have been asking for ways to use the ABI macros, heres some docs to
> clarify their use. Included is:
Hi,
Thanks for this.
There are a few minor comments on the RST structure below.
Also, there is a conflict in the doc/guides/guidelines/index.rst file with an addition that just got merged. I just needs a rebase.
> +This file needs to be modified as follows
> +
> +.. code-block:: none
> +
> + DPDK_2.0 {
> + global:
> +
> + rte_acl_add_rules;
> + rte_acl_build;
> + rte_acl_classify;
> + rte_acl_classify_alg;
> + rte_acl_classify_scalar;
> + rte_acl_create;
> + rte_acl_dump;
> + rte_acl_find_existing;
> + rte_acl_free;
> + rte_acl_ipv4vlan_add_rules;
> + rte_acl_ipv4vlan_build;
> + rte_acl_list_dump;
> + rte_acl_reset;
> + rte_acl_reset_rules;
> + rte_acl_set_ctx_classify;
> +
> + local: *;
> + };
> +
> + DPDK_2.1 {
> + global:
> + rte_acl_create;
> +
> + } DPDK_2.0;
The last 7 lines of this verbatim section should be indented to the same level as the rest of the section. In general the code blocks should be indented at least 3 spaces to keep the various RST converters happy. That applies in a few places.
> +Note that the base name of the symbol was kept in tact, as this is
> +condusive to the macros used for versioning symbols. That is our next
> +step, mapping this new symbol name to the initial symbol name at
> +version node 2.0. Immediately after the function, we add this line of
> +code
> +
> +.. code-block:: c
> +
> + VERSION_SYMBOL(rte_acl_create, _v20, 2.0);VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
The is a duplicate macro here.
> +
> +Remembering to also add the rte_compat.h header to the requisite c file
> +where these changes are being made. The above macro instructs the
> +linker to create a new symbol rte_acl_create@DPDK_2.0, which matches
Could you enclose the symbol in RST backquotes ``rte_acl_create@DPDK_2.0`` since some of the renderers treat this as an email address! There is another one a few paragraphs down.
> +the symbol created in older builds, but now points to the above newly
> +named function. We have now mapped the origional rte_acl_create symbol
> +to the origional function
There are a few minor typos here and there.
> + };
> +
> + DPDK_2.1 {
> + global:
> + rte_acl_create;
> + } DPDK_2.0;
Same comment as above on indentation.
John.
--
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
@ 2015-06-24 18:34 14% ` Neil Horman
2015-06-24 21:09 9% ` Thomas Monjalon
2015-06-25 7:19 4% ` Zhang, Helin
0 siblings, 2 replies; 200+ results
From: Neil Horman @ 2015-06-24 18:34 UTC (permalink / raw)
To: dev
People have been asking for ways to use the ABI macros, heres some docs to
clarify their use. Included is:
* An overview of what ABI is
* Details of the ABI deprecation process
* Details of the versioning macros
* Examples of their use
* Details of how to use the ABI validator
Thanks to John Mcnamara, who duplicated much of this effort at Intel while I was
working on it. Much of the introductory material was gathered and cleaned up by
him
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: john.mcnamara@intel.com
CC: thomas.monjalon@6wind.com
Change notes:
v2)
* Fixed RST indentations and spelling errors
* Rebased to upstream to fix index.rst conflict
---
doc/guides/guidelines/index.rst | 1 +
doc/guides/guidelines/versioning.rst | 456 +++++++++++++++++++++++++++++++++++
2 files changed, 457 insertions(+)
create mode 100644 doc/guides/guidelines/versioning.rst
diff --git a/doc/guides/guidelines/index.rst b/doc/guides/guidelines/index.rst
index 0ee9ab3..bfb9fa3 100644
--- a/doc/guides/guidelines/index.rst
+++ b/doc/guides/guidelines/index.rst
@@ -7,3 +7,4 @@ Guidelines
coding_style
design
+ versioning
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
new file mode 100644
index 0000000..2aef526
--- /dev/null
+++ b/doc/guides/guidelines/versioning.rst
@@ -0,0 +1,456 @@
+Managing ABI updates
+====================
+
+Description
+-----------
+
+This document details some methods for handling ABI management in the DPDK.
+Note this document is not exhaustive, in that C library versioning is flexible
+allowing multiple methods to achieve various goals, but it will provide the user
+with some introductory methods
+
+General Guidelines
+------------------
+
+#. Whenever possible, ABI should be preserved
+#. The addition of symbols is generally not problematic
+#. The modification of symbols can generally be managed with versioning
+#. The removal of symbols generally is an ABI break and requires bumping of the
+ LIBABIVER macro
+
+What is an ABI
+--------------
+
+An ABI (Application Binary Interface) is the set of runtime interfaces exposed
+by a library. It is similar to an API (Application Programming Interface) but
+is the result of compilation. It is also effectively cloned when applications
+link to dynamic libraries. That is to say when an application is compiled to
+link against dynamic libraries, it is assumed that the ABI remains constant
+between the time the application is compiled/linked, and the time that it runs.
+Therefore, in the case of dynamic linking, it is critical that an ABI is
+preserved, or (when modified), done in such a way that the application is unable
+to behave improperly or in an unexpected fashion.
+
+The DPDK ABI policy
+-------------------
+
+ABI versions are set at the time of major release labeling, and the ABI may
+change multiple times, without warning, between the last release label and the
+HEAD label of the git tree.
+
+ABI versions, once released, are available until such time as their
+deprecation has been noted in the Release Notes for at least one major release
+cycle. For example consider the case where the ABI for DPDK 2.0 has been
+shipped and then a decision is made to modify it during the development of
+DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
+release and the modification will be made available in the DPDK 2.2 release.
+
+ABI versions may be deprecated in whole or in part as needed by a given
+update.
+
+Some ABI changes may be too significant to reasonably maintain multiple
+versions. In those cases ABI's may be updated without backward compatibility
+being provided. The requirements for doing so are:
+
+#. At least 3 acknowledgments of the need to do so must be made on the
+ dpdk.org mailing list.
+
+#. A full deprecation cycle, as explained above, must be made to offer
+ downstream consumers sufficient warning of the change.
+
+#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
+ incorporated must be incremented in parallel with the ABI changes
+ themselves.
+
+Note that the above process for ABI deprecation should not be undertaken
+lightly. ABI stability is extremely important for downstream consumers of the
+DPDK, especially when distributed in shared object form. Every effort should
+be made to preserve the ABI whenever possible. The ABI should only be changed
+for significant reasons, such as performance enhancements. ABI breakage due to
+changes such as reorganizing public structure fields for aesthetic or
+readability purposes should be avoided.
+
+Examples of Deprecation Notices
+-------------------------------
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+ to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+ in version 2.0. Backwards compatibility will be maintained for this function
+ until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+ performance reasons. Existing binary applications will have backwards
+ compatibility in release 2.0, while newly built binaries will need to
+ reference the new structure variant ``struct rte_foo2``. Compatibility will
+ be removed in release 2.2, and all applications will require updating and
+ rebuilding to the new structure at that time, which will be renamed to the
+ original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+ upcoming release 2.0 will not contain these changes, but release 2.1 will,
+ and no backwards compatibility is planned due to the extensive nature of
+ these changes. Binaries using this library built prior to version 2.1 will
+ require updating and recompilation.
+
+Versioning Macros
+-----------------
+
+When a symbol is exported from a library to provide an API, it also provides a
+calling convention (ABI) that is embodied in its name, return type and
+arguments. Occasionally that function may need to change to accommodate new
+functionality or behavior. When that occurs, it is desirable to allow for
+backward compatibility for a time with older binaries that are dynamically
+linked to the DPDK.
+
+To support backward compatibility the ``lib/librte_compat/rte_compat.h``
+header file provides macros to use when updating exported functions. These
+macros are used in conjunction with the ``rte_<library>_version.map`` file for
+a given library to allow multiple versions of a symbol to exist in a shared
+library so that older binaries need not be immediately recompiled.
+
+The macros exported are:
+
+* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
+ unversioned symbol ``b`` to the internal function ``b_e``.
+
+
+* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
+ unversioned symbol ``b`` to the internal function ``b_e``.
+
+* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
+ the linker to bind references to symbol ``b`` to the internal symbol
+ ``b_e``.
+
+
+Examples of ABI Macro use
+-------------------------
+
+Updating a public API
+~~~~~~~~~~~~~~~~~~~~~
+
+Assume we have a function as follows
+
+.. code-block:: c
+
+ /*
+ * Create an acl context object for apps to
+ * manipulate
+ */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param)
+ {
+ ...
+ }
+
+
+Assume that struct rte_acl_ctx is a private structure, and that a developer
+wishes to enhance the acl api so that a debugging flag can be enabled on a
+per-context basis. This requires an addition to the structure (which, being
+private, is safe), but it also requires modifying the code as follows
+
+.. code-block:: c
+
+ /*
+ * Create an acl context object for apps to
+ * manipulate
+ */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param, int debug)
+ {
+ ...
+ }
+
+
+Note also that, being a public function, the header file prototype must also be
+changed, as must all the call sites, to reflect the new ABI footprint. We will
+maintain previous ABI versions that are accessible only to previously compiled
+binaries
+
+The addition of a parameter to the function is ABI breaking as the function is
+public, and existing application may use it in its current form. However, the
+compatibility macros in DPDK allow a developer to use symbol versioning so that
+multiple functions can be mapped to the same public symbol based on when an
+application was linked to it. To see how this is done, we start with the
+requisite libraries version map file. Initially the version map file for the
+acl library looks like this
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_create;
+ rte_acl_dump;
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+This file needs to be modified as follows
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_create;
+ rte_acl_dump;
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+ DPDK_2.1 {
+ global:
+ rte_acl_create;
+
+ } DPDK_2.0;
+
+The addition of the new block tells the linker that a new version node is
+available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
+symbols from the DPDK_2.0 node. This list is directly translated into a list of
+exported symbols when DPDK is compiled as a shared library
+
+Next, we need to specify in the code which function map to the rte_acl_create
+symbol at which versions. First, at the site of the initial symbol definition,
+we need to update the function so that it is uniquely named, and not in conflict
+with the public symbol name
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param)
+ +rte_acl_create_v20(const struct rte_acl_param *param)
+ {
+ size_t sz;
+ struct rte_acl_ctx *ctx;
+ ...
+
+Note that the base name of the symbol was kept in tact, as this is condusive to
+the macros used for versioning symbols. That is our next step, mapping this new
+symbol name to the initial symbol name at version node 2.0. Immediately after
+the function, we add this line of code
+
+.. code-block:: c
+
+ VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+Remembering to also add the rte_compat.h header to the requisite c file where
+these changes are being made. The above macro instructs the linker to create a
+new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
+builds, but now points to the above newly named function. We have now mapped
+the original rte_acl_create symbol to the original function (but with a new
+name)
+
+Next, we need to create the 2.1 version of the symbol. We create a new function
+name, with a different suffix, and implement it appropriately
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+ {
+ struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
+
+ ctx->debug = debug;
+
+ return ctx;
+ }
+
+This code serves as our new API call. Its the same as our old call, but adds
+the new parameter in place. Next we need to map this function to the symbol
+``rte_acl_create@DPDK_2.1``. To do this, we modify the public prototype of the call
+in the header file, adding the macro there to inform all including applications,
+that on re-link, the default rte_acl_create symbol should point to this
+function. Note that we could do this by simply naming the function above
+rte_acl_create, and the linker would chose the most recent version tag to apply
+in the version script, but we can also do this in the header file
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param);
+ +rte_acl_create(const struct rte_acl_param *param, int debug);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
+header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
+version node to it. This method is more explicit and flexible than just
+re-implementing the exact symbol name, and allows for other features (such as
+linking to the old symbol version by default, when the new ABI is to be opt-in
+for a period.
+
+That's it, on the next shared library rebuild, there will be two versions of
+rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
+and a new DPDK_2.1 version, used by future built applications.
+
+
+Deprecating part of a public API
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Lets assume that you've done the above update, and after a few releases have
+passed you decide you would like to retire the old version of the function.
+After having gone through the ABI deprecation announcement process, removal is
+easy. Start by removing the symbol from the requisite version map file:
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_dump;
+ - rte_acl_create
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+ DPDK_2.1 {
+ global:
+ rte_acl_create;
+ } DPDK_2.0;
+
+
+Next remove the corresponding versioned export
+.. code-block:: c
+
+ -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+
+Note that the internal function definition could also be removed, but its used
+in our example by the newer version _v21, so we leave it in place. This is a
+coding style choice.
+
+Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
+indicate to applications doing dynamic linking that this is a later, and
+possibly incompatible library version:
+
+.. code-block:: c
+
+ -LIBABIVER := 1
+ +LIBABIVER := 2
+
+Deprecating an entire ABI version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+While removing a symbol from and ABI may be useful, it is often more practical
+to remove an entire version node at once. If a version node completely
+specifies an API, then removing part of it, typically makes it incomplete. In
+those cases it is better to remove the entire node
+
+To do this, start by modifying the version map file, such that all symbols from
+the node to be removed are merged into the next node in the map
+
+In the case of our map above, it would transform to look as follows
+
+.. code-block:: none
+
+ DPDK_2.1 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_dump;
+ rte_acl_create
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+Then any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be
+updated to point to the new version node in any header files for all affected
+symbols.
+
+.. code-block:: c
+
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+Lastly, any VERSION_SYMBOL macros that point to the old version node should be
+removed, taking care to keep, where need old code in place to support newer
+versions of the symbol.
+
+Running the ABI Validator
+-------------------------
+
+The ``scripts`` directory in the DPDK source tree contains a utility program,
+``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
+Compliance Checker
+<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
+
+This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
+utilities which can be installed via a package manager. For example::
+
+ sudo yum install abi-compliance-checker
+ sudo yum install abi-dumper
+
+The syntax of the ``validate-abi.sh`` utility is::
+
+ ./scripts/validate-abi.sh <TAG1> <TAG2> <TARGET>
+
+Where ``TAG1`` and ``TAG2`` are valid git tags on the local repo and target is
+the usual DPDK compilation target.
+
+For example to test the current committed HEAD against a previous release tag
+we could add a temporary tag and run the utility as follows::
+
+ git tag MY_TEMP_TAG
+ ./scripts/validate-abi.sh v2.0.0 MY_TEMP_TAG x86_64-native-linuxapp-gcc
+
+After the validation script completes (it can take a while since it need to
+compile both tags) it will create compatibility reports in the
+``./compat_report`` directory. Listed incompatibilities can be found as
+follows::
+
+ grep -lr Incompatible compat_reports/
--
2.1.0
^ permalink raw reply [relevance 14%]
* Re: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
2015-06-24 18:34 14% ` [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation Neil Horman
@ 2015-06-24 21:09 9% ` Thomas Monjalon
2015-06-25 11:35 9% ` Neil Horman
2015-06-25 7:19 4% ` Zhang, Helin
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-06-24 21:09 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-24 14:34, Neil Horman:
> +Some ABI changes may be too significant to reasonably maintain multiple
> +versions. In those cases ABI's may be updated without backward compatibility
> +being provided. The requirements for doing so are:
> +
> +#. At least 3 acknowledgments of the need to do so must be made on the
> + dpdk.org mailing list.
> +
> +#. A full deprecation cycle, as explained above, must be made to offer
> + downstream consumers sufficient warning of the change.
> +
> +#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
> + incorporated must be incremented in parallel with the ABI changes
> + themselves.
The proposal was to provide the old and the new ABI in the same source code
during the deprecation cycle. The old ABI would be the default and people
can build the new one by enabling the NEXT_ABI config option.
So the migration to the new ABI is smoother.
[...]
> +The macros exported are:
> +
> +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
> + unversioned symbol ``b`` to the internal function ``b_e``.
The definition is the same as BASE_SYMBOL.
> +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
> + unversioned symbol ``b`` to the internal function ``b_e``.
[...]
> + DPDK_2.0 {
> + global:
> +
> + rte_acl_add_rules;
> + rte_acl_build;
> + rte_acl_classify;
> + rte_acl_classify_alg;
> + rte_acl_classify_scalar;
> + rte_acl_create;
So it's declared twice, right?
I think it should be explicit.
> + rte_acl_dump;
> + rte_acl_find_existing;
> + rte_acl_free;
> + rte_acl_ipv4vlan_add_rules;
> + rte_acl_ipv4vlan_build;
> + rte_acl_list_dump;
> + rte_acl_reset;
> + rte_acl_reset_rules;
> + rte_acl_set_ctx_classify;
> +
> + local: *;
> + };
> +
> + DPDK_2.1 {
> + global:
> + rte_acl_create;
> +
> + } DPDK_2.0;
[...]
> +Note that the base name of the symbol was kept in tact, as this is condusive to
s/in tact/intact/?
[...]
> +the macros used for versioning symbols. That is our next step, mapping this new
> +symbol name to the initial symbol name at version node 2.0. Immediately after
> +the function, we add this line of code
> +
> +.. code-block:: c
> +
> + VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
Can it be declared before the function?
[...]
> +Remembering to also add the rte_compat.h header to the requisite c file where
> +these changes are being made. The above macro instructs the linker to create a
> +new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
> +builds, but now points to the above newly named function. We have now mapped
> +the original rte_acl_create symbol to the original function (but with a new
> +name)
Could we use VERSION_SYMBOL(rte_acl_create, , 2.0);
when introducing the function in DPDK 2.0 (before any ABI breakage)?
It could help to generate the .map file.
When do we need to use BASE_SYMBOL?
[...]
> +This code serves as our new API call. Its the same as our old call, but adds
> +the new parameter in place. Next we need to map this function to the symbol
> +``rte_acl_create@DPDK_2.1``. To do this, we modify the public prototype of the call
> +in the header file, adding the macro there to inform all including applications,
> +that on re-link, the default rte_acl_create symbol should point to this
> +function. Note that we could do this by simply naming the function above
> +rte_acl_create, and the linker would chose the most recent version tag to apply
> +in the version script, but we can also do this in the header file
> +
> +.. code-block:: c
> +
> + struct rte_acl_ctx *
> + -rte_acl_create(const struct rte_acl_param *param);
> + +rte_acl_create(const struct rte_acl_param *param, int debug);
> + +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
Will it work with static library?
> +Next remove the corresponding versioned export
> +.. code-block:: c
> +
> + -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
> +
> +
> +Note that the internal function definition could also be removed, but its used
> +in our example by the newer version _v21, so we leave it in place. This is a
> +coding style choice.
> +
> +Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
> +indicate to applications doing dynamic linking that this is a later, and
> +possibly incompatible library version:
> +
> +.. code-block:: c
> +
> + -LIBABIVER := 1
> + +LIBABIVER := 2
Very well explained, thanks.
[...]
> + rte_acl_add_rules;
> + rte_acl_build;
> + rte_acl_classify;
> + rte_acl_classify_alg;
> + rte_acl_classify_scalar;
> + rte_acl_dump;
> + rte_acl_create
Not in alphabetical order.
As you copy a part of abi.rst, it should be removed from the original doc.
Thanks Neil
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
2015-06-24 18:34 14% ` [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation Neil Horman
2015-06-24 21:09 9% ` Thomas Monjalon
@ 2015-06-25 7:19 4% ` Zhang, Helin
2015-06-25 7:42 4% ` Gonzalez Monroy, Sergio
2015-06-25 12:25 4% ` Neil Horman
1 sibling, 2 replies; 200+ results
From: Zhang, Helin @ 2015-06-25 7:19 UTC (permalink / raw)
To: Neil Horman, dev
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Neil Horman
> Sent: Thursday, June 25, 2015 2:35 AM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
>
> People have been asking for ways to use the ABI macros, heres some docs to
> clarify their use. Included is:
>
> * An overview of what ABI is
> * Details of the ABI deprecation process
> * Details of the versioning macros
> * Examples of their use
> * Details of how to use the ABI validator
>
> Thanks to John Mcnamara, who duplicated much of this effort at Intel while I was
> working on it. Much of the introductory material was gathered and cleaned up
> by him
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: john.mcnamara@intel.com
> CC: thomas.monjalon@6wind.com
>
> Change notes:
>
> v2)
> * Fixed RST indentations and spelling errors
> * Rebased to upstream to fix index.rst conflict
> ---
> doc/guides/guidelines/index.rst | 1 +
> doc/guides/guidelines/versioning.rst | 456
> +++++++++++++++++++++++++++++++++++
> 2 files changed, 457 insertions(+)
> create mode 100644 doc/guides/guidelines/versioning.rst
>
> diff --git a/doc/guides/guidelines/index.rst b/doc/guides/guidelines/index.rst
> index 0ee9ab3..bfb9fa3 100644
> --- a/doc/guides/guidelines/index.rst
> +++ b/doc/guides/guidelines/index.rst
> @@ -7,3 +7,4 @@ Guidelines
>
> coding_style
> design
> + versioning
> diff --git a/doc/guides/guidelines/versioning.rst
> b/doc/guides/guidelines/versioning.rst
> new file mode 100644
> index 0000000..2aef526
> --- /dev/null
> +++ b/doc/guides/guidelines/versioning.rst
> @@ -0,0 +1,456 @@
> +Managing ABI updates
> +====================
> +
> +Description
> +-----------
> +
> +This document details some methods for handling ABI management in the
> DPDK.
> +Note this document is not exhaustive, in that C library versioning is
> +flexible allowing multiple methods to achieve various goals, but it
> +will provide the user with some introductory methods
> +
> +General Guidelines
> +------------------
> +
> +#. Whenever possible, ABI should be preserved #. The addition of
> +symbols is generally not problematic #. The modification of symbols can
> +generally be managed with versioning #. The removal of symbols
> +generally is an ABI break and requires bumping of the
> + LIBABIVER macro
> +
> +What is an ABI
> +--------------
> +
> +An ABI (Application Binary Interface) is the set of runtime interfaces
> +exposed by a library. It is similar to an API (Application Programming
> +Interface) but is the result of compilation. It is also effectively
> +cloned when applications link to dynamic libraries. That is to say
> +when an application is compiled to link against dynamic libraries, it
> +is assumed that the ABI remains constant between the time the application is
> compiled/linked, and the time that it runs.
> +Therefore, in the case of dynamic linking, it is critical that an ABI
> +is preserved, or (when modified), done in such a way that the
> +application is unable to behave improperly or in an unexpected fashion.
> +
> +The DPDK ABI policy
> +-------------------
> +
> +ABI versions are set at the time of major release labeling, and the ABI
> +may change multiple times, without warning, between the last release
> +label and the HEAD label of the git tree.
> +
> +ABI versions, once released, are available until such time as their
> +deprecation has been noted in the Release Notes for at least one major
> +release cycle. For example consider the case where the ABI for DPDK 2.0
> +has been shipped and then a decision is made to modify it during the
> +development of DPDK 2.1. The decision will be recorded in the Release
> +Notes for the DPDK 2.1 release and the modification will be made available in
> the DPDK 2.2 release.
> +
> +ABI versions may be deprecated in whole or in part as needed by a given
> +update.
> +
> +Some ABI changes may be too significant to reasonably maintain multiple
> +versions. In those cases ABI's may be updated without backward
> +compatibility being provided. The requirements for doing so are:
> +
> +#. At least 3 acknowledgments of the need to do so must be made on the
> + dpdk.org mailing list.
> +
> +#. A full deprecation cycle, as explained above, must be made to offer
> + downstream consumers sufficient warning of the change.
> +
> +#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
> + incorporated must be incremented in parallel with the ABI changes
> + themselves.
> +
> +Note that the above process for ABI deprecation should not be
> +undertaken lightly. ABI stability is extremely important for downstream
> +consumers of the DPDK, especially when distributed in shared object
> +form. Every effort should be made to preserve the ABI whenever
> +possible. The ABI should only be changed for significant reasons, such
> +as performance enhancements. ABI breakage due to changes such as
> +reorganizing public structure fields for aesthetic or readability purposes should
> be avoided.
> +
> +Examples of Deprecation Notices
> +-------------------------------
> +
> +The following are some examples of ABI deprecation notices which would
> +be added to the Release Notes:
> +
> +* The Macro ``#RTE_FOO`` is deprecated and will be removed with version
> +2.0,
> + to be replaced with the inline function ``rte_foo()``.
> +
> +* The function ``rte_mbuf_grok()`` has been updated to include a new
> +parameter
> + in version 2.0. Backwards compatibility will be maintained for this
> +function
> + until the release of version 2.1
> +
> +* The members of ``struct rte_foo`` have been reorganized in release
> +2.0 for
> + performance reasons. Existing binary applications will have backwards
> + compatibility in release 2.0, while newly built binaries will need to
> + reference the new structure variant ``struct rte_foo2``.
> +Compatibility will
> + be removed in release 2.2, and all applications will require updating
> +and
> + rebuilding to the new structure at that time, which will be renamed
> +to the
> + original ``struct rte_foo``.
> +
> +* Significant ABI changes are planned for the ``librte_dostuff``
> +library. The
> + upcoming release 2.0 will not contain these changes, but release 2.1
> +will,
> + and no backwards compatibility is planned due to the extensive nature
> +of
> + these changes. Binaries using this library built prior to version 2.1
> +will
> + require updating and recompilation.
> +
> +Versioning Macros
> +-----------------
> +
> +When a symbol is exported from a library to provide an API, it also
> +provides a calling convention (ABI) that is embodied in its name,
> +return type and arguments. Occasionally that function may need to
> +change to accommodate new functionality or behavior. When that occurs,
> +it is desirable to allow for backward compatibility for a time with
> +older binaries that are dynamically linked to the DPDK.
> +
> +To support backward compatibility the
> +``lib/librte_compat/rte_compat.h``
> +header file provides macros to use when updating exported functions.
> +These macros are used in conjunction with the
> +``rte_<library>_version.map`` file for a given library to allow
> +multiple versions of a symbol to exist in a shared library so that older binaries
> need not be immediately recompiled.
> +
> +The macros exported are:
> +
> +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry
> +binding
> + unversioned symbol ``b`` to the internal function ``b_e``.
> +
> +
> +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
> + unversioned symbol ``b`` to the internal function ``b_e``.
> +
> +* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry
> +instructing
> + the linker to bind references to symbol ``b`` to the internal symbol
> + ``b_e``.
> +
> +
> +Examples of ABI Macro use
> +-------------------------
> +
> +Updating a public API
> +~~~~~~~~~~~~~~~~~~~~~
> +
> +Assume we have a function as follows
> +
> +.. code-block:: c
> +
> + /*
> + * Create an acl context object for apps to
> + * manipulate
> + */
> + struct rte_acl_ctx *
> + rte_acl_create(const struct rte_acl_param *param) {
> + ...
> + }
> +
> +
> +Assume that struct rte_acl_ctx is a private structure, and that a
> +developer wishes to enhance the acl api so that a debugging flag can be
> +enabled on a per-context basis. This requires an addition to the
> +structure (which, being private, is safe), but it also requires
> +modifying the code as follows
> +
> +.. code-block:: c
> +
> + /*
> + * Create an acl context object for apps to
> + * manipulate
> + */
> + struct rte_acl_ctx *
> + rte_acl_create(const struct rte_acl_param *param, int debug) {
> + ...
> + }
> +
> +
> +Note also that, being a public function, the header file prototype must
> +also be changed, as must all the call sites, to reflect the new ABI
> +footprint. We will maintain previous ABI versions that are accessible
> +only to previously compiled binaries
> +
> +The addition of a parameter to the function is ABI breaking as the
> +function is public, and existing application may use it in its current
> +form. However, the compatibility macros in DPDK allow a developer to
> +use symbol versioning so that multiple functions can be mapped to the
> +same public symbol based on when an application was linked to it. To
> +see how this is done, we start with the requisite libraries version map
> +file. Initially the version map file for the acl library looks like
> +this
> +
> +.. code-block:: none
> +
> + DPDK_2.0 {
> + global:
> +
> + rte_acl_add_rules;
> + rte_acl_build;
> + rte_acl_classify;
> + rte_acl_classify_alg;
> + rte_acl_classify_scalar;
> + rte_acl_create;
> + rte_acl_dump;
> + rte_acl_find_existing;
> + rte_acl_free;
> + rte_acl_ipv4vlan_add_rules;
> + rte_acl_ipv4vlan_build;
> + rte_acl_list_dump;
> + rte_acl_reset;
> + rte_acl_reset_rules;
> + rte_acl_set_ctx_classify;
> +
> + local: *;
> + };
> +
> +This file needs to be modified as follows
> +
> +.. code-block:: none
> +
> + DPDK_2.0 {
> + global:
> +
> + rte_acl_add_rules;
> + rte_acl_build;
> + rte_acl_classify;
> + rte_acl_classify_alg;
> + rte_acl_classify_scalar;
> + rte_acl_create;
> + rte_acl_dump;
> + rte_acl_find_existing;
> + rte_acl_free;
> + rte_acl_ipv4vlan_add_rules;
> + rte_acl_ipv4vlan_build;
> + rte_acl_list_dump;
> + rte_acl_reset;
> + rte_acl_reset_rules;
> + rte_acl_set_ctx_classify;
> +
> + local: *;
> + };
> +
> + DPDK_2.1 {
> + global:
> + rte_acl_create;
One question, does it need a line of "local: *;", like it did in
librte_ether/rte_ether_version.map?
> +
> + } DPDK_2.0;
> +
> +The addition of the new block tells the linker that a new version node
> +is available (DPDK_2.1), which contains the symbol rte_acl_create, and
> +inherits the symbols from the DPDK_2.0 node. This list is directly
> +translated into a list of exported symbols when DPDK is compiled as a
> +shared library
> +
> +Next, we need to specify in the code which function map to the
> +rte_acl_create symbol at which versions. First, at the site of the
> +initial symbol definition, we need to update the function so that it is
> +uniquely named, and not in conflict with the public symbol name
> +
> +.. code-block:: c
> +
> + struct rte_acl_ctx *
> + -rte_acl_create(const struct rte_acl_param *param)
> + +rte_acl_create_v20(const struct rte_acl_param *param)
> + {
> + size_t sz;
> + struct rte_acl_ctx *ctx;
> + ...
> +
> +Note that the base name of the symbol was kept in tact, as this is
> +condusive to the macros used for versioning symbols. That is our next
> +step, mapping this new symbol name to the initial symbol name at
> +version node 2.0. Immediately after the function, we add this line of
> +code
> +
> +.. code-block:: c
> +
> + VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
> +
> +Remembering to also add the rte_compat.h header to the requisite c file
> +where these changes are being made. The above macro instructs the
> +linker to create a new symbol ``rte_acl_create@DPDK_2.0``, which
> +matches the symbol created in older builds, but now points to the above
> +newly named function. We have now mapped the original rte_acl_create
> +symbol to the original function (but with a new
> +name)
> +
> +Next, we need to create the 2.1 version of the symbol. We create a new
> +function name, with a different suffix, and implement it appropriately
> +
> +.. code-block:: c
> +
> + struct rte_acl_ctx *
> + rte_acl_create_v21(const struct rte_acl_param *param, int debug);
> + {
> + struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
> +
> + ctx->debug = debug;
> +
> + return ctx;
> + }
> +
> +This code serves as our new API call. Its the same as our old call,
> +but adds the new parameter in place. Next we need to map this function
> +to the symbol ``rte_acl_create@DPDK_2.1``. To do this, we modify the
> +public prototype of the call in the header file, adding the macro there
> +to inform all including applications, that on re-link, the default
> +rte_acl_create symbol should point to this function. Note that we
> +could do this by simply naming the function above rte_acl_create, and
> +the linker would chose the most recent version tag to apply in the
> +version script, but we can also do this in the header file
> +
> +.. code-block:: c
> +
> + struct rte_acl_ctx *
> + -rte_acl_create(const struct rte_acl_param *param);
> + +rte_acl_create(const struct rte_acl_param *param, int debug);
> + +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
> +
> +The BIND_DEFAULT_SYMBOL macro explicitly tells applications that
> +include this header, to link to the rte_acl_create_v21 function and
> +apply the DPDK_2.1 version node to it. This method is more explicit
> +and flexible than just re-implementing the exact symbol name, and
> +allows for other features (such as linking to the old symbol version by
> +default, when the new ABI is to be opt-in for a period.
> +
> +That's it, on the next shared library rebuild, there will be two
> +versions of rte_acl_create, an old DPDK_2.0 version, used by previously
> +built applications, and a new DPDK_2.1 version, used by future built
> applications.
> +
> +
> +Deprecating part of a public API
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Lets assume that you've done the above update, and after a few releases
> +have passed you decide you would like to retire the old version of the function.
> +After having gone through the ABI deprecation announcement process,
> +removal is easy. Start by removing the symbol from the requisite version map
> file:
> +
> +.. code-block:: none
> +
> + DPDK_2.0 {
> + global:
> +
> + rte_acl_add_rules;
> + rte_acl_build;
> + rte_acl_classify;
> + rte_acl_classify_alg;
> + rte_acl_classify_scalar;
> + rte_acl_dump;
> + - rte_acl_create
> + rte_acl_find_existing;
> + rte_acl_free;
> + rte_acl_ipv4vlan_add_rules;
> + rte_acl_ipv4vlan_build;
> + rte_acl_list_dump;
> + rte_acl_reset;
> + rte_acl_reset_rules;
> + rte_acl_set_ctx_classify;
> +
> + local: *;
> + };
> +
> + DPDK_2.1 {
> + global:
> + rte_acl_create;
> + } DPDK_2.0;
> +
> +
> +Next remove the corresponding versioned export .. code-block:: c
> +
> + -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
> +
> +
> +Note that the internal function definition could also be removed, but
> +its used in our example by the newer version _v21, so we leave it in
> +place. This is a coding style choice.
> +
> +Lastly, we need to bump the LIBABIVER number for this library in the
> +Makefile to indicate to applications doing dynamic linking that this is
> +a later, and possibly incompatible library version:
> +
> +.. code-block:: c
> +
> + -LIBABIVER := 1
> + +LIBABIVER := 2
> +
> +Deprecating an entire ABI version
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +While removing a symbol from and ABI may be useful, it is often more
> +practical to remove an entire version node at once. If a version node
> +completely specifies an API, then removing part of it, typically makes
> +it incomplete. In those cases it is better to remove the entire node
> +
> +To do this, start by modifying the version map file, such that all
> +symbols from the node to be removed are merged into the next node in
> +the map
> +
> +In the case of our map above, it would transform to look as follows
> +
> +.. code-block:: none
> +
> + DPDK_2.1 {
> + global:
> +
> + rte_acl_add_rules;
> + rte_acl_build;
> + rte_acl_classify;
> + rte_acl_classify_alg;
> + rte_acl_classify_scalar;
> + rte_acl_dump;
> + rte_acl_create
> + rte_acl_find_existing;
> + rte_acl_free;
> + rte_acl_ipv4vlan_add_rules;
> + rte_acl_ipv4vlan_build;
> + rte_acl_list_dump;
> + rte_acl_reset;
> + rte_acl_reset_rules;
> + rte_acl_set_ctx_classify;
> +
> + local: *;
> + };
> +
> +Then any uses of BIND_DEFAULT_SYMBOL that pointed to the old node
> +should be updated to point to the new version node in any header files
> +for all affected symbols.
> +
> +.. code-block:: c
> +
> + -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
> + +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
> +
> +Lastly, any VERSION_SYMBOL macros that point to the old version node
> +should be removed, taking care to keep, where need old code in place to
> +support newer versions of the symbol.
> +
> +Running the ABI Validator
> +-------------------------
> +
> +The ``scripts`` directory in the DPDK source tree contains a utility
> +program, ``validate-abi.sh``, for validating the DPDK ABI based on the
> +Linux `ABI Compliance Checker
> +<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
> +
> +This has a dependency on the ``abi-compliance-checker`` and ``and
> +abi-dumper`` utilities which can be installed via a package manager. For
> example::
> +
> + sudo yum install abi-compliance-checker
> + sudo yum install abi-dumper
> +
> +The syntax of the ``validate-abi.sh`` utility is::
> +
> + ./scripts/validate-abi.sh <TAG1> <TAG2> <TARGET>
> +
> +Where ``TAG1`` and ``TAG2`` are valid git tags on the local repo and
> +target is the usual DPDK compilation target.
> +
> +For example to test the current committed HEAD against a previous
> +release tag we could add a temporary tag and run the utility as follows::
> +
> + git tag MY_TEMP_TAG
> + ./scripts/validate-abi.sh v2.0.0 MY_TEMP_TAG
> + x86_64-native-linuxapp-gcc
> +
> +After the validation script completes (it can take a while since it
> +need to compile both tags) it will create compatibility reports in the
> +``./compat_report`` directory. Listed incompatibilities can be found as
> +follows::
> +
> + grep -lr Incompatible compat_reports/
> --
> 2.1.0
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
2015-06-25 7:19 4% ` Zhang, Helin
@ 2015-06-25 7:42 4% ` Gonzalez Monroy, Sergio
2015-06-25 8:00 4% ` Gonzalez Monroy, Sergio
2015-06-25 12:25 4% ` Neil Horman
1 sibling, 1 reply; 200+ results
From: Gonzalez Monroy, Sergio @ 2015-06-25 7:42 UTC (permalink / raw)
To: Zhang, Helin, Neil Horman, dev
On 25/06/2015 08:19, Zhang, Helin wrote:
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Neil Horman
>> Sent: Thursday, June 25, 2015 2:35 AM
>> To: dev@dpdk.org
>> Subject: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
>>
>> People have been asking for ways to use the ABI macros, heres some docs to
>> clarify their use. Included is:
>>
>> * An overview of what ABI is
>> * Details of the ABI deprecation process
>> * Details of the versioning macros
>> * Examples of their use
>> * Details of how to use the ABI validator
>>
>> Thanks to John Mcnamara, who duplicated much of this effort at Intel while I was
>> working on it. Much of the introductory material was gathered and cleaned up
>> by him
>>
>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>> CC: john.mcnamara@intel.com
>> CC: thomas.monjalon@6wind.com
>>
>> Change notes:
>>
>> v2)
>> * Fixed RST indentations and spelling errors
>> * Rebased to upstream to fix index.rst conflict
>> ---
>> doc/guides/guidelines/index.rst | 1 +
>> doc/guides/guidelines/versioning.rst | 456
>> +++++++++++++++++++++++++++++++++++
>> 2 files changed, 457 insertions(+)
>> create mode 100644 doc/guides/guidelines/versioning.rst
>>
>> diff --git a/doc/guides/guidelines/index.rst b/doc/guides/guidelines/index.rst
>> index 0ee9ab3..bfb9fa3 100644
>> --- a/doc/guides/guidelines/index.rst
>> +++ b/doc/guides/guidelines/index.rst
>> @@ -7,3 +7,4 @@ Guidelines
>>
>> coding_style
>> design
>> + versioning
>> diff --git a/doc/guides/guidelines/versioning.rst
>> b/doc/guides/guidelines/versioning.rst
>> new file mode 100644
>> index 0000000..2aef526
>> --- /dev/null
>> +++ b/doc/guides/guidelines/versioning.rst
>> @@ -0,0 +1,456 @@
>> +Managing ABI updates
>> +====================
>> +
>> +Description
>> +-----------
>> +
>> +This document details some methods for handling ABI management in the
>> DPDK.
>> +Note this document is not exhaustive, in that C library versioning is
>> +flexible allowing multiple methods to achieve various goals, but it
>> +will provide the user with some introductory methods
>> +
>> +General Guidelines
>> +------------------
>> +
>> +#. Whenever possible, ABI should be preserved #. The addition of
>> +symbols is generally not problematic #. The modification of symbols can
>> +generally be managed with versioning #. The removal of symbols
>> +generally is an ABI break and requires bumping of the
>> + LIBABIVER macro
>> +
>> +What is an ABI
>> +--------------
>> +
>> +An ABI (Application Binary Interface) is the set of runtime interfaces
>> +exposed by a library. It is similar to an API (Application Programming
>> +Interface) but is the result of compilation. It is also effectively
>> +cloned when applications link to dynamic libraries. That is to say
>> +when an application is compiled to link against dynamic libraries, it
>> +is assumed that the ABI remains constant between the time the application is
>> compiled/linked, and the time that it runs.
>> +Therefore, in the case of dynamic linking, it is critical that an ABI
>> +is preserved, or (when modified), done in such a way that the
>> +application is unable to behave improperly or in an unexpected fashion.
>> +
>> +The DPDK ABI policy
>> +-------------------
>> +
>> +ABI versions are set at the time of major release labeling, and the ABI
>> +may change multiple times, without warning, between the last release
>> +label and the HEAD label of the git tree.
>> +
>> +ABI versions, once released, are available until such time as their
>> +deprecation has been noted in the Release Notes for at least one major
>> +release cycle. For example consider the case where the ABI for DPDK 2.0
>> +has been shipped and then a decision is made to modify it during the
>> +development of DPDK 2.1. The decision will be recorded in the Release
>> +Notes for the DPDK 2.1 release and the modification will be made available in
>> the DPDK 2.2 release.
>> +
>> +ABI versions may be deprecated in whole or in part as needed by a given
>> +update.
>> +
>> +Some ABI changes may be too significant to reasonably maintain multiple
>> +versions. In those cases ABI's may be updated without backward
>> +compatibility being provided. The requirements for doing so are:
>> +
>> +#. At least 3 acknowledgments of the need to do so must be made on the
>> + dpdk.org mailing list.
>> +
>> +#. A full deprecation cycle, as explained above, must be made to offer
>> + downstream consumers sufficient warning of the change.
>> +
>> +#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
>> + incorporated must be incremented in parallel with the ABI changes
>> + themselves.
>> +
>> +Note that the above process for ABI deprecation should not be
>> +undertaken lightly. ABI stability is extremely important for downstream
>> +consumers of the DPDK, especially when distributed in shared object
>> +form. Every effort should be made to preserve the ABI whenever
>> +possible. The ABI should only be changed for significant reasons, such
>> +as performance enhancements. ABI breakage due to changes such as
>> +reorganizing public structure fields for aesthetic or readability purposes should
>> be avoided.
>> +
>> +Examples of Deprecation Notices
>> +-------------------------------
>> +
>> +The following are some examples of ABI deprecation notices which would
>> +be added to the Release Notes:
>> +
>> +* The Macro ``#RTE_FOO`` is deprecated and will be removed with version
>> +2.0,
>> + to be replaced with the inline function ``rte_foo()``.
>> +
>> +* The function ``rte_mbuf_grok()`` has been updated to include a new
>> +parameter
>> + in version 2.0. Backwards compatibility will be maintained for this
>> +function
>> + until the release of version 2.1
>> +
>> +* The members of ``struct rte_foo`` have been reorganized in release
>> +2.0 for
>> + performance reasons. Existing binary applications will have backwards
>> + compatibility in release 2.0, while newly built binaries will need to
>> + reference the new structure variant ``struct rte_foo2``.
>> +Compatibility will
>> + be removed in release 2.2, and all applications will require updating
>> +and
>> + rebuilding to the new structure at that time, which will be renamed
>> +to the
>> + original ``struct rte_foo``.
>> +
>> +* Significant ABI changes are planned for the ``librte_dostuff``
>> +library. The
>> + upcoming release 2.0 will not contain these changes, but release 2.1
>> +will,
>> + and no backwards compatibility is planned due to the extensive nature
>> +of
>> + these changes. Binaries using this library built prior to version 2.1
>> +will
>> + require updating and recompilation.
>> +
>> +Versioning Macros
>> +-----------------
>> +
>> +When a symbol is exported from a library to provide an API, it also
>> +provides a calling convention (ABI) that is embodied in its name,
>> +return type and arguments. Occasionally that function may need to
>> +change to accommodate new functionality or behavior. When that occurs,
>> +it is desirable to allow for backward compatibility for a time with
>> +older binaries that are dynamically linked to the DPDK.
>> +
>> +To support backward compatibility the
>> +``lib/librte_compat/rte_compat.h``
>> +header file provides macros to use when updating exported functions.
>> +These macros are used in conjunction with the
>> +``rte_<library>_version.map`` file for a given library to allow
>> +multiple versions of a symbol to exist in a shared library so that older binaries
>> need not be immediately recompiled.
>> +
>> +The macros exported are:
>> +
>> +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry
>> +binding
>> + unversioned symbol ``b`` to the internal function ``b_e``.
>> +
>> +
>> +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
>> + unversioned symbol ``b`` to the internal function ``b_e``.
>> +
>> +* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry
>> +instructing
>> + the linker to bind references to symbol ``b`` to the internal symbol
>> + ``b_e``.
>> +
>> +
>> +Examples of ABI Macro use
>> +-------------------------
>> +
>> +Updating a public API
>> +~~~~~~~~~~~~~~~~~~~~~
>> +
>> +Assume we have a function as follows
>> +
>> +.. code-block:: c
>> +
>> + /*
>> + * Create an acl context object for apps to
>> + * manipulate
>> + */
>> + struct rte_acl_ctx *
>> + rte_acl_create(const struct rte_acl_param *param) {
>> + ...
>> + }
>> +
>> +
>> +Assume that struct rte_acl_ctx is a private structure, and that a
>> +developer wishes to enhance the acl api so that a debugging flag can be
>> +enabled on a per-context basis. This requires an addition to the
>> +structure (which, being private, is safe), but it also requires
>> +modifying the code as follows
>> +
>> +.. code-block:: c
>> +
>> + /*
>> + * Create an acl context object for apps to
>> + * manipulate
>> + */
>> + struct rte_acl_ctx *
>> + rte_acl_create(const struct rte_acl_param *param, int debug) {
>> + ...
>> + }
>> +
>> +
>> +Note also that, being a public function, the header file prototype must
>> +also be changed, as must all the call sites, to reflect the new ABI
>> +footprint. We will maintain previous ABI versions that are accessible
>> +only to previously compiled binaries
>> +
>> +The addition of a parameter to the function is ABI breaking as the
>> +function is public, and existing application may use it in its current
>> +form. However, the compatibility macros in DPDK allow a developer to
>> +use symbol versioning so that multiple functions can be mapped to the
>> +same public symbol based on when an application was linked to it. To
>> +see how this is done, we start with the requisite libraries version map
>> +file. Initially the version map file for the acl library looks like
>> +this
>> +
>> +.. code-block:: none
>> +
>> + DPDK_2.0 {
>> + global:
>> +
>> + rte_acl_add_rules;
>> + rte_acl_build;
>> + rte_acl_classify;
>> + rte_acl_classify_alg;
>> + rte_acl_classify_scalar;
>> + rte_acl_create;
>> + rte_acl_dump;
>> + rte_acl_find_existing;
>> + rte_acl_free;
>> + rte_acl_ipv4vlan_add_rules;
>> + rte_acl_ipv4vlan_build;
>> + rte_acl_list_dump;
>> + rte_acl_reset;
>> + rte_acl_reset_rules;
>> + rte_acl_set_ctx_classify;
>> +
>> + local: *;
>> + };
>> +
>> +This file needs to be modified as follows
>> +
>> +.. code-block:: none
>> +
>> + DPDK_2.0 {
>> + global:
>> +
>> + rte_acl_add_rules;
>> + rte_acl_build;
>> + rte_acl_classify;
>> + rte_acl_classify_alg;
>> + rte_acl_classify_scalar;
>> + rte_acl_create;
>> + rte_acl_dump;
>> + rte_acl_find_existing;
>> + rte_acl_free;
>> + rte_acl_ipv4vlan_add_rules;
>> + rte_acl_ipv4vlan_build;
>> + rte_acl_list_dump;
>> + rte_acl_reset;
>> + rte_acl_reset_rules;
>> + rte_acl_set_ctx_classify;
>> +
>> + local: *;
>> + };
>> +
>> + DPDK_2.1 {
>> + global:
>> + rte_acl_create;
> One question, does it need a line of "local: *;", like it did in
> librte_ether/rte_ether_version.map?
No, it does not. You only need to specify 'local' in the default/base
node, which
in this case/example is DPDK_2.0.
Sergio
>> +
>> + } DPDK_2.0;
>> +
>>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
2015-06-25 7:42 4% ` Gonzalez Monroy, Sergio
@ 2015-06-25 8:00 4% ` Gonzalez Monroy, Sergio
0 siblings, 0 replies; 200+ results
From: Gonzalez Monroy, Sergio @ 2015-06-25 8:00 UTC (permalink / raw)
To: Zhang, Helin, Neil Horman, dev
On 25/06/2015 08:42, Gonzalez Monroy, Sergio wrote:
> On 25/06/2015 08:19, Zhang, Helin wrote:
>>
>>> -----Original Message-----
>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Neil Horman
>>> Sent: Thursday, June 25, 2015 2:35 AM
>>> To: dev@dpdk.org
>>> Subject: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
>>>
>>> People have been asking for ways to use the ABI macros, heres some
>>> docs to
>>> clarify their use. Included is:
>>>
>>> * An overview of what ABI is
>>> * Details of the ABI deprecation process
>>> * Details of the versioning macros
>>> * Examples of their use
>>> * Details of how to use the ABI validator
>>>
>>> Thanks to John Mcnamara, who duplicated much of this effort at Intel
>>> while I was
>>> working on it. Much of the introductory material was gathered and
>>> cleaned up
>>> by him
>>>
>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>> CC: john.mcnamara@intel.com
>>> CC: thomas.monjalon@6wind.com
>>>
>>> Change notes:
>>>
>>> v2)
>>> * Fixed RST indentations and spelling errors
>>> * Rebased to upstream to fix index.rst conflict
>>> ---
>>> doc/guides/guidelines/index.rst | 1 +
>>> doc/guides/guidelines/versioning.rst | 456
>>> +++++++++++++++++++++++++++++++++++
>>> 2 files changed, 457 insertions(+)
>>> create mode 100644 doc/guides/guidelines/versioning.rst
>>>
>>> diff --git a/doc/guides/guidelines/index.rst
>>> b/doc/guides/guidelines/index.rst
>>> index 0ee9ab3..bfb9fa3 100644
>>> --- a/doc/guides/guidelines/index.rst
>>> +++ b/doc/guides/guidelines/index.rst
>>> @@ -7,3 +7,4 @@ Guidelines
>>>
>>> coding_style
>>> design
>>> + versioning
>>> diff --git a/doc/guides/guidelines/versioning.rst
>>> b/doc/guides/guidelines/versioning.rst
>>> new file mode 100644
>>> index 0000000..2aef526
>>> --- /dev/null
>>> +++ b/doc/guides/guidelines/versioning.rst
>>> @@ -0,0 +1,456 @@
>>> +Managing ABI updates
>>> +====================
>>> +
>>> +Description
>>> +-----------
>>> +
>>> +This document details some methods for handling ABI management in the
>>> DPDK.
>>> +Note this document is not exhaustive, in that C library versioning is
>>> +flexible allowing multiple methods to achieve various goals, but it
>>> +will provide the user with some introductory methods
>>> +
>>> +General Guidelines
>>> +------------------
>>> +
>>> +#. Whenever possible, ABI should be preserved #. The addition of
>>> +symbols is generally not problematic #. The modification of symbols
>>> can
>>> +generally be managed with versioning #. The removal of symbols
>>> +generally is an ABI break and requires bumping of the
>>> + LIBABIVER macro
>>> +
>>> +What is an ABI
>>> +--------------
>>> +
>>> +An ABI (Application Binary Interface) is the set of runtime interfaces
>>> +exposed by a library. It is similar to an API (Application Programming
>>> +Interface) but is the result of compilation. It is also effectively
>>> +cloned when applications link to dynamic libraries. That is to say
>>> +when an application is compiled to link against dynamic libraries, it
>>> +is assumed that the ABI remains constant between the time the
>>> application is
>>> compiled/linked, and the time that it runs.
>>> +Therefore, in the case of dynamic linking, it is critical that an ABI
>>> +is preserved, or (when modified), done in such a way that the
>>> +application is unable to behave improperly or in an unexpected
>>> fashion.
>>> +
>>> +The DPDK ABI policy
>>> +-------------------
>>> +
>>> +ABI versions are set at the time of major release labeling, and the
>>> ABI
>>> +may change multiple times, without warning, between the last release
>>> +label and the HEAD label of the git tree.
>>> +
>>> +ABI versions, once released, are available until such time as their
>>> +deprecation has been noted in the Release Notes for at least one major
>>> +release cycle. For example consider the case where the ABI for DPDK
>>> 2.0
>>> +has been shipped and then a decision is made to modify it during the
>>> +development of DPDK 2.1. The decision will be recorded in the Release
>>> +Notes for the DPDK 2.1 release and the modification will be made
>>> available in
>>> the DPDK 2.2 release.
>>> +
>>> +ABI versions may be deprecated in whole or in part as needed by a
>>> given
>>> +update.
>>> +
>>> +Some ABI changes may be too significant to reasonably maintain
>>> multiple
>>> +versions. In those cases ABI's may be updated without backward
>>> +compatibility being provided. The requirements for doing so are:
>>> +
>>> +#. At least 3 acknowledgments of the need to do so must be made on the
>>> + dpdk.org mailing list.
>>> +
>>> +#. A full deprecation cycle, as explained above, must be made to offer
>>> + downstream consumers sufficient warning of the change.
>>> +
>>> +#. The ``LIBABIVER`` variable in the makefile(s) where the ABI
>>> changes are
>>> + incorporated must be incremented in parallel with the ABI changes
>>> + themselves.
>>> +
>>> +Note that the above process for ABI deprecation should not be
>>> +undertaken lightly. ABI stability is extremely important for
>>> downstream
>>> +consumers of the DPDK, especially when distributed in shared object
>>> +form. Every effort should be made to preserve the ABI whenever
>>> +possible. The ABI should only be changed for significant reasons, such
>>> +as performance enhancements. ABI breakage due to changes such as
>>> +reorganizing public structure fields for aesthetic or readability
>>> purposes should
>>> be avoided.
>>> +
>>> +Examples of Deprecation Notices
>>> +-------------------------------
>>> +
>>> +The following are some examples of ABI deprecation notices which would
>>> +be added to the Release Notes:
>>> +
>>> +* The Macro ``#RTE_FOO`` is deprecated and will be removed with
>>> version
>>> +2.0,
>>> + to be replaced with the inline function ``rte_foo()``.
>>> +
>>> +* The function ``rte_mbuf_grok()`` has been updated to include a new
>>> +parameter
>>> + in version 2.0. Backwards compatibility will be maintained for this
>>> +function
>>> + until the release of version 2.1
>>> +
>>> +* The members of ``struct rte_foo`` have been reorganized in release
>>> +2.0 for
>>> + performance reasons. Existing binary applications will have
>>> backwards
>>> + compatibility in release 2.0, while newly built binaries will
>>> need to
>>> + reference the new structure variant ``struct rte_foo2``.
>>> +Compatibility will
>>> + be removed in release 2.2, and all applications will require
>>> updating
>>> +and
>>> + rebuilding to the new structure at that time, which will be renamed
>>> +to the
>>> + original ``struct rte_foo``.
>>> +
>>> +* Significant ABI changes are planned for the ``librte_dostuff``
>>> +library. The
>>> + upcoming release 2.0 will not contain these changes, but release 2.1
>>> +will,
>>> + and no backwards compatibility is planned due to the extensive
>>> nature
>>> +of
>>> + these changes. Binaries using this library built prior to version
>>> 2.1
>>> +will
>>> + require updating and recompilation.
>>> +
>>> +Versioning Macros
>>> +-----------------
>>> +
>>> +When a symbol is exported from a library to provide an API, it also
>>> +provides a calling convention (ABI) that is embodied in its name,
>>> +return type and arguments. Occasionally that function may need to
>>> +change to accommodate new functionality or behavior. When that occurs,
>>> +it is desirable to allow for backward compatibility for a time with
>>> +older binaries that are dynamically linked to the DPDK.
>>> +
>>> +To support backward compatibility the
>>> +``lib/librte_compat/rte_compat.h``
>>> +header file provides macros to use when updating exported functions.
>>> +These macros are used in conjunction with the
>>> +``rte_<library>_version.map`` file for a given library to allow
>>> +multiple versions of a symbol to exist in a shared library so that
>>> older binaries
>>> need not be immediately recompiled.
>>> +
>>> +The macros exported are:
>>> +
>>> +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry
>>> +binding
>>> + unversioned symbol ``b`` to the internal function ``b_e``.
>>> +
>>> +
>>> +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
>>> + unversioned symbol ``b`` to the internal function ``b_e``.
>>> +
>>> +* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry
>>> +instructing
>>> + the linker to bind references to symbol ``b`` to the internal symbol
>>> + ``b_e``.
>>> +
>>> +
>>> +Examples of ABI Macro use
>>> +-------------------------
>>> +
>>> +Updating a public API
>>> +~~~~~~~~~~~~~~~~~~~~~
>>> +
>>> +Assume we have a function as follows
>>> +
>>> +.. code-block:: c
>>> +
>>> + /*
>>> + * Create an acl context object for apps to
>>> + * manipulate
>>> + */
>>> + struct rte_acl_ctx *
>>> + rte_acl_create(const struct rte_acl_param *param) {
>>> + ...
>>> + }
>>> +
>>> +
>>> +Assume that struct rte_acl_ctx is a private structure, and that a
>>> +developer wishes to enhance the acl api so that a debugging flag
>>> can be
>>> +enabled on a per-context basis. This requires an addition to the
>>> +structure (which, being private, is safe), but it also requires
>>> +modifying the code as follows
>>> +
>>> +.. code-block:: c
>>> +
>>> + /*
>>> + * Create an acl context object for apps to
>>> + * manipulate
>>> + */
>>> + struct rte_acl_ctx *
>>> + rte_acl_create(const struct rte_acl_param *param, int debug) {
>>> + ...
>>> + }
>>> +
>>> +
>>> +Note also that, being a public function, the header file prototype
>>> must
>>> +also be changed, as must all the call sites, to reflect the new ABI
>>> +footprint. We will maintain previous ABI versions that are accessible
>>> +only to previously compiled binaries
>>> +
>>> +The addition of a parameter to the function is ABI breaking as the
>>> +function is public, and existing application may use it in its current
>>> +form. However, the compatibility macros in DPDK allow a developer to
>>> +use symbol versioning so that multiple functions can be mapped to the
>>> +same public symbol based on when an application was linked to it. To
>>> +see how this is done, we start with the requisite libraries version
>>> map
>>> +file. Initially the version map file for the acl library looks like
>>> +this
>>> +
>>> +.. code-block:: none
>>> +
>>> + DPDK_2.0 {
>>> + global:
>>> +
>>> + rte_acl_add_rules;
>>> + rte_acl_build;
>>> + rte_acl_classify;
>>> + rte_acl_classify_alg;
>>> + rte_acl_classify_scalar;
>>> + rte_acl_create;
>>> + rte_acl_dump;
>>> + rte_acl_find_existing;
>>> + rte_acl_free;
>>> + rte_acl_ipv4vlan_add_rules;
>>> + rte_acl_ipv4vlan_build;
>>> + rte_acl_list_dump;
>>> + rte_acl_reset;
>>> + rte_acl_reset_rules;
>>> + rte_acl_set_ctx_classify;
>>> +
>>> + local: *;
>>> + };
>>> +
>>> +This file needs to be modified as follows
>>> +
>>> +.. code-block:: none
>>> +
>>> + DPDK_2.0 {
>>> + global:
>>> +
>>> + rte_acl_add_rules;
>>> + rte_acl_build;
>>> + rte_acl_classify;
>>> + rte_acl_classify_alg;
>>> + rte_acl_classify_scalar;
>>> + rte_acl_create;
>>> + rte_acl_dump;
>>> + rte_acl_find_existing;
>>> + rte_acl_free;
>>> + rte_acl_ipv4vlan_add_rules;
>>> + rte_acl_ipv4vlan_build;
>>> + rte_acl_list_dump;
>>> + rte_acl_reset;
>>> + rte_acl_reset_rules;
>>> + rte_acl_set_ctx_classify;
>>> +
>>> + local: *;
>>> + };
>>> +
>>> + DPDK_2.1 {
>>> + global:
>>> + rte_acl_create;
>> One question, does it need a line of "local: *;", like it did in
>> librte_ether/rte_ether_version.map?
> No, it does not. You only need to specify 'local' in the default/base
> node, which
> in this case/example is DPDK_2.0.
>
> Sergio
Just to be clear, as I think I may have misused the term 'default' here,
it is recommended
to just specify 'local: *;' in just one node (it could confuse the
linker) and it doesn't really
matter which one.
Quoting http://www.akkadia.org/drepper/symbol-versioning:
"It makes no sense at all to associate versions with symbols which are
not exported. Therefore the `local:' sections of all but the base
version are empty and the `local:' section of the base version simply
contains `*'. This will match all symbols which are not explicitly
mentioned in any `global:' list."
Sergio
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 2/7] mbuf: use the reserved 16 bits for double vlan
@ 2015-06-25 8:31 3% ` Zhang, Helin
2015-06-28 20:36 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Zhang, Helin @ 2015-06-25 8:31 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
Hi Neil
> -----Original Message-----
> From: Zhang, Helin
> Sent: Thursday, June 11, 2015 3:04 PM
> To: dev@dpdk.org
> Cc: Cao, Min; Liu, Jijiang; Wu, Jingjing; Ananyev, Konstantin; Richardson, Bruce;
> olivier.matz@6wind.com; Zhang, Helin
> Subject: [PATCH v3 2/7] mbuf: use the reserved 16 bits for double vlan
>
> Use the reserved 16 bits in rte_mbuf structure for the outer vlan, also add QinQ
> offloading flags for both RX and TX sides.
>
> Signed-off-by: Helin Zhang <helin.zhang@intel.com>
> ---
> lib/librte_mbuf/rte_mbuf.h | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> v2 changes:
> * Fixed a typo.
>
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index
> ab6de67..84fe181 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -101,11 +101,17 @@ extern "C" {
> #define PKT_RX_TUNNEL_IPV6_HDR (1ULL << 12) /**< RX tunnel packet with
> IPv6 header. */
> #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. */
> /* add new RX flags here */
>
> /* add new TX flags here */
>
> /**
> + * Second VLAN insertion (QinQ) flag.
> + */
> +#define PKT_TX_QINQ_PKT (1ULL << 49) /**< TX packet with double
> VLAN inserted. */
> +
> +/**
> * 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 @@
> -279,7 +285,7 @@ struct rte_mbuf {
> 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;
> + uint16_t vlan_tci_outer; /**< Outer VLAN Tag Control Identifier (CPU
> +order) */
Do you think here is a ABI break or not? Just using the reserved 16 bits, which was
intended for the second_vlan_tag. Thanks in advance!
I did not see any "Incompatible" reported by validate_abi.sh.
Regards,
Helin
> union {
> uint32_t rss; /**< RSS hash result if RSS enabled */
> struct {
> @@ -777,6 +783,7 @@ static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
> m->pkt_len = 0;
> m->tx_offload = 0;
> m->vlan_tci = 0;
> + m->vlan_tci_outer = 0;
> m->nb_segs = 1;
> m->port = 0xff;
>
> @@ -849,6 +856,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi,
> struct rte_mbuf *m)
> mi->data_len = m->data_len;
> mi->port = m->port;
> mi->vlan_tci = m->vlan_tci;
> + mi->vlan_tci_outer = m->vlan_tci_outer;
> mi->tx_offload = m->tx_offload;
> mi->hash = m->hash;
>
> --
> 1.9.3
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
2015-06-24 21:09 9% ` Thomas Monjalon
@ 2015-06-25 11:35 9% ` Neil Horman
2015-06-25 13:22 7% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-06-25 11:35 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Wed, Jun 24, 2015 at 11:09:29PM +0200, Thomas Monjalon wrote:
> 2015-06-24 14:34, Neil Horman:
> > +Some ABI changes may be too significant to reasonably maintain multiple
> > +versions. In those cases ABI's may be updated without backward compatibility
> > +being provided. The requirements for doing so are:
> > +
> > +#. At least 3 acknowledgments of the need to do so must be made on the
> > + dpdk.org mailing list.
> > +
> > +#. A full deprecation cycle, as explained above, must be made to offer
> > + downstream consumers sufficient warning of the change.
> > +
> > +#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
> > + incorporated must be incremented in parallel with the ABI changes
> > + themselves.
>
> The proposal was to provide the old and the new ABI in the same source code
> during the deprecation cycle. The old ABI would be the default and people
> can build the new one by enabling the NEXT_ABI config option.
> So the migration to the new ABI is smoother.
>
Yes....I'm not sure what you're saying here. The ABI doesn't 'Change' until the
old ABI is removed (i.e. old applications are forced to adopt a new ABI), and so
LIBABIVER has to be updated in parallel with that removal
>
> [...]
> > +The macros exported are:
> > +
> > +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
> > + unversioned symbol ``b`` to the internal function ``b_e``.
>
> The definition is the same as BASE_SYMBOL.
>
No, they're different. VERSION_SYMBOL is defined as:
VERSION_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@DPDK_" RTE_STR(n))
while BASE_SYMBOL is
#define BASE_SYMBOL(b, e) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b)"@")
> > +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
> > + unversioned symbol ``b`` to the internal function ``b_e``.
>
>
> [...]
> > + DPDK_2.0 {
> > + global:
> > +
> > + rte_acl_add_rules;
> > + rte_acl_build;
> > + rte_acl_classify;
> > + rte_acl_classify_alg;
> > + rte_acl_classify_scalar;
> > + rte_acl_create;
>
> So it's declared twice, right?
> I think it should be explicit.
>
Yes, its listed once for each version node, so 2 delcarations. I thought that
was made explicit by the use of the code block. What else would you like to
see?
> > + rte_acl_dump;
> > + rte_acl_find_existing;
> > + rte_acl_free;
> > + rte_acl_ipv4vlan_add_rules;
> > + rte_acl_ipv4vlan_build;
> > + rte_acl_list_dump;
> > + rte_acl_reset;
> > + rte_acl_reset_rules;
> > + rte_acl_set_ctx_classify;
> > +
> > + local: *;
> > + };
> > +
> > + DPDK_2.1 {
> > + global:
> > + rte_acl_create;
> > +
> > + } DPDK_2.0;
>
> [...]
> > +Note that the base name of the symbol was kept in tact, as this is condusive to
>
> s/in tact/intact/?
>
Hmm, thats odd, aspell explicitly changed that. Though your right, it should be
intact. I'll fix it.
> [...]
> > +the macros used for versioning symbols. That is our next step, mapping this new
> > +symbol name to the initial symbol name at version node 2.0. Immediately after
> > +the function, we add this line of code
> > +
> > +.. code-block:: c
> > +
> > + VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
>
> Can it be declared before the function?
>
Strictly speaking yes, though its a bit odd from a sylistic point to declare
versioned aliases for a symbol prior to defining the symbol itself (its like a
forward declaration)
> [...]
> > +Remembering to also add the rte_compat.h header to the requisite c file where
> > +these changes are being made. The above macro instructs the linker to create a
> > +new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
> > +builds, but now points to the above newly named function. We have now mapped
> > +the original rte_acl_create symbol to the original function (but with a new
> > +name)
>
> Could we use VERSION_SYMBOL(rte_acl_create, , 2.0);
> when introducing the function in DPDK 2.0 (before any ABI breakage)?
> It could help to generate the .map file.
>
I've honestly not tried. I think its possible, but the example you give above I
don't think will work, because it will result in an error indicating
rte_acl_create is declared twice. You would have to rename rte_acl_create to
something uniqe prior to versioning it.
> When do we need to use BASE_SYMBOL?
>
For our purposes you currently don't, because there are no unversioned symbols
in DPDK (since we use a map file). I've just included it here for completeness
in the header file should it ever be needed in the future.
> [...]
> > +This code serves as our new API call. Its the same as our old call, but adds
> > +the new parameter in place. Next we need to map this function to the symbol
> > +``rte_acl_create@DPDK_2.1``. To do this, we modify the public prototype of the call
> > +in the header file, adding the macro there to inform all including applications,
> > +that on re-link, the default rte_acl_create symbol should point to this
> > +function. Note that we could do this by simply naming the function above
> > +rte_acl_create, and the linker would chose the most recent version tag to apply
> > +in the version script, but we can also do this in the header file
> > +
> > +.. code-block:: c
> > +
> > + struct rte_acl_ctx *
> > + -rte_acl_create(const struct rte_acl_param *param);
> > + +rte_acl_create(const struct rte_acl_param *param, int debug);
> > + +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
>
> Will it work with static library?
>
hmm, this example in particular? No, I didn't think of that. To work with a
static build, you still need to define the unversioned symbol. Thats easy
enough to do though, by either defining rte_acl_create as a public api and
calling the appropriate versioned function, or by creating a macro to point to
the right version via an alias. I can fix that easily enough.
> > +Next remove the corresponding versioned export
> > +.. code-block:: c
> > +
> > + -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
> > +
> > +
> > +Note that the internal function definition could also be removed, but its used
> > +in our example by the newer version _v21, so we leave it in place. This is a
> > +coding style choice.
> > +
> > +Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
> > +indicate to applications doing dynamic linking that this is a later, and
> > +possibly incompatible library version:
> > +
> > +.. code-block:: c
> > +
> > + -LIBABIVER := 1
> > + +LIBABIVER := 2
>
> Very well explained, thanks.
>
> [...]
> > + rte_acl_add_rules;
> > + rte_acl_build;
> > + rte_acl_classify;
> > + rte_acl_classify_alg;
> > + rte_acl_classify_scalar;
> > + rte_acl_dump;
> > + rte_acl_create
>
> Not in alphabetical order.
>
No, none of them are, but that can be adjusted, though I'd like to do that
separately from this documentation.
>
> As you copy a part of abi.rst, it should be removed from the original doc.
>
Sure
> Thanks Neil
>
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
2015-06-25 7:19 4% ` Zhang, Helin
2015-06-25 7:42 4% ` Gonzalez Monroy, Sergio
@ 2015-06-25 12:25 4% ` Neil Horman
1 sibling, 0 replies; 200+ results
From: Neil Horman @ 2015-06-25 12:25 UTC (permalink / raw)
To: Zhang, Helin; +Cc: dev
On Thu, Jun 25, 2015 at 07:19:49AM +0000, Zhang, Helin wrote:
>
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Neil Horman
> > Sent: Thursday, June 25, 2015 2:35 AM
> > To: dev@dpdk.org
> > Subject: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
> >
> > People have been asking for ways to use the ABI macros, heres some docs to
> > clarify their use. Included is:
> >
> > * An overview of what ABI is
> > * Details of the ABI deprecation process
> > * Details of the versioning macros
> > * Examples of their use
> > * Details of how to use the ABI validator
> >
> > Thanks to John Mcnamara, who duplicated much of this effort at Intel while I was
> > working on it. Much of the introductory material was gathered and cleaned up
> > by him
> >
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > CC: john.mcnamara@intel.com
> > CC: thomas.monjalon@6wind.com
> >
> > Change notes:
> >
> > v2)
> > * Fixed RST indentations and spelling errors
> > * Rebased to upstream to fix index.rst conflict
> > ---
> > doc/guides/guidelines/index.rst | 1 +
> > doc/guides/guidelines/versioning.rst | 456
> > +++++++++++++++++++++++++++++++++++
> > 2 files changed, 457 insertions(+)
> > create mode 100644 doc/guides/guidelines/versioning.rst
> >
> > diff --git a/doc/guides/guidelines/index.rst b/doc/guides/guidelines/index.rst
> > index 0ee9ab3..bfb9fa3 100644
> > --- a/doc/guides/guidelines/index.rst
> > +++ b/doc/guides/guidelines/index.rst
> > @@ -7,3 +7,4 @@ Guidelines
> >
> > coding_style
> > design
> > + versioning
> > diff --git a/doc/guides/guidelines/versioning.rst
> > b/doc/guides/guidelines/versioning.rst
> > new file mode 100644
> > index 0000000..2aef526
> > --- /dev/null
> > +++ b/doc/guides/guidelines/versioning.rst
> > @@ -0,0 +1,456 @@
> > +Managing ABI updates
> > +====================
> > +
> > +Description
> > +-----------
> > +
> > +This document details some methods for handling ABI management in the
> > DPDK.
> > +Note this document is not exhaustive, in that C library versioning is
> > +flexible allowing multiple methods to achieve various goals, but it
> > +will provide the user with some introductory methods
> > +
> > +General Guidelines
> > +------------------
> > +
> > +#. Whenever possible, ABI should be preserved #. The addition of
> > +symbols is generally not problematic #. The modification of symbols can
> > +generally be managed with versioning #. The removal of symbols
> > +generally is an ABI break and requires bumping of the
> > + LIBABIVER macro
> > +
> > +What is an ABI
> > +--------------
> > +
> > +An ABI (Application Binary Interface) is the set of runtime interfaces
> > +exposed by a library. It is similar to an API (Application Programming
> > +Interface) but is the result of compilation. It is also effectively
> > +cloned when applications link to dynamic libraries. That is to say
> > +when an application is compiled to link against dynamic libraries, it
> > +is assumed that the ABI remains constant between the time the application is
> > compiled/linked, and the time that it runs.
> > +Therefore, in the case of dynamic linking, it is critical that an ABI
> > +is preserved, or (when modified), done in such a way that the
> > +application is unable to behave improperly or in an unexpected fashion.
> > +
> > +The DPDK ABI policy
> > +-------------------
> > +
> > +ABI versions are set at the time of major release labeling, and the ABI
> > +may change multiple times, without warning, between the last release
> > +label and the HEAD label of the git tree.
> > +
> > +ABI versions, once released, are available until such time as their
> > +deprecation has been noted in the Release Notes for at least one major
> > +release cycle. For example consider the case where the ABI for DPDK 2.0
> > +has been shipped and then a decision is made to modify it during the
> > +development of DPDK 2.1. The decision will be recorded in the Release
> > +Notes for the DPDK 2.1 release and the modification will be made available in
> > the DPDK 2.2 release.
> > +
> > +ABI versions may be deprecated in whole or in part as needed by a given
> > +update.
> > +
> > +Some ABI changes may be too significant to reasonably maintain multiple
> > +versions. In those cases ABI's may be updated without backward
> > +compatibility being provided. The requirements for doing so are:
> > +
> > +#. At least 3 acknowledgments of the need to do so must be made on the
> > + dpdk.org mailing list.
> > +
> > +#. A full deprecation cycle, as explained above, must be made to offer
> > + downstream consumers sufficient warning of the change.
> > +
> > +#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
> > + incorporated must be incremented in parallel with the ABI changes
> > + themselves.
> > +
> > +Note that the above process for ABI deprecation should not be
> > +undertaken lightly. ABI stability is extremely important for downstream
> > +consumers of the DPDK, especially when distributed in shared object
> > +form. Every effort should be made to preserve the ABI whenever
> > +possible. The ABI should only be changed for significant reasons, such
> > +as performance enhancements. ABI breakage due to changes such as
> > +reorganizing public structure fields for aesthetic or readability purposes should
> > be avoided.
> > +
> > +Examples of Deprecation Notices
> > +-------------------------------
> > +
> > +The following are some examples of ABI deprecation notices which would
> > +be added to the Release Notes:
> > +
> > +* The Macro ``#RTE_FOO`` is deprecated and will be removed with version
> > +2.0,
> > + to be replaced with the inline function ``rte_foo()``.
> > +
> > +* The function ``rte_mbuf_grok()`` has been updated to include a new
> > +parameter
> > + in version 2.0. Backwards compatibility will be maintained for this
> > +function
> > + until the release of version 2.1
> > +
> > +* The members of ``struct rte_foo`` have been reorganized in release
> > +2.0 for
> > + performance reasons. Existing binary applications will have backwards
> > + compatibility in release 2.0, while newly built binaries will need to
> > + reference the new structure variant ``struct rte_foo2``.
> > +Compatibility will
> > + be removed in release 2.2, and all applications will require updating
> > +and
> > + rebuilding to the new structure at that time, which will be renamed
> > +to the
> > + original ``struct rte_foo``.
> > +
> > +* Significant ABI changes are planned for the ``librte_dostuff``
> > +library. The
> > + upcoming release 2.0 will not contain these changes, but release 2.1
> > +will,
> > + and no backwards compatibility is planned due to the extensive nature
> > +of
> > + these changes. Binaries using this library built prior to version 2.1
> > +will
> > + require updating and recompilation.
> > +
> > +Versioning Macros
> > +-----------------
> > +
> > +When a symbol is exported from a library to provide an API, it also
> > +provides a calling convention (ABI) that is embodied in its name,
> > +return type and arguments. Occasionally that function may need to
> > +change to accommodate new functionality or behavior. When that occurs,
> > +it is desirable to allow for backward compatibility for a time with
> > +older binaries that are dynamically linked to the DPDK.
> > +
> > +To support backward compatibility the
> > +``lib/librte_compat/rte_compat.h``
> > +header file provides macros to use when updating exported functions.
> > +These macros are used in conjunction with the
> > +``rte_<library>_version.map`` file for a given library to allow
> > +multiple versions of a symbol to exist in a shared library so that older binaries
> > need not be immediately recompiled.
> > +
> > +The macros exported are:
> > +
> > +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry
> > +binding
> > + unversioned symbol ``b`` to the internal function ``b_e``.
> > +
> > +
> > +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
> > + unversioned symbol ``b`` to the internal function ``b_e``.
> > +
> > +* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry
> > +instructing
> > + the linker to bind references to symbol ``b`` to the internal symbol
> > + ``b_e``.
> > +
> > +
> > +Examples of ABI Macro use
> > +-------------------------
> > +
> > +Updating a public API
> > +~~~~~~~~~~~~~~~~~~~~~
> > +
> > +Assume we have a function as follows
> > +
> > +.. code-block:: c
> > +
> > + /*
> > + * Create an acl context object for apps to
> > + * manipulate
> > + */
> > + struct rte_acl_ctx *
> > + rte_acl_create(const struct rte_acl_param *param) {
> > + ...
> > + }
> > +
> > +
> > +Assume that struct rte_acl_ctx is a private structure, and that a
> > +developer wishes to enhance the acl api so that a debugging flag can be
> > +enabled on a per-context basis. This requires an addition to the
> > +structure (which, being private, is safe), but it also requires
> > +modifying the code as follows
> > +
> > +.. code-block:: c
> > +
> > + /*
> > + * Create an acl context object for apps to
> > + * manipulate
> > + */
> > + struct rte_acl_ctx *
> > + rte_acl_create(const struct rte_acl_param *param, int debug) {
> > + ...
> > + }
> > +
> > +
> > +Note also that, being a public function, the header file prototype must
> > +also be changed, as must all the call sites, to reflect the new ABI
> > +footprint. We will maintain previous ABI versions that are accessible
> > +only to previously compiled binaries
> > +
> > +The addition of a parameter to the function is ABI breaking as the
> > +function is public, and existing application may use it in its current
> > +form. However, the compatibility macros in DPDK allow a developer to
> > +use symbol versioning so that multiple functions can be mapped to the
> > +same public symbol based on when an application was linked to it. To
> > +see how this is done, we start with the requisite libraries version map
> > +file. Initially the version map file for the acl library looks like
> > +this
> > +
> > +.. code-block:: none
> > +
> > + DPDK_2.0 {
> > + global:
> > +
> > + rte_acl_add_rules;
> > + rte_acl_build;
> > + rte_acl_classify;
> > + rte_acl_classify_alg;
> > + rte_acl_classify_scalar;
> > + rte_acl_create;
> > + rte_acl_dump;
> > + rte_acl_find_existing;
> > + rte_acl_free;
> > + rte_acl_ipv4vlan_add_rules;
> > + rte_acl_ipv4vlan_build;
> > + rte_acl_list_dump;
> > + rte_acl_reset;
> > + rte_acl_reset_rules;
> > + rte_acl_set_ctx_classify;
> > +
> > + local: *;
> > + };
> > +
> > +This file needs to be modified as follows
> > +
> > +.. code-block:: none
> > +
> > + DPDK_2.0 {
> > + global:
> > +
> > + rte_acl_add_rules;
> > + rte_acl_build;
> > + rte_acl_classify;
> > + rte_acl_classify_alg;
> > + rte_acl_classify_scalar;
> > + rte_acl_create;
> > + rte_acl_dump;
> > + rte_acl_find_existing;
> > + rte_acl_free;
> > + rte_acl_ipv4vlan_add_rules;
> > + rte_acl_ipv4vlan_build;
> > + rte_acl_list_dump;
> > + rte_acl_reset;
> > + rte_acl_reset_rules;
> > + rte_acl_set_ctx_classify;
> > +
> > + local: *;
> > + };
> > +
> > + DPDK_2.1 {
> > + global:
> > + rte_acl_create;
> One question, does it need a line of "local: *;", like it did in
> librte_ether/rte_ether_version.map?
>
It shouldn't. local just specifies that any symbol not already declared global
be unpublished in the ELF file (i.e. not global). You can declare it again in
the next version node, but since the 2.1 node inherits from the 2.0 node, its
implied.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
2015-06-25 11:35 9% ` Neil Horman
@ 2015-06-25 13:22 7% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-06-25 13:22 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-25 07:35, Neil Horman:
> On Wed, Jun 24, 2015 at 11:09:29PM +0200, Thomas Monjalon wrote:
> > 2015-06-24 14:34, Neil Horman:
> > > +Some ABI changes may be too significant to reasonably maintain multiple
> > > +versions. In those cases ABI's may be updated without backward compatibility
> > > +being provided. The requirements for doing so are:
> > > +
> > > +#. At least 3 acknowledgments of the need to do so must be made on the
> > > + dpdk.org mailing list.
> > > +
> > > +#. A full deprecation cycle, as explained above, must be made to offer
> > > + downstream consumers sufficient warning of the change.
> > > +
> > > +#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
> > > + incorporated must be incremented in parallel with the ABI changes
> > > + themselves.
> >
> > The proposal was to provide the old and the new ABI in the same source code
> > during the deprecation cycle. The old ABI would be the default and people
> > can build the new one by enabling the NEXT_ABI config option.
> > So the migration to the new ABI is smoother.
>
> Yes....I'm not sure what you're saying here. The ABI doesn't 'Change' until the
> old ABI is removed (i.e. old applications are forced to adopt a new ABI), and so
> LIBABIVER has to be updated in parallel with that removal
I'm referring to previous threads suggesting a NEXT_ABI build option to be able
to build the old (default) ABI or the next one.
So the LIBABIVER and .map file would depend of enabling NEXT_ABI or not:
http://dpdk.org/ml/archives/dev/2015-June/019147.html
http://dpdk.org/ml/archives/dev/2015-June/019784.html
http://dpdk.org/ml/archives/dev/2015-June/019810.html
> > [...]
> > > +The macros exported are:
> > > +
> > > +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
> > > + unversioned symbol ``b`` to the internal function ``b_e``.
> >
> > The definition is the same as BASE_SYMBOL.
> >
> No, they're different. VERSION_SYMBOL is defined as:
> VERSION_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@DPDK_" RTE_STR(n))
>
> while BASE_SYMBOL is
> #define BASE_SYMBOL(b, e) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b)"@")
Yes. I mean the comments are the same, so don't reflect the difference.
> > [...]
> > > + DPDK_2.0 {
> > > + global:
> > > +
> > > + rte_acl_add_rules;
> > > + rte_acl_build;
> > > + rte_acl_classify;
> > > + rte_acl_classify_alg;
> > > + rte_acl_classify_scalar;
> > > + rte_acl_create;
> >
> > So it's declared twice, right?
> > I think it should be explicit.
> >
> Yes, its listed once for each version node, so 2 delcarations. I thought that
> was made explicit by the use of the code block. What else would you like to
> see?
I think you should say it explicitly in the comment below the block.
> > > + rte_acl_dump;
> > > + rte_acl_find_existing;
> > > + rte_acl_free;
> > > + rte_acl_ipv4vlan_add_rules;
> > > + rte_acl_ipv4vlan_build;
> > > + rte_acl_list_dump;
> > > + rte_acl_reset;
> > > + rte_acl_reset_rules;
> > > + rte_acl_set_ctx_classify;
> > > +
> > > + local: *;
> > > + };
> > > +
> > > + DPDK_2.1 {
> > > + global:
> > > + rte_acl_create;
> > > +
> > > + } DPDK_2.0;
> > [...]
> > > +the macros used for versioning symbols. That is our next step, mapping this new
> > > +symbol name to the initial symbol name at version node 2.0. Immediately after
> > > +the function, we add this line of code
> > > +
> > > +.. code-block:: c
> > > +
> > > + VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
> >
> > Can it be declared before the function?
> >
> Strictly speaking yes, though its a bit odd from a sylistic point to declare
> versioned aliases for a symbol prior to defining the symbol itself (its like a
> forward declaration)
It allows to declare it near the function header.
> > When do we need to use BASE_SYMBOL?
> >
> For our purposes you currently don't, because there are no unversioned symbols
> in DPDK (since we use a map file). I've just included it here for completeness
> in the header file should it ever be needed in the future.
If it can be useful, please integrate a note to explain when it should be used.
> > [...]
> > > +This code serves as our new API call. Its the same as our old call, but adds
> > > +the new parameter in place. Next we need to map this function to the symbol
> > > +``rte_acl_create@DPDK_2.1``. To do this, we modify the public prototype of the call
> > > +in the header file, adding the macro there to inform all including applications,
> > > +that on re-link, the default rte_acl_create symbol should point to this
> > > +function. Note that we could do this by simply naming the function above
> > > +rte_acl_create, and the linker would chose the most recent version tag to apply
> > > +in the version script, but we can also do this in the header file
> > > +
> > > +.. code-block:: c
> > > +
> > > + struct rte_acl_ctx *
> > > + -rte_acl_create(const struct rte_acl_param *param);
> > > + +rte_acl_create(const struct rte_acl_param *param, int debug);
> > > + +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
> >
> > Will it work with static library?
> >
> hmm, this example in particular? No, I didn't think of that. To work with a
> static build, you still need to define the unversioned symbol. Thats easy
> enough to do though, by either defining rte_acl_create as a public api and
> calling the appropriate versioned function, or by creating a macro to point to
> the right version via an alias. I can fix that easily enough.
Yes please, static libraries are really important in DPDK.
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCH v4 0/9] Dynamic memzone
2015-06-19 17:21 4% ` [dpdk-dev] [PATCH v3 0/9] Dynamic memzone Sergio Gonzalez Monroy
@ 2015-06-25 14:05 4% ` Sergio Gonzalez Monroy
2015-06-25 14:05 1% ` [dpdk-dev] [PATCH v4 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-06-25 14:05 14% ` [dpdk-dev] [PATCH v4 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
2015-06-26 11:32 4% ` [dpdk-dev] [PATCH v5 0/9] Dynamic memzones Sergio Gonzalez Monroy
2015-06-26 15:29 4% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Sergio Gonzalez Monroy
3 siblings, 2 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-25 14:05 UTC (permalink / raw)
To: dev
Current implemetation allows reserving/creating memzones but not the opposite
(unreserve/free). This affects mempools and other memzone based objects.
>From my point of view, implementing free functionality for memzones would look
like malloc over memsegs.
Thus, this approach moves malloc inside eal (which in turn removes a circular
dependency), where malloc heaps are composed of memsegs.
We keep both malloc and memzone APIs as they are, but memzones allocate its
memory by calling malloc_heap_alloc.
Some extra functionality is required in malloc to allow for boundary constrained
memory requests.
In summary, currently malloc is based on memzones, and with this approach
memzones are based on malloc.
v4:
- rebase and fix couple of merge issues
v3:
- Create dummy librte_malloc
- Add deprecation notice
- Rework some of the code
- Doc update
- checkpatch
v2:
- New rte_memzone_free
- Support memzone len = 0
- Add all available memsegs to malloc heap at init
- Update memzone/malloc unit tests
Sergio Gonzalez Monroy (9):
eal: move librte_malloc to eal/common
eal: memzone allocated by malloc
app/test: update malloc/memzone unit tests
config: remove CONFIG_RTE_MALLOC_MEMZONE_SIZE
eal: remove free_memseg and references to it
eal: new rte_memzone_free
app/test: update unit test with rte_memzone_free
doc: announce ABI change of librte_malloc
doc: update malloc documentation
MAINTAINERS | 9 +-
app/test/test_malloc.c | 86 -----
app/test/test_memzone.c | 441 +++-------------------
config/common_bsdapp | 8 +-
config/common_linuxapp | 8 +-
doc/guides/prog_guide/env_abstraction_layer.rst | 220 ++++++++++-
doc/guides/prog_guide/img/malloc_heap.png | Bin 81329 -> 80952 bytes
doc/guides/prog_guide/index.rst | 1 -
doc/guides/prog_guide/malloc_lib.rst | 233 ------------
doc/guides/prog_guide/overview.rst | 11 +-
doc/guides/rel_notes/abi.rst | 1 +
drivers/net/af_packet/Makefile | 1 -
drivers/net/bonding/Makefile | 1 -
drivers/net/e1000/Makefile | 2 +-
drivers/net/enic/Makefile | 2 +-
drivers/net/fm10k/Makefile | 2 +-
drivers/net/i40e/Makefile | 2 +-
drivers/net/ixgbe/Makefile | 2 +-
drivers/net/mlx4/Makefile | 1 -
drivers/net/null/Makefile | 1 -
drivers/net/pcap/Makefile | 1 -
drivers/net/virtio/Makefile | 2 +-
drivers/net/vmxnet3/Makefile | 2 +-
drivers/net/xenvirt/Makefile | 2 +-
lib/Makefile | 2 +-
lib/librte_acl/Makefile | 2 +-
lib/librte_eal/bsdapp/eal/Makefile | 4 +-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 19 +
lib/librte_eal/common/Makefile | 1 +
lib/librte_eal/common/eal_common_memzone.c | 329 ++++++----------
lib/librte_eal/common/include/rte_eal_memconfig.h | 5 +-
lib/librte_eal/common/include/rte_malloc.h | 342 +++++++++++++++++
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/include/rte_memzone.h | 11 +
lib/librte_eal/common/malloc_elem.c | 344 +++++++++++++++++
lib/librte_eal/common/malloc_elem.h | 192 ++++++++++
lib/librte_eal/common/malloc_heap.c | 206 ++++++++++
lib/librte_eal/common/malloc_heap.h | 70 ++++
lib/librte_eal/common/rte_malloc.c | 259 +++++++++++++
lib/librte_eal/linuxapp/eal/Makefile | 4 +-
lib/librte_eal/linuxapp/eal/eal_ivshmem.c | 17 +-
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 19 +
lib/librte_hash/Makefile | 2 +-
lib/librte_lpm/Makefile | 2 +-
lib/librte_malloc/Makefile | 6 +-
lib/librte_malloc/malloc_elem.c | 320 ----------------
lib/librte_malloc/malloc_elem.h | 190 ----------
lib/librte_malloc/malloc_heap.c | 208 ----------
lib/librte_malloc/malloc_heap.h | 70 ----
lib/librte_malloc/rte_malloc.c | 228 +----------
lib/librte_malloc/rte_malloc.h | 342 -----------------
lib/librte_malloc/rte_malloc_version.map | 16 -
lib/librte_mempool/Makefile | 2 -
lib/librte_port/Makefile | 1 -
lib/librte_ring/Makefile | 3 +-
lib/librte_table/Makefile | 1 -
56 files changed, 1897 insertions(+), 2362 deletions(-)
delete mode 100644 doc/guides/prog_guide/malloc_lib.rst
create mode 100644 lib/librte_eal/common/include/rte_malloc.h
create mode 100644 lib/librte_eal/common/malloc_elem.c
create mode 100644 lib/librte_eal/common/malloc_elem.h
create mode 100644 lib/librte_eal/common/malloc_heap.c
create mode 100644 lib/librte_eal/common/malloc_heap.h
create mode 100644 lib/librte_eal/common/rte_malloc.c
delete mode 100644 lib/librte_malloc/malloc_elem.c
delete mode 100644 lib/librte_malloc/malloc_elem.h
delete mode 100644 lib/librte_malloc/malloc_heap.c
delete mode 100644 lib/librte_malloc/malloc_heap.h
delete mode 100644 lib/librte_malloc/rte_malloc.h
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v4 8/9] doc: announce ABI change of librte_malloc
2015-06-25 14:05 4% ` [dpdk-dev] [PATCH v4 0/9] Dynamic memzone Sergio Gonzalez Monroy
2015-06-25 14:05 1% ` [dpdk-dev] [PATCH v4 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
@ 2015-06-25 14:05 14% ` Sergio Gonzalez Monroy
1 sibling, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-25 14:05 UTC (permalink / raw)
To: dev
Announce the creation of dummy malloc library for 2.1 and removal of
such library, now integrated in librte_eal, for 2.2 release.
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
doc/guides/rel_notes/abi.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..2aaf900 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,4 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* librte_malloc library has been integrated into librte_eal. The 2.1 release creates a dummy/empty malloc library to fulfill binaries with dynamic linking dependencies on librte_malloc.so. Such dummy library will not be created from release 2.2 so binaries will need to be rebuilt.
--
1.9.3
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [PATCH v4 2/9] eal: memzone allocated by malloc
2015-06-25 14:05 4% ` [dpdk-dev] [PATCH v4 0/9] Dynamic memzone Sergio Gonzalez Monroy
@ 2015-06-25 14:05 1% ` Sergio Gonzalez Monroy
2015-06-25 14:05 14% ` [dpdk-dev] [PATCH v4 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
1 sibling, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-25 14:05 UTC (permalink / raw)
To: dev
In the current memory hierarchy, memsegs are groups of physically
contiguous hugepages, memzones are slices of memsegs and malloc further
slices memzones into smaller memory chunks.
This patch modifies malloc so it partitions memsegs instead of memzones.
Thus memzones would call malloc internally for memory allocation while
maintaining its ABI.
It would be possible to free memzones and therefore any other structure
based on memzones, ie. mempools
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
lib/librte_eal/common/eal_common_memzone.c | 274 ++++++----------------
lib/librte_eal/common/include/rte_eal_memconfig.h | 2 +-
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/malloc_elem.c | 68 ++++--
lib/librte_eal/common/malloc_elem.h | 14 +-
lib/librte_eal/common/malloc_heap.c | 140 ++++++-----
lib/librte_eal/common/malloc_heap.h | 6 +-
lib/librte_eal/common/rte_malloc.c | 7 +-
8 files changed, 197 insertions(+), 317 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c
index aee184a..943012b 100644
--- a/lib/librte_eal/common/eal_common_memzone.c
+++ b/lib/librte_eal/common/eal_common_memzone.c
@@ -50,15 +50,15 @@
#include <rte_string_fns.h>
#include <rte_common.h>
+#include "malloc_heap.h"
+#include "malloc_elem.h"
#include "eal_private.h"
-/* internal copy of free memory segments */
-static struct rte_memseg *free_memseg = NULL;
-
static inline const struct rte_memzone *
memzone_lookup_thread_unsafe(const char *name)
{
const struct rte_mem_config *mcfg;
+ const struct rte_memzone *mz;
unsigned i = 0;
/* get pointer to global configuration */
@@ -68,8 +68,9 @@ memzone_lookup_thread_unsafe(const char *name)
* the algorithm is not optimal (linear), but there are few
* zones and this function should be called at init only
*/
- for (i = 0; i < RTE_MAX_MEMZONE && mcfg->memzone[i].addr != NULL; i++) {
- if (!strncmp(name, mcfg->memzone[i].name, RTE_MEMZONE_NAMESIZE))
+ for (i = 0; i < RTE_MAX_MEMZONE; i++) {
+ mz = &mcfg->memzone[i];
+ if (mz->addr != NULL && !strncmp(name, mz->name, RTE_MEMZONE_NAMESIZE))
return &mcfg->memzone[i];
}
@@ -88,39 +89,45 @@ rte_memzone_reserve(const char *name, size_t len, int socket_id,
len, socket_id, flags, RTE_CACHE_LINE_SIZE);
}
-/*
- * Helper function for memzone_reserve_aligned_thread_unsafe().
- * Calculate address offset from the start of the segment.
- * Align offset in that way that it satisfy istart alignmnet and
- * buffer of the requested length would not cross specified boundary.
- */
-static inline phys_addr_t
-align_phys_boundary(const struct rte_memseg *ms, size_t len, size_t align,
- size_t bound)
+/* Find the heap with the greatest free block size */
+static void
+find_heap_max_free_elem(int *s, size_t *len, unsigned align)
{
- phys_addr_t addr_offset, bmask, end, start;
- size_t step;
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- step = RTE_MAX(align, bound);
- bmask = ~((phys_addr_t)bound - 1);
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate offset to closest alignment */
- start = RTE_ALIGN_CEIL(ms->phys_addr, align);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size > *len) {
+ *len = stats.greatest_free_size;
+ *s = i;
+ }
+ }
+ *len -= (MALLOC_ELEM_OVERHEAD + align);
+}
- while (addr_offset + len < ms->len) {
+/* Find a heap that can allocate the requested size */
+static void
+find_heap_suitable(int *s, size_t len, unsigned align)
+{
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- /* check, do we meet boundary condition */
- end = start + len - (len != 0);
- if ((start & bmask) == (end & bmask))
- break;
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate next offset */
- start = RTE_ALIGN_CEIL(start + 1, step);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size >= len + MALLOC_ELEM_OVERHEAD + align) {
+ *s = i;
+ break;
+ }
}
-
- return addr_offset;
}
static const struct rte_memzone *
@@ -128,13 +135,7 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
int socket_id, unsigned flags, unsigned align, unsigned bound)
{
struct rte_mem_config *mcfg;
- unsigned i = 0;
- int memseg_idx = -1;
- uint64_t addr_offset, seg_offset = 0;
size_t requested_len;
- size_t memseg_len = 0;
- phys_addr_t memseg_physaddr;
- void *memseg_addr;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
@@ -166,7 +167,6 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
if (align < RTE_CACHE_LINE_SIZE)
align = RTE_CACHE_LINE_SIZE;
-
/* align length on cache boundary. Check for overflow before doing so */
if (len > SIZE_MAX - RTE_CACHE_LINE_MASK) {
rte_errno = EINVAL; /* requested size too big */
@@ -180,129 +180,50 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
requested_len = RTE_MAX((size_t)RTE_CACHE_LINE_SIZE, len);
/* check that boundary condition is valid */
- if (bound != 0 &&
- (requested_len > bound || !rte_is_power_of_2(bound))) {
+ if (bound != 0 && (requested_len > bound || !rte_is_power_of_2(bound))) {
rte_errno = EINVAL;
return NULL;
}
- /* find the smallest segment matching requirements */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- /* last segment */
- if (free_memseg[i].addr == NULL)
- break;
+ if (len == 0) {
+ if (bound != 0)
+ requested_len = bound;
+ else
+ requested_len = 0;
+ }
- /* empty segment, skip it */
- if (free_memseg[i].len == 0)
- continue;
-
- /* bad socket ID */
- if (socket_id != SOCKET_ID_ANY &&
- free_memseg[i].socket_id != SOCKET_ID_ANY &&
- socket_id != free_memseg[i].socket_id)
- continue;
-
- /*
- * calculate offset to closest alignment that
- * meets boundary conditions.
- */
- addr_offset = align_phys_boundary(free_memseg + i,
- requested_len, align, bound);
-
- /* check len */
- if ((requested_len + addr_offset) > free_memseg[i].len)
- continue;
-
- /* check flags for hugepage sizes */
- if ((flags & RTE_MEMZONE_2MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_1G)
- continue;
- if ((flags & RTE_MEMZONE_1GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_2M)
- continue;
- if ((flags & RTE_MEMZONE_16MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16G)
- continue;
- if ((flags & RTE_MEMZONE_16GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16M)
- continue;
-
- /* this segment is the best until now */
- if (memseg_idx == -1) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- /* find the biggest contiguous zone */
- else if (len == 0) {
- if (free_memseg[i].len > memseg_len) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- }
- /*
- * find the smallest (we already checked that current
- * zone length is > len
- */
- else if (free_memseg[i].len + align < memseg_len ||
- (free_memseg[i].len <= memseg_len + align &&
- addr_offset < seg_offset)) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
+ if (socket_id == SOCKET_ID_ANY) {
+ if (requested_len == 0)
+ find_heap_max_free_elem(&socket_id, &requested_len, align);
+ else
+ find_heap_suitable(&socket_id, requested_len, align);
+
+ if (socket_id == SOCKET_ID_ANY) {
+ rte_errno = ENOMEM;
+ return NULL;
}
}
- /* no segment found */
- if (memseg_idx == -1) {
- /*
- * If RTE_MEMZONE_SIZE_HINT_ONLY flag is specified,
- * try allocating again without the size parameter otherwise -fail.
- */
- if ((flags & RTE_MEMZONE_SIZE_HINT_ONLY) &&
- ((flags & RTE_MEMZONE_1GB) || (flags & RTE_MEMZONE_2MB)
- || (flags & RTE_MEMZONE_16MB) || (flags & RTE_MEMZONE_16GB)))
- return memzone_reserve_aligned_thread_unsafe(name,
- len, socket_id, 0, align, bound);
-
+ /* allocate memory on heap */
+ void *mz_addr = malloc_heap_alloc(&mcfg->malloc_heaps[socket_id], NULL,
+ requested_len, flags, align, bound);
+ if (mz_addr == NULL) {
rte_errno = ENOMEM;
return NULL;
}
- /* save aligned physical and virtual addresses */
- memseg_physaddr = free_memseg[memseg_idx].phys_addr + seg_offset;
- memseg_addr = RTE_PTR_ADD(free_memseg[memseg_idx].addr,
- (uintptr_t) seg_offset);
-
- /* if we are looking for a biggest memzone */
- if (len == 0) {
- if (bound == 0)
- requested_len = memseg_len - seg_offset;
- else
- requested_len = RTE_ALIGN_CEIL(memseg_physaddr + 1,
- bound) - memseg_physaddr;
- }
-
- /* set length to correct value */
- len = (size_t)seg_offset + requested_len;
-
- /* update our internal state */
- free_memseg[memseg_idx].len -= len;
- free_memseg[memseg_idx].phys_addr += len;
- free_memseg[memseg_idx].addr =
- (char *)free_memseg[memseg_idx].addr + len;
+ const struct malloc_elem *elem = malloc_elem_from_data(mz_addr);
/* fill the zone in config */
struct rte_memzone *mz = &mcfg->memzone[mcfg->memzone_idx++];
snprintf(mz->name, sizeof(mz->name), "%s", name);
- mz->phys_addr = memseg_physaddr;
- mz->addr = memseg_addr;
- mz->len = requested_len;
- mz->hugepage_sz = free_memseg[memseg_idx].hugepage_sz;
- mz->socket_id = free_memseg[memseg_idx].socket_id;
+ mz->phys_addr = rte_malloc_virt2phy(mz_addr);
+ mz->addr = mz_addr;
+ mz->len = (requested_len == 0 ? elem->size : requested_len);
+ mz->hugepage_sz = elem->ms->hugepage_sz;
+ mz->socket_id = elem->ms->socket_id;
mz->flags = 0;
- mz->memseg_id = memseg_idx;
+ mz->memseg_id = elem->ms - rte_eal_get_configuration()->mem_config->memseg;
return mz;
}
@@ -419,45 +340,6 @@ rte_memzone_dump(FILE *f)
}
/*
- * called by init: modify the free memseg list to have cache-aligned
- * addresses and cache-aligned lengths
- */
-static int
-memseg_sanitize(struct rte_memseg *memseg)
-{
- unsigned phys_align;
- unsigned virt_align;
- unsigned off;
-
- phys_align = memseg->phys_addr & RTE_CACHE_LINE_MASK;
- virt_align = (unsigned long)memseg->addr & RTE_CACHE_LINE_MASK;
-
- /*
- * sanity check: phys_addr and addr must have the same
- * alignment
- */
- if (phys_align != virt_align)
- return -1;
-
- /* memseg is really too small, don't bother with it */
- if (memseg->len < (2 * RTE_CACHE_LINE_SIZE)) {
- memseg->len = 0;
- return 0;
- }
-
- /* align start address */
- off = (RTE_CACHE_LINE_SIZE - phys_align) & RTE_CACHE_LINE_MASK;
- memseg->phys_addr += off;
- memseg->addr = (char *)memseg->addr + off;
- memseg->len -= off;
-
- /* align end address */
- memseg->len &= ~((uint64_t)RTE_CACHE_LINE_MASK);
-
- return 0;
-}
-
-/*
* Init the memzone subsystem
*/
int
@@ -465,14 +347,10 @@ rte_eal_memzone_init(void)
{
struct rte_mem_config *mcfg;
const struct rte_memseg *memseg;
- unsigned i = 0;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
- /* mirror the runtime memsegs from config */
- free_memseg = mcfg->free_memseg;
-
/* secondary processes don't need to initialise anything */
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
return 0;
@@ -485,33 +363,13 @@ rte_eal_memzone_init(void)
rte_rwlock_write_lock(&mcfg->mlock);
- /* fill in uninitialized free_memsegs */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (memseg[i].addr == NULL)
- break;
- if (free_memseg[i].addr != NULL)
- continue;
- memcpy(&free_memseg[i], &memseg[i], sizeof(struct rte_memseg));
- }
-
- /* make all zones cache-aligned */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (free_memseg[i].addr == NULL)
- break;
- if (memseg_sanitize(&free_memseg[i]) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Sanity check failed\n", __func__);
- rte_rwlock_write_unlock(&mcfg->mlock);
- return -1;
- }
- }
-
/* delete all zones */
mcfg->memzone_idx = 0;
memset(mcfg->memzone, 0, sizeof(mcfg->memzone));
rte_rwlock_write_unlock(&mcfg->mlock);
- return 0;
+ return rte_eal_malloc_heap_init();
}
/* Walk all reserved memory zones */
diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h
index 34f5abc..055212a 100644
--- a/lib/librte_eal/common/include/rte_eal_memconfig.h
+++ b/lib/librte_eal/common/include/rte_eal_memconfig.h
@@ -73,7 +73,7 @@ struct rte_mem_config {
struct rte_memseg memseg[RTE_MAX_MEMSEG]; /**< Physmem descriptors. */
struct rte_memzone memzone[RTE_MAX_MEMZONE]; /**< Memzone descriptors. */
- /* Runtime Physmem descriptors. */
+ /* Runtime Physmem descriptors - NOT USED */
struct rte_memseg free_memseg[RTE_MAX_MEMSEG];
struct rte_tailq_head tailq_head[RTE_MAX_TAILQ]; /**< Tailqs for objects */
diff --git a/lib/librte_eal/common/include/rte_malloc_heap.h b/lib/librte_eal/common/include/rte_malloc_heap.h
index 716216f..b270356 100644
--- a/lib/librte_eal/common/include/rte_malloc_heap.h
+++ b/lib/librte_eal/common/include/rte_malloc_heap.h
@@ -40,7 +40,7 @@
#include <rte_memory.h>
/* Number of free lists per heap, grouped by size. */
-#define RTE_HEAP_NUM_FREELISTS 5
+#define RTE_HEAP_NUM_FREELISTS 13
/**
* Structure to hold malloc heap
@@ -48,7 +48,6 @@
struct malloc_heap {
rte_spinlock_t lock;
LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
- unsigned mz_count;
unsigned alloc_count;
size_t total_size;
} __rte_cache_aligned;
diff --git a/lib/librte_eal/common/malloc_elem.c b/lib/librte_eal/common/malloc_elem.c
index a5e1248..b54ee33 100644
--- a/lib/librte_eal/common/malloc_elem.c
+++ b/lib/librte_eal/common/malloc_elem.c
@@ -37,7 +37,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_per_lcore.h>
@@ -56,10 +55,10 @@
*/
void
malloc_elem_init(struct malloc_elem *elem,
- struct malloc_heap *heap, const struct rte_memzone *mz, size_t size)
+ struct malloc_heap *heap, const struct rte_memseg *ms, size_t size)
{
elem->heap = heap;
- elem->mz = mz;
+ elem->ms = ms;
elem->prev = NULL;
memset(&elem->free_list, 0, sizeof(elem->free_list));
elem->state = ELEM_FREE;
@@ -70,12 +69,12 @@ malloc_elem_init(struct malloc_elem *elem,
}
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
{
- malloc_elem_init(elem, prev->heap, prev->mz, 0);
+ malloc_elem_init(elem, prev->heap, prev->ms, 0);
elem->prev = prev;
elem->state = ELEM_BUSY; /* mark busy so its never merged */
}
@@ -86,12 +85,24 @@ malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
* fit, return NULL.
*/
static void *
-elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
+elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- const uintptr_t end_pt = (uintptr_t)elem +
+ const size_t bmask = ~(bound - 1);
+ uintptr_t end_pt = (uintptr_t)elem +
elem->size - MALLOC_ELEM_TRAILER_LEN;
- const uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
- const uintptr_t new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
+ uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ uintptr_t new_elem_start;
+
+ /* check boundary */
+ if ((new_data_start & bmask) != ((end_pt - 1) & bmask)) {
+ end_pt = RTE_ALIGN_FLOOR(end_pt, bound);
+ new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ if (((end_pt - 1) & bmask) != (new_data_start & bmask))
+ return NULL;
+ }
+
+ new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
/* if the new start point is before the exist start, it won't fit */
return (new_elem_start < (uintptr_t)elem) ? NULL : (void *)new_elem_start;
@@ -102,9 +113,10 @@ elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
* alignment request from the current element
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- return elem_start_pt(elem, size, align) != NULL;
+ return elem_start_pt(elem, size, align, bound) != NULL;
}
/*
@@ -115,10 +127,10 @@ static void
split_elem(struct malloc_elem *elem, struct malloc_elem *split_pt)
{
struct malloc_elem *next_elem = RTE_PTR_ADD(elem, elem->size);
- const unsigned old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
- const unsigned new_elem_size = elem->size - old_elem_size;
+ const size_t old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
+ const size_t new_elem_size = elem->size - old_elem_size;
- malloc_elem_init(split_pt, elem->heap, elem->mz, new_elem_size);
+ malloc_elem_init(split_pt, elem->heap, elem->ms, new_elem_size);
split_pt->prev = elem;
next_elem->prev = split_pt;
elem->size = old_elem_size;
@@ -168,8 +180,9 @@ malloc_elem_free_list_index(size_t size)
void
malloc_elem_free_list_insert(struct malloc_elem *elem)
{
- size_t idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
+ size_t idx;
+ idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
elem->state = ELEM_FREE;
LIST_INSERT_HEAD(&elem->heap->free_head[idx], elem, free_list);
}
@@ -190,12 +203,26 @@ elem_free_list_remove(struct malloc_elem *elem)
* is not done here, as it's done there previously.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- struct malloc_elem *new_elem = elem_start_pt(elem, size, align);
- const unsigned old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ struct malloc_elem *new_elem = elem_start_pt(elem, size, align, bound);
+ const size_t old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ const size_t trailer_size = elem->size - old_elem_size - size -
+ MALLOC_ELEM_OVERHEAD;
+
+ elem_free_list_remove(elem);
- if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE){
+ if (trailer_size > MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
+ /* split it, too much free space after elem */
+ struct malloc_elem *new_free_elem =
+ RTE_PTR_ADD(new_elem, size + MALLOC_ELEM_OVERHEAD);
+
+ split_elem(elem, new_free_elem);
+ malloc_elem_free_list_insert(new_free_elem);
+ }
+
+ if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
/* don't split it, pad the element instead */
elem->state = ELEM_BUSY;
elem->pad = old_elem_size;
@@ -208,8 +235,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
new_elem->size = elem->size - elem->pad;
set_header(new_elem);
}
- /* remove element from free list */
- elem_free_list_remove(elem);
return new_elem;
}
@@ -219,7 +244,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
* Re-insert original element, in case its new size makes it
* belong on a different list.
*/
- elem_free_list_remove(elem);
split_elem(elem, new_elem);
new_elem->state = ELEM_BUSY;
malloc_elem_free_list_insert(elem);
diff --git a/lib/librte_eal/common/malloc_elem.h b/lib/librte_eal/common/malloc_elem.h
index 9790b1a..e05d2ea 100644
--- a/lib/librte_eal/common/malloc_elem.h
+++ b/lib/librte_eal/common/malloc_elem.h
@@ -47,9 +47,9 @@ enum elem_state {
struct malloc_elem {
struct malloc_heap *heap;
- struct malloc_elem *volatile prev; /* points to prev elem in memzone */
+ struct malloc_elem *volatile prev; /* points to prev elem in memseg */
LIST_ENTRY(malloc_elem) free_list; /* list of free elements in heap */
- const struct rte_memzone *mz;
+ const struct rte_memseg *ms;
volatile enum elem_state state;
uint32_t pad;
size_t size;
@@ -136,11 +136,11 @@ malloc_elem_from_data(const void *data)
void
malloc_elem_init(struct malloc_elem *elem,
struct malloc_heap *heap,
- const struct rte_memzone *mz,
+ const struct rte_memseg *ms,
size_t size);
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem,
@@ -151,14 +151,16 @@ malloc_elem_mkend(struct malloc_elem *elem,
* of the requested size and with the requested alignment
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* reserve a block of data in an existing malloc_elem. If the malloc_elem
* is much larger than the data block requested, we split the element in two.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_alloc(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* free a malloc_elem block by adding it to the free list. If the
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index 8861d27..f5fff96 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -39,7 +39,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_launch.h>
@@ -54,123 +53,104 @@
#include "malloc_elem.h"
#include "malloc_heap.h"
-/* since the memzone size starts with a digit, it will appear unquoted in
- * rte_config.h, so quote it so it can be passed to rte_str_to_size */
-#define MALLOC_MEMZONE_SIZE RTE_STR(RTE_MALLOC_MEMZONE_SIZE)
-
-/*
- * returns the configuration setting for the memzone size as a size_t value
- */
-static inline size_t
-get_malloc_memzone_size(void)
+static unsigned
+check_hugepage_sz(unsigned flags, size_t hugepage_sz)
{
- return rte_str_to_size(MALLOC_MEMZONE_SIZE);
+ unsigned ret = 1;
+
+ if ((flags & RTE_MEMZONE_2MB) && hugepage_sz == RTE_PGSIZE_1G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_1GB) && hugepage_sz == RTE_PGSIZE_2M)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16MB) && hugepage_sz == RTE_PGSIZE_16G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16GB) && hugepage_sz == RTE_PGSIZE_16M)
+ ret = 0;
+
+ return ret;
}
/*
- * reserve an extra memory zone and make it available for use by a particular
- * heap. This reserves the zone and sets a dummy malloc_elem header at the end
+ * Expand the heap with a memseg.
+ * This reserves the zone and sets a dummy malloc_elem header at the end
* to prevent overflow. The rest of the zone is added to free list as a single
* large free block
*/
-static int
-malloc_heap_add_memzone(struct malloc_heap *heap, size_t size, unsigned align)
+static void
+malloc_heap_add_memseg(struct malloc_heap *heap, struct rte_memseg *ms)
{
- const unsigned mz_flags = 0;
- const size_t block_size = get_malloc_memzone_size();
- /* ensure the data we want to allocate will fit in the memzone */
- const size_t min_size = size + align + MALLOC_ELEM_OVERHEAD * 2;
- const struct rte_memzone *mz = NULL;
- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- unsigned numa_socket = heap - mcfg->malloc_heaps;
-
- size_t mz_size = min_size;
- if (mz_size < block_size)
- mz_size = block_size;
-
- char mz_name[RTE_MEMZONE_NAMESIZE];
- snprintf(mz_name, sizeof(mz_name), "MALLOC_S%u_HEAP_%u",
- numa_socket, heap->mz_count++);
-
- /* try getting a block. if we fail and we don't need as big a block
- * as given in the config, we can shrink our request and try again
- */
- do {
- mz = rte_memzone_reserve(mz_name, mz_size, numa_socket,
- mz_flags);
- if (mz == NULL)
- mz_size /= 2;
- } while (mz == NULL && mz_size > min_size);
- if (mz == NULL)
- return -1;
-
/* allocate the memory block headers, one at end, one at start */
- struct malloc_elem *start_elem = (struct malloc_elem *)mz->addr;
- struct malloc_elem *end_elem = RTE_PTR_ADD(mz->addr,
- mz_size - MALLOC_ELEM_OVERHEAD);
+ struct malloc_elem *start_elem = (struct malloc_elem *)ms->addr;
+ struct malloc_elem *end_elem = RTE_PTR_ADD(ms->addr,
+ ms->len - MALLOC_ELEM_OVERHEAD);
end_elem = RTE_PTR_ALIGN_FLOOR(end_elem, RTE_CACHE_LINE_SIZE);
+ const size_t elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- const unsigned elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- malloc_elem_init(start_elem, heap, mz, elem_size);
+ malloc_elem_init(start_elem, heap, ms, elem_size);
malloc_elem_mkend(end_elem, start_elem);
malloc_elem_free_list_insert(start_elem);
- /* increase heap total size by size of new memzone */
- heap->total_size+=mz_size - MALLOC_ELEM_OVERHEAD;
- return 0;
+ heap->total_size += elem_size;
}
/*
* Iterates through the freelist for a heap to find a free element
* which can store data of the required size and with the requested alignment.
+ * If size is 0, find the biggest available elem.
* Returns null on failure, or pointer to element on success.
*/
static struct malloc_elem *
-find_suitable_element(struct malloc_heap *heap, size_t size, unsigned align)
+find_suitable_element(struct malloc_heap *heap, size_t size,
+ unsigned flags, size_t align, size_t bound)
{
size_t idx;
- struct malloc_elem *elem;
+ struct malloc_elem *elem, *alt_elem = NULL;
for (idx = malloc_elem_free_list_index(size);
- idx < RTE_HEAP_NUM_FREELISTS; idx++)
- {
+ idx < RTE_HEAP_NUM_FREELISTS; idx++) {
for (elem = LIST_FIRST(&heap->free_head[idx]);
- !!elem; elem = LIST_NEXT(elem, free_list))
- {
- if (malloc_elem_can_hold(elem, size, align))
- return elem;
+ !!elem; elem = LIST_NEXT(elem, free_list)) {
+ if (malloc_elem_can_hold(elem, size, align, bound)) {
+ if (check_hugepage_sz(flags, elem->ms->hugepage_sz))
+ return elem;
+ alt_elem = elem;
+ }
}
}
+
+ if ((alt_elem != NULL) && (flags & RTE_MEMZONE_SIZE_HINT_ONLY))
+ return alt_elem;
+
return NULL;
}
/*
- * Main function called by malloc to allocate a block of memory from the
- * heap. It locks the free list, scans it, and adds a new memzone if the
- * scan fails. Once the new memzone is added, it re-scans and should return
+ * Main function to allocate a block of memory from the heap.
+ * It locks the free list, scans it, and adds a new memseg if the
+ * scan fails. Once the new memseg is added, it re-scans and should return
* the new element after releasing the lock.
*/
void *
malloc_heap_alloc(struct malloc_heap *heap,
- const char *type __attribute__((unused)), size_t size, unsigned align)
+ const char *type __attribute__((unused)), size_t size, unsigned flags,
+ size_t align, size_t bound)
{
+ struct malloc_elem *elem;
+
size = RTE_CACHE_LINE_ROUNDUP(size);
align = RTE_CACHE_LINE_ROUNDUP(align);
+
rte_spinlock_lock(&heap->lock);
- struct malloc_elem *elem = find_suitable_element(heap, size, align);
- if (elem == NULL){
- if ((malloc_heap_add_memzone(heap, size, align)) == 0)
- elem = find_suitable_element(heap, size, align);
- }
- if (elem != NULL){
- elem = malloc_elem_alloc(elem, size, align);
+ elem = find_suitable_element(heap, size, flags, align, bound);
+ if (elem != NULL) {
+ elem = malloc_elem_alloc(elem, size, align, bound);
/* increase heap's count of allocated elements */
heap->alloc_count++;
}
rte_spinlock_unlock(&heap->lock);
- return elem == NULL ? NULL : (void *)(&elem[1]);
+ return elem == NULL ? NULL : (void *)(&elem[1]);
}
/*
@@ -206,3 +186,21 @@ malloc_heap_get_stats(const struct malloc_heap *heap,
socket_stats->alloc_count = heap->alloc_count;
return 0;
}
+
+int
+rte_eal_malloc_heap_init(void)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ unsigned ms_cnt;
+ struct rte_memseg *ms;
+
+ if (mcfg == NULL)
+ return -1;
+
+ for (ms = &mcfg->memseg[0], ms_cnt = 0;
+ (ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0);
+ ms_cnt++, ms++)
+ malloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms);
+
+ return 0;
+}
diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h
index a47136d..3ccbef0 100644
--- a/lib/librte_eal/common/malloc_heap.h
+++ b/lib/librte_eal/common/malloc_heap.h
@@ -53,15 +53,15 @@ malloc_get_numa_socket(void)
}
void *
-malloc_heap_alloc(struct malloc_heap *heap, const char *type,
- size_t size, unsigned align);
+malloc_heap_alloc(struct malloc_heap *heap, const char *type, size_t size,
+ unsigned flags, size_t align, size_t bound);
int
malloc_heap_get_stats(const struct malloc_heap *heap,
struct rte_malloc_socket_stats *socket_stats);
int
-rte_eal_heap_memzone_init(void);
+rte_eal_malloc_heap_init(void);
#ifdef __cplusplus
}
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index c313a57..54c2bd8 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -39,7 +39,6 @@
#include <rte_memcpy.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_branch_prediction.h>
@@ -87,7 +86,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
return NULL;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[socket], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL || socket_arg != SOCKET_ID_ANY)
return ret;
@@ -98,7 +97,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
continue;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[i], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL)
return ret;
}
@@ -256,5 +255,5 @@ rte_malloc_virt2phy(const void *addr)
const struct malloc_elem *elem = malloc_elem_from_data(addr);
if (elem == NULL)
return 0;
- return elem->mz->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->mz->addr);
+ return elem->ms->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->ms->addr);
}
--
1.9.3
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCHv3 3/3] ABI: Add some documentation
@ 2015-06-25 14:35 28% ` Neil Horman
2015-06-26 13:00 4% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Neil Horman @ 2015-06-25 14:35 UTC (permalink / raw)
To: dev
People have been asking for ways to use the ABI macros, heres some docs to
clarify their use. Included is:
* An overview of what ABI is
* Details of the ABI deprecation process
* Details of the versioning macros
* Examples of their use
* Details of how to use the ABI validator
Thanks to John Mcnamara, who duplicated much of this effort at Intel while I was
working on it. Much of the introductory material was gathered and cleaned up by
him
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: john.mcnamara@intel.com
CC: thomas.monjalon@6wind.com
Change notes:
v2)
* Fixed RST indentations and spelling errors
* Rebased to upstream to fix index.rst conflict
v3)
* Fixed in tact -> intact
* Added docs to address static linking
* Removed duplicate documentation from release notes
---
doc/guides/guidelines/index.rst | 1 +
doc/guides/guidelines/versioning.rst | 484 +++++++++++++++++++++++++++++++++++
doc/guides/rel_notes/abi.rst | 30 +--
3 files changed, 487 insertions(+), 28 deletions(-)
create mode 100644 doc/guides/guidelines/versioning.rst
diff --git a/doc/guides/guidelines/index.rst b/doc/guides/guidelines/index.rst
index 0ee9ab3..bfb9fa3 100644
--- a/doc/guides/guidelines/index.rst
+++ b/doc/guides/guidelines/index.rst
@@ -7,3 +7,4 @@ Guidelines
coding_style
design
+ versioning
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
new file mode 100644
index 0000000..da9eca0
--- /dev/null
+++ b/doc/guides/guidelines/versioning.rst
@@ -0,0 +1,484 @@
+Managing ABI updates
+====================
+
+Description
+-----------
+
+This document details some methods for handling ABI management in the DPDK.
+Note this document is not exhaustive, in that C library versioning is flexible
+allowing multiple methods to achieve various goals, but it will provide the user
+with some introductory methods
+
+General Guidelines
+------------------
+
+#. Whenever possible, ABI should be preserved
+#. The addition of symbols is generally not problematic
+#. The modification of symbols can generally be managed with versioning
+#. The removal of symbols generally is an ABI break and requires bumping of the
+ LIBABIVER macro
+
+What is an ABI
+--------------
+
+An ABI (Application Binary Interface) is the set of runtime interfaces exposed
+by a library. It is similar to an API (Application Programming Interface) but
+is the result of compilation. It is also effectively cloned when applications
+link to dynamic libraries. That is to say when an application is compiled to
+link against dynamic libraries, it is assumed that the ABI remains constant
+between the time the application is compiled/linked, and the time that it runs.
+Therefore, in the case of dynamic linking, it is critical that an ABI is
+preserved, or (when modified), done in such a way that the application is unable
+to behave improperly or in an unexpected fashion.
+
+The DPDK ABI policy
+-------------------
+
+ABI versions are set at the time of major release labeling, and the ABI may
+change multiple times, without warning, between the last release label and the
+HEAD label of the git tree.
+
+ABI versions, once released, are available until such time as their
+deprecation has been noted in the Release Notes for at least one major release
+cycle. For example consider the case where the ABI for DPDK 2.0 has been
+shipped and then a decision is made to modify it during the development of
+DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
+release and the modification will be made available in the DPDK 2.2 release.
+
+ABI versions may be deprecated in whole or in part as needed by a given
+update.
+
+Some ABI changes may be too significant to reasonably maintain multiple
+versions. In those cases ABI's may be updated without backward compatibility
+being provided. The requirements for doing so are:
+
+#. At least 3 acknowledgments of the need to do so must be made on the
+ dpdk.org mailing list.
+
+#. A full deprecation cycle, as explained above, must be made to offer
+ downstream consumers sufficient warning of the change.
+
+#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
+ incorporated must be incremented in parallel with the ABI changes
+ themselves.
+
+Note that the above process for ABI deprecation should not be undertaken
+lightly. ABI stability is extremely important for downstream consumers of the
+DPDK, especially when distributed in shared object form. Every effort should
+be made to preserve the ABI whenever possible. The ABI should only be changed
+for significant reasons, such as performance enhancements. ABI breakage due to
+changes such as reorganizing public structure fields for aesthetic or
+readability purposes should be avoided.
+
+Examples of Deprecation Notices
+-------------------------------
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+ to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+ in version 2.0. Backwards compatibility will be maintained for this function
+ until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+ performance reasons. Existing binary applications will have backwards
+ compatibility in release 2.0, while newly built binaries will need to
+ reference the new structure variant ``struct rte_foo2``. Compatibility will
+ be removed in release 2.2, and all applications will require updating and
+ rebuilding to the new structure at that time, which will be renamed to the
+ original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+ upcoming release 2.0 will not contain these changes, but release 2.1 will,
+ and no backwards compatibility is planned due to the extensive nature of
+ these changes. Binaries using this library built prior to version 2.1 will
+ require updating and recompilation.
+
+Versioning Macros
+-----------------
+
+When a symbol is exported from a library to provide an API, it also provides a
+calling convention (ABI) that is embodied in its name, return type and
+arguments. Occasionally that function may need to change to accommodate new
+functionality or behavior. When that occurs, it is desirable to allow for
+backward compatibility for a time with older binaries that are dynamically
+linked to the DPDK.
+
+To support backward compatibility the ``lib/librte_compat/rte_compat.h``
+header file provides macros to use when updating exported functions. These
+macros are used in conjunction with the ``rte_<library>_version.map`` file for
+a given library to allow multiple versions of a symbol to exist in a shared
+library so that older binaries need not be immediately recompiled.
+
+The macros exported are:
+
+* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
+ unversioned symbol ``b`` to the internal function ``b_e``.
+
+
+* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
+ unversioned symbol ``b`` to the internal function ``b_e``.
+
+* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
+ the linker to bind references to symbol ``b`` to the internal symbol
+ ``b_e``.
+
+* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the fully
+qualified function ``p``, so that if a symbol becomes versioned, it can still be
+mapped back to the public symbol name.
+
+Examples of ABI Macro use
+-------------------------
+
+Updating a public API
+~~~~~~~~~~~~~~~~~~~~~
+
+Assume we have a function as follows
+
+.. code-block:: c
+
+ /*
+ * Create an acl context object for apps to
+ * manipulate
+ */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param)
+ {
+ ...
+ }
+
+
+Assume that struct rte_acl_ctx is a private structure, and that a developer
+wishes to enhance the acl api so that a debugging flag can be enabled on a
+per-context basis. This requires an addition to the structure (which, being
+private, is safe), but it also requires modifying the code as follows
+
+.. code-block:: c
+
+ /*
+ * Create an acl context object for apps to
+ * manipulate
+ */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param, int debug)
+ {
+ ...
+ }
+
+
+Note also that, being a public function, the header file prototype must also be
+changed, as must all the call sites, to reflect the new ABI footprint. We will
+maintain previous ABI versions that are accessible only to previously compiled
+binaries
+
+The addition of a parameter to the function is ABI breaking as the function is
+public, and existing application may use it in its current form. However, the
+compatibility macros in DPDK allow a developer to use symbol versioning so that
+multiple functions can be mapped to the same public symbol based on when an
+application was linked to it. To see how this is done, we start with the
+requisite libraries version map file. Initially the version map file for the
+acl library looks like this
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_create;
+ rte_acl_dump;
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+This file needs to be modified as follows
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_create;
+ rte_acl_dump;
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+ DPDK_2.1 {
+ global:
+ rte_acl_create;
+
+ } DPDK_2.0;
+
+The addition of the new block tells the linker that a new version node is
+available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
+symbols from the DPDK_2.0 node. This list is directly translated into a list of
+exported symbols when DPDK is compiled as a shared library
+
+Next, we need to specify in the code which function map to the rte_acl_create
+symbol at which versions. First, at the site of the initial symbol definition,
+we need to update the function so that it is uniquely named, and not in conflict
+with the public symbol name
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param)
+ +rte_acl_create_v20(const struct rte_acl_param *param)
+ {
+ size_t sz;
+ struct rte_acl_ctx *ctx;
+ ...
+
+Note that the base name of the symbol was kept intact, as this is condusive to
+the macros used for versioning symbols. That is our next step, mapping this new
+symbol name to the initial symbol name at version node 2.0. Immediately after
+the function, we add this line of code
+
+.. code-block:: c
+
+ VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+Remembering to also add the rte_compat.h header to the requisite c file where
+these changes are being made. The above macro instructs the linker to create a
+new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
+builds, but now points to the above newly named function. We have now mapped
+the original rte_acl_create symbol to the original function (but with a new
+name)
+
+Next, we need to create the 2.1 version of the symbol. We create a new function
+name, with a different suffix, and implement it appropriately
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+ {
+ struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
+
+ ctx->debug = debug;
+
+ return ctx;
+ }
+
+This code serves as our new API call. Its the same as our old call, but adds
+the new parameter in place. Next we need to map this function to the symbol
+``rte_acl_create@DPDK_2.1``. To do this, we modify the public prototype of the call
+in the header file, adding the macro there to inform all including applications,
+that on re-link, the default rte_acl_create symbol should point to this
+function. Note that we could do this by simply naming the function above
+rte_acl_create, and the linker would chose the most recent version tag to apply
+in the version script, but we can also do this in the header file
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param);
+ +rte_acl_create(const struct rte_acl_param *param, int debug);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
+header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
+version node to it. This method is more explicit and flexible than just
+re-implementing the exact symbol name, and allows for other features (such as
+linking to the old symbol version by default, when the new ABI is to be opt-in
+for a period.
+
+One last thing we need to do. Note that we've taken what was a public symbol,
+and duplicated it into two uniquely and differently named symbols. We've then
+mapped each of those back to the public symbol ``rte_acl_create`` with different
+version tags. This only applies to dynamic linking, as static linking has no
+notion of versioning. That leaves this code in a position of no longer having a
+symbol simply named ``rte_acl_create`` and a static build will fail on that
+missing symbol.
+
+To correct this, we can simply map a function of our choosing back to the public
+symbol in the static build with the ``MAP_STATIC_SYMBOL`` macro. Generally the
+assumption is that the most recent version of the symbol is the one you want to
+map. So, back in the C file where, immediately after ``rte_acl_create_v21`` is
+defined, we add this
+
+.. code-block:: c
+
+ struct rte_acl_create_v21(const struct rte_acl_param *param, int debug)
+ {
+ ...
+ }
+ MAP_STATIC_SYMBOL(struct rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v21);
+
+That tells the compiler that, when building a static library, any calls to the
+symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
+
+That's it, on the next shared library rebuild, there will be two versions of
+rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
+and a new DPDK_2.1 version, used by future built applications.
+
+
+Deprecating part of a public API
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Lets assume that you've done the above update, and after a few releases have
+passed you decide you would like to retire the old version of the function.
+After having gone through the ABI deprecation announcement process, removal is
+easy. Start by removing the symbol from the requisite version map file:
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_dump;
+ - rte_acl_create
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+ DPDK_2.1 {
+ global:
+ rte_acl_create;
+ } DPDK_2.0;
+
+
+Next remove the corresponding versioned export
+.. code-block:: c
+
+ -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+
+Note that the internal function definition could also be removed, but its used
+in our example by the newer version _v21, so we leave it in place. This is a
+coding style choice.
+
+Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
+indicate to applications doing dynamic linking that this is a later, and
+possibly incompatible library version:
+
+.. code-block:: c
+
+ -LIBABIVER := 1
+ +LIBABIVER := 2
+
+Deprecating an entire ABI version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+While removing a symbol from and ABI may be useful, it is often more practical
+to remove an entire version node at once. If a version node completely
+specifies an API, then removing part of it, typically makes it incomplete. In
+those cases it is better to remove the entire node
+
+To do this, start by modifying the version map file, such that all symbols from
+the node to be removed are merged into the next node in the map
+
+In the case of our map above, it would transform to look as follows
+
+.. code-block:: none
+
+ DPDK_2.1 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_dump;
+ rte_acl_create
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+Then any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be
+updated to point to the new version node in any header files for all affected
+symbols.
+
+.. code-block:: c
+
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+Lastly, any VERSION_SYMBOL macros that point to the old version node should be
+removed, taking care to keep, where need old code in place to support newer
+versions of the symbol.
+
+Running the ABI Validator
+-------------------------
+
+The ``scripts`` directory in the DPDK source tree contains a utility program,
+``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
+Compliance Checker
+<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
+
+This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
+utilities which can be installed via a package manager. For example::
+
+ sudo yum install abi-compliance-checker
+ sudo yum install abi-dumper
+
+The syntax of the ``validate-abi.sh`` utility is::
+
+ ./scripts/validate-abi.sh <TAG1> <TAG2> <TARGET>
+
+Where ``TAG1`` and ``TAG2`` are valid git tags on the local repo and target is
+the usual DPDK compilation target.
+
+For example to test the current committed HEAD against a previous release tag
+we could add a temporary tag and run the utility as follows::
+
+ git tag MY_TEMP_TAG
+ ./scripts/validate-abi.sh v2.0.0 MY_TEMP_TAG x86_64-native-linuxapp-gcc
+
+After the validation script completes (it can take a while since it need to
+compile both tags) it will create compatibility reports in the
+``./compat_report`` directory. Listed incompatibilities can be found as
+follows::
+
+ grep -lr Incompatible compat_reports/
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..4086198 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -1,33 +1,7 @@
ABI policy
==========
-ABI versions are set at the time of major release labeling, and ABI may change
-multiple times between the last labeling and the HEAD label of the git tree
-without warning.
-
-ABI versions, once released are available until such time as their
-deprecation has been noted here for at least one major release cycle, after it
-has been tagged. E.g. the ABI for DPDK 2.0 is shipped, and then the decision to
-remove it is made during the development of DPDK 2.1. The decision will be
-recorded here, shipped with the DPDK 2.1 release, and actually removed when DPDK
-2.2 ships.
-
-ABI versions may be deprecated in whole, or in part as needed by a given update.
-
-Some ABI changes may be too significant to reasonably maintain multiple
-versions of. In those events ABI's may be updated without backward
-compatibility provided. The requirements for doing so are:
-
-#. At least 3 acknowledgments of the need on the dpdk.org
-#. A full deprecation cycle must be made to offer downstream consumers sufficient warning of the change. E.g. if dpdk 2.0 is under development when the change is proposed, a deprecation notice must be added to this file, and released with dpdk 2.0. Then the change may be incorporated for dpdk 2.1
-#. The LIBABIVER variable in the makefile(s) where the ABI changes are incorporated must be incremented in parallel with the ABI changes themselves
-
-Note that the above process for ABI deprecation should not be undertaken
-lightly. ABI stability is extremely important for downstream consumers of the
-DPDK, especially when distributed in shared object form. Every effort should be
-made to preserve ABI whenever possible. For instance, reorganizing public
-structure field for aesthetic or readability purposes should be avoided as it will
-cause ABI breakage. Only significant (e.g. performance) reasons should be seen
-as cause to alter ABI.
+See the guidelines document for details of the ABI policy. ABI deprecation
+notices are to be posted here
Examples of Deprecation Notices
-------------------------------
--
2.1.0
^ permalink raw reply [relevance 28%]
* [dpdk-dev] [PATCH v2 00/11] Cuckoo hash
@ 2015-06-25 22:05 4% ` Pablo de Lara
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Pablo de Lara @ 2015-06-25 22:05 UTC (permalink / raw)
To: dev
This patchset is to replace the existing hash library with
a more efficient and functional approach, using the Cuckoo hash
method to deal with collisions. This method is based on using
two different hash functions to have two possible locations
in the hash table where an entry can be.
So, if a bucket is full, a new entry can push one of the items
in that bucket to its alternative location, making space for itself.
Advantages
~~~~~~~
- Offers the option to store more entries when the target bucket is full
(unlike the previous implementation)
- Memory efficient: for storing those entries, it is not necessary to
request new memory, as the entries will be stored in the same table
- Constant worst lookup time: in worst case scenario, it always takes
the same time to look up an entry, as there are only two possible locations
where an entry can be.
- Storing data: user can store data in the hash table, unlike the
previous implementation, but he can still use the old API
This implementation tipically offers over 90% utilization.
Notice that API has been extended, but old API remains. The main
change in ABI is that rte_hash structure is now private and the
deprecation of two macros.
Changes in v2:
- Fixed issue where table could not store maximum number of entries
- Fixed issue where lookup burst could not be more than 32 (instead of 64)
- Remove unnecessary macros and add other useful ones
- Added missing library dependencies
- Used directly rte_hash_secondary instead of rte_hash_alt
- Renamed rte_hash.c to rte_cuckoo_hash.c to ease the view of the new library
- Renamed test_hash_perf.c temporarily to ease the view of the improved unit test
- Moved rte_hash, rte_bucket and rte_hash_key structures to rte_cuckoo_hash.c to
make them private
- Corrected copyright dates
- Added an optimized function to compare keys that are multiple of 16 bytes
- Improved the way to use primary/secondary signatures. Now both are stored in
the bucket, so there is no need to calculate them if required.
Also, there is no need to use the MSB of a signature to differenciate between
an empty entry and signature 0, since we are storing both signatures,
which cannot be both 0.
- Removed rte_hash_rehash, as it was a very expensive operation.
Therefore, the add function returns now -ENOSPC if key cannot be added
because of a loop.
- Prefetched new slot for new key in add function to improve performance.
- Made doxygen comments more clear.
- Removed unnecessary rte_hash_del_key_data and rte_hash_del_key_with_data,
as we can use the lookup functions if we want to get the data before deleting.
- Removed some unnecessary includes in rte_hash.h
- Removed some unnecessary variables in rte_cuckoo_hash.c
- Removed some unnecessary checks before creating a new hash table
- Added documentation (in release notes and programmers guide)
- Added new unit tests and replaced the performance one for hash tables
Pablo de Lara (11):
eal: add const in prefetch functions
hash: move rte_hash structure to C file and make it internal
test/hash: enhance hash unit tests
test/hash: rename new hash perf unit test back to original name
hash: replace existing hash library with cuckoo hash implementation
hash: add new lookup_bulk_with_hash function
hash: add new function rte_hash_reset
hash: add new functionality to store data in hash table
MAINTAINERS: claim responsability for hash library
doc: announce ABI change of librte_hash
doc: update hash documentation
MAINTAINERS | 1 +
app/test/test_hash.c | 189 +--
app/test/test_hash_perf.c | 906 ++++++-------
doc/guides/prog_guide/hash_lib.rst | 77 +-
doc/guides/rel_notes/abi.rst | 2 +
.../common/include/arch/ppc_64/rte_prefetch.h | 6 +-
.../common/include/arch/x86/rte_prefetch.h | 14 +-
.../common/include/generic/rte_prefetch.h | 8 +-
lib/librte_hash/Makefile | 8 +-
lib/librte_hash/rte_cuckoo_hash.c | 1394 ++++++++++++++++++++
lib/librte_hash/rte_hash.c | 471 -------
lib/librte_hash/rte_hash.h | 274 +++-
lib/librte_hash/rte_hash_version.map | 15 +
13 files changed, 2191 insertions(+), 1174 deletions(-)
create mode 100644 lib/librte_hash/rte_cuckoo_hash.c
delete mode 100644 lib/librte_hash/rte_hash.c
--
2.4.2
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 10/11] doc: announce ABI change of librte_hash
2015-06-25 22:05 4% ` [dpdk-dev] [PATCH v2 00/11] " Pablo de Lara
@ 2015-06-25 22:05 14% ` Pablo de Lara
2015-06-28 22:25 4% ` [dpdk-dev] [PATCH v3 00/11] Cuckoo hash Pablo de Lara
2 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2015-06-25 22:05 UTC (permalink / raw)
To: dev
rte_hash structure is now private for version 2.1, and two
of the macros in rte_hash.h are now deprecated, so this patch
adds notice of these changes.
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
doc/guides/rel_notes/abi.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..fae09fd 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,5 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* Structure rte_hash in librte_hash library has been changed and has been made private in relese 2.1, as applications should have never accessed to its internal data (library should have been marked as internal).
+* The Macros #RTE_HASH_BUCKET_ENTRIES_MAX and #RTE_HASH_KEY_LENGTH_MAX are deprecated and will be removed with version 2.2.
--
2.4.2
^ permalink raw reply [relevance 14%]
* Re: [dpdk-dev] [PATCH v2 0/4] extend flow director to support L2_paylod type
@ 2015-06-26 2:26 0% ` Xu, HuilongX
2015-06-26 3:14 0% ` Zhang, Helin
1 sibling, 0 replies; 200+ results
From: Xu, HuilongX @ 2015-06-26 2:26 UTC (permalink / raw)
To: Wu, Jingjing, dev
Tested-by:huilong,xu <huilongx.xu@intel.com>
Os: 3.11.10-301.fc20.x86_64
Gcc: gcc version 4.8.3 20140911 (Red Hat 4.8.3-7) (GCC)
Package: d2c08067240baf27f2447bf4981b9ab58ce74d35 + l2payload patch
NIC: Intel Corporation Ethernet Controller XL710 for 40GbE QSFP+ [8086:1583]
Test case Summary: 1 case passed
Test sets:
1. build dpdk with x86_64 gcc target
2. set hugpage and bind igb_uio to Fortville nic
3. ./testpmd -c ffff -n 4 -- -I --portmask=0x3 --disable-rss --rxq=2 --txq=2 --nbcores=8 --pkt-filter-mode=perfect
4. exec testpmd cmdline
a) set verbose 1
b) set fwd rxonly
c) flow_director_filter 0 add flow l2_payload ether 0x0806 flexbytes () fwd queue 1 fd 1
d) start
5. send a arp package to port 0
6. testpmd print port 0 queue 1 received a pachage
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Tuesday, June 16, 2015 11:44 AM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin; Xu, HuilongX
> Subject: [PATCH v2 0/4] extend flow director to support L2_paylod type
>
> This patch set extends flow director to support L2_paylod type in i40e
> driver.
>
> v2 change:
> - remove the flow director VF filtering from this patch to avoid breaking
> ABI.
>
> Jingjing Wu (4):
> ethdev: add struct rte_eth_l2_flow to support l2_payload flow type
> i40e: extend flow diretcor to support l2_payload flow type
> testpmd: extend commands
> doc: extend commands in testpmd
>
> app/test-pmd/cmdline.c | 48
> +++++++++++++++++++++++++++--
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 5 ++-
> drivers/net/i40e/i40e_fdir.c | 24 +++++++++++++--
> lib/librte_ether/rte_eth_ctrl.h | 8 +++++
> 4 files changed, 78 insertions(+), 7 deletions(-)
>
> --
> 1.9.3
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 0/4] extend flow director to support L2_paylod type
2015-06-26 2:26 0% ` Xu, HuilongX
@ 2015-06-26 3:14 0% ` Zhang, Helin
2015-07-07 21:24 0% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Zhang, Helin @ 2015-06-26 3:14 UTC (permalink / raw)
To: Wu, Jingjing, dev
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Tuesday, June 16, 2015 11:44 AM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin; Xu, HuilongX
> Subject: [PATCH v2 0/4] extend flow director to support L2_paylod type
>
> This patch set extends flow director to support L2_paylod type in i40e driver.
>
> v2 change:
> - remove the flow director VF filtering from this patch to avoid breaking ABI.
>
> Jingjing Wu (4):
> ethdev: add struct rte_eth_l2_flow to support l2_payload flow type
> i40e: extend flow diretcor to support l2_payload flow type
> testpmd: extend commands
> doc: extend commands in testpmd
>
> app/test-pmd/cmdline.c | 48
> +++++++++++++++++++++++++++--
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 5 ++-
> drivers/net/i40e/i40e_fdir.c | 24 +++++++++++++--
> lib/librte_ether/rte_eth_ctrl.h | 8 +++++
> 4 files changed, 78 insertions(+), 7 deletions(-)
Acked-by: Helin Zhang <helin.zhang@intel.com>
>
> --
> 1.9.3
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf
@ 2015-06-26 7:03 5% ` Wu, Jingjing
2015-07-06 1:27 0% ` Wu, Jingjing
2015-07-07 14:51 4% ` Thomas Monjalon
0 siblings, 2 replies; 200+ results
From: Wu, Jingjing @ 2015-06-26 7:03 UTC (permalink / raw)
To: 'nhorman@tuxdriver.com'; +Cc: dev
Hi, Neil
About this patch I have an ABI concern about it.
This patch just renamed a struct rte_eth_vmdq_mirror_conf to rte_eth_mirror_conf, the size and its elements don't change. As my understanding, it will not break the ABI. And I also tested it.
But when I use the script ./scripts/validate-abi.sh to check. A low severity problem is reported in symbol "rte_eth_mirror_rule_set"
- Change: "Base type of 2nd parameter mirror_conf has been changed from struct rte_eth_vmdq_mirror_conf to struct rte_eth_mirror_conf."
- Effect: "Replacement of parameter base type may indicate a change in its semantic meaning."
So, I'm not sure whether this patch meet the ABI policy?
Additional, about the validate-abi.sh, does it mean we need to fix all the problems it reports? Or we can decide case by case. Can a Low Severity problem be acceptable?
Look forward to your reply.
Thanks
Jingjing
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Wednesday, June 10, 2015 2:25 PM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Liu, Jijiang; Jiajia, SunX; Zhang, Helin
> Subject: [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf
>
> rename rte_eth_vmdq_mirror_conf to rte_eth_mirror_conf and move the
> maximum rule id check from ethdev level to driver
>
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> ---
> app/test-pmd/cmdline.c | 22 +++++++++++-----------
> drivers/net/ixgbe/ixgbe_ethdev.c | 11 +++++++----
> drivers/net/ixgbe/ixgbe_ethdev.h | 4 +++-
> lib/librte_ether/rte_ethdev.c | 18 ++----------------
> lib/librte_ether/rte_ethdev.h | 19 ++++++++++---------
> 5 files changed, 33 insertions(+), 41 deletions(-)
>
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> f01db2a..d693bde 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -6604,11 +6604,11 @@ cmd_set_mirror_mask_parsed(void
> *parsed_result, {
> int ret,nb_item,i;
> struct cmd_set_mirror_mask_result *res = parsed_result;
> - struct rte_eth_vmdq_mirror_conf mr_conf;
> + struct rte_eth_mirror_conf mr_conf;
>
> - memset(&mr_conf,0,sizeof(struct rte_eth_vmdq_mirror_conf));
> + memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
>
> - unsigned int vlan_list[ETH_VMDQ_MAX_VLAN_FILTERS];
> + unsigned int vlan_list[ETH_MIRROR_MAX_VLANS];
>
> mr_conf.dst_pool = res->dstpool_id;
>
> @@ -6618,11 +6618,11 @@ cmd_set_mirror_mask_parsed(void
> *parsed_result,
> } else if(!strcmp(res->what, "vlan-mirror")) {
> mr_conf.rule_type_mask = ETH_VMDQ_VLAN_MIRROR;
> nb_item = parse_item_list(res->value, "core",
> -
> ETH_VMDQ_MAX_VLAN_FILTERS,vlan_list,1);
> + ETH_MIRROR_MAX_VLANS, vlan_list,
> 1);
> if (nb_item <= 0)
> return;
>
> - for(i=0; i < nb_item; i++) {
> + for (i = 0; i < nb_item; i++) {
> if (vlan_list[i] > ETHER_MAX_VLAN_ID) {
> printf("Invalid vlan_id: must be < 4096\n");
> return;
> @@ -6634,10 +6634,10 @@ cmd_set_mirror_mask_parsed(void
> *parsed_result,
> }
>
> if(!strcmp(res->on, "on"))
> - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
> + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
> res->rule_id, 1);
> else
> - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
> + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
> res->rule_id, 0);
> if(ret < 0)
> printf("mirror rule add error: (%s)\n", strerror(-ret)); @@ -
> 6711,9 +6711,9 @@ cmd_set_mirror_link_parsed(void *parsed_result, {
> int ret;
> struct cmd_set_mirror_link_result *res = parsed_result;
> - struct rte_eth_vmdq_mirror_conf mr_conf;
> + struct rte_eth_mirror_conf mr_conf;
>
> - memset(&mr_conf,0,sizeof(struct rte_eth_vmdq_mirror_conf));
> + memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
> if(!strcmp(res->what, "uplink-mirror")) {
> mr_conf.rule_type_mask = ETH_VMDQ_UPLINK_MIRROR;
> }else if(!strcmp(res->what, "downlink-mirror")) @@ -6722,10
> +6722,10 @@ cmd_set_mirror_link_parsed(void *parsed_result,
> mr_conf.dst_pool = res->dstpool_id;
>
> if(!strcmp(res->on, "on"))
> - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
> + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
> res->rule_id, 1);
> else
> - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
> + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
> res->rule_id, 0);
>
> /* check the return value and print it if is < 0 */ diff --git
> a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 0d9f9b2..9e767fa 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -209,7 +209,7 @@ static int ixgbe_set_pool_tx(struct rte_eth_dev
> *dev,uint16_t pool,uint8_t on); static int ixgbe_set_pool_vlan_filter(struct
> rte_eth_dev *dev, uint16_t vlan,
> uint64_t pool_mask,uint8_t vlan_on);
> static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
> - struct rte_eth_vmdq_mirror_conf *mirror_conf,
> + struct rte_eth_mirror_conf *mirror_conf,
> uint8_t rule_id, uint8_t on);
> static int ixgbe_mirror_rule_reset(struct rte_eth_dev *dev,
> uint8_t rule_id);
> @@ -3388,7 +3388,7 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev
> *dev, uint16_t vlan,
>
> static int
> ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
> - struct rte_eth_vmdq_mirror_conf *mirror_conf,
> + struct rte_eth_mirror_conf *mirror_conf,
> uint8_t rule_id, uint8_t on)
> {
> uint32_t mr_ctl,vlvf;
> @@ -3412,7 +3412,10 @@ ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
> IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>
> if (ixgbe_vmdq_mode_check(hw) < 0)
> - return (-ENOTSUP);
> + return -ENOTSUP;
> +
> + if (rule_id >= IXGBE_MAX_MIRROR_RULES)
> + return -EINVAL;
>
> /* Check if vlan mask is valid */
> if ((mirror_conf->rule_type_mask & ETH_VMDQ_VLAN_MIRROR)
> && (on)) { @@ -3526,7 +3529,7 @@ ixgbe_mirror_rule_reset(struct
> rte_eth_dev *dev, uint8_t rule_id)
> return (-ENOTSUP);
>
> memset(&mr_info->mr_conf[rule_id], 0,
> - sizeof(struct rte_eth_vmdq_mirror_conf));
> + sizeof(struct rte_eth_mirror_conf));
>
> /* clear PFVMCTL register */
> IXGBE_WRITE_REG(hw, IXGBE_MRCTL(rule_id), mr_ctl); diff --git
> a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
> index 19237b8..755b674 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.h
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.h
> @@ -177,8 +177,10 @@ struct ixgbe_uta_info {
> uint32_t uta_shadow[IXGBE_MAX_UTA];
> };
>
> +#define IXGBE_MAX_MIRROR_RULES 4 /* Maximum nb. of mirror rules. */
> +
> struct ixgbe_mirror_info {
> - struct rte_eth_vmdq_mirror_conf
> mr_conf[ETH_VMDQ_NUM_MIRROR_RULE];
> + struct rte_eth_mirror_conf mr_conf[IXGBE_MAX_MIRROR_RULES];
> /**< store PF mirror rules configuration*/ };
>
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 024fe8b..43c7295 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -3034,7 +3034,7 @@ int rte_eth_set_vf_rate_limit(uint8_t port_id,
> uint16_t vf, uint16_t tx_rate,
>
> int
> rte_eth_mirror_rule_set(uint8_t port_id,
> - struct rte_eth_vmdq_mirror_conf *mirror_conf,
> + struct rte_eth_mirror_conf *mirror_conf,
> uint8_t rule_id, uint8_t on)
> {
> struct rte_eth_dev *dev = &rte_eth_devices[port_id]; @@ -3051,7
> +3051,7 @@ rte_eth_mirror_rule_set(uint8_t port_id,
>
> if (mirror_conf->dst_pool >= ETH_64_POOLS) {
> PMD_DEBUG_TRACE("Invalid dst pool, pool id must"
> - "be 0-%d\n",ETH_64_POOLS - 1);
> + "be 0-%d\n", ETH_64_POOLS - 1);
> return -EINVAL;
> }
>
> @@ -3062,13 +3062,6 @@ rte_eth_mirror_rule_set(uint8_t port_id,
> return -EINVAL;
> }
>
> - if(rule_id >= ETH_VMDQ_NUM_MIRROR_RULE)
> - {
> - PMD_DEBUG_TRACE("Invalid rule_id, rule_id must be 0-
> %d\n",
> - ETH_VMDQ_NUM_MIRROR_RULE - 1);
> - return -EINVAL;
> - }
> -
> dev = &rte_eth_devices[port_id];
> FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -
> ENOTSUP);
>
> @@ -3085,13 +3078,6 @@ rte_eth_mirror_rule_reset(uint8_t port_id,
> uint8_t rule_id)
> return -ENODEV;
> }
>
> - if(rule_id >= ETH_VMDQ_NUM_MIRROR_RULE)
> - {
> - PMD_DEBUG_TRACE("Invalid rule_id, rule_id must be 0-
> %d\n",
> - ETH_VMDQ_NUM_MIRROR_RULE-1);
> - return -EINVAL;
> - }
> -
> dev = &rte_eth_devices[port_id];
> FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_reset, -
> ENOTSUP);
>
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 16dbe00..ae22fea 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -467,8 +467,8 @@ struct rte_eth_rss_conf {
> #define ETH_VMDQ_ACCEPT_BROADCAST 0x0008 /**< accept broadcast
> packets. */
> #define ETH_VMDQ_ACCEPT_MULTICAST 0x0010 /**< multicast
> promiscuous. */
>
> -/* Definitions used for VMDQ mirror rules setting */
> -#define ETH_VMDQ_NUM_MIRROR_RULE 4 /**< Maximum nb. of mirror
> rules. . */
> +/** Maximum nb. of vlan per mirror rule */
> +#define ETH_MIRROR_MAX_VLANS 64
>
> #define ETH_VMDQ_POOL_MIRROR 0x0001 /**< Virtual Pool Mirroring. */
> #define ETH_VMDQ_UPLINK_MIRROR 0x0002 /**< Uplink Port Mirroring.
> */ @@ -480,18 +480,19 @@ struct rte_eth_rss_conf {
> */
> struct rte_eth_vlan_mirror {
> uint64_t vlan_mask; /**< mask for valid VLAN ID. */
> - uint16_t vlan_id[ETH_VMDQ_MAX_VLAN_FILTERS];
> - /** VLAN ID list for vlan mirror. */
> + /** VLAN ID list for vlan mirroring. */
> + uint16_t vlan_id[ETH_MIRROR_MAX_VLANS];
> };
>
> /**
> * A structure used to configure traffic mirror of an Ethernet port.
> */
> -struct rte_eth_vmdq_mirror_conf {
> +struct rte_eth_mirror_conf {
> uint8_t rule_type_mask; /**< Mirroring rule type mask we want to
> set */
> - uint8_t dst_pool; /**< Destination pool for this mirror rule. */
> + uint8_t dst_pool; /**< Destination pool for this mirror rule. */
> uint64_t pool_mask; /**< Bitmap of pool for pool mirroring */
> - struct rte_eth_vlan_mirror vlan; /**< VLAN ID setting for VLAN
> mirroring */
> + /** VLAN ID setting for VLAN mirroring. */
> + struct rte_eth_vlan_mirror vlan;
> };
>
> /**
> @@ -1211,7 +1212,7 @@ typedef int (*eth_set_vf_rate_limit_t)(struct
> rte_eth_dev *dev, /**< @internal Set VF TX rate */
>
> typedef int (*eth_mirror_rule_set_t)(struct rte_eth_dev *dev,
> - struct rte_eth_vmdq_mirror_conf
> *mirror_conf,
> + struct rte_eth_mirror_conf *mirror_conf,
> uint8_t rule_id,
> uint8_t on);
> /**< @internal Add a traffic mirroring rule on an Ethernet device */ @@ -
> 3168,7 +3169,7 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t
> vlan_id,
> * - (-EINVAL) if the mr_conf information is not correct.
> */
> int rte_eth_mirror_rule_set(uint8_t port_id,
> - struct rte_eth_vmdq_mirror_conf *mirror_conf,
> + struct rte_eth_mirror_conf *mirror_conf,
> uint8_t rule_id,
> uint8_t on);
>
> --
> 1.9.3
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH v5 2/9] eal: memzone allocated by malloc
2015-06-26 11:32 4% ` [dpdk-dev] [PATCH v5 0/9] Dynamic memzones Sergio Gonzalez Monroy
@ 2015-06-26 11:32 1% ` Sergio Gonzalez Monroy
2015-06-26 11:32 14% ` [dpdk-dev] [PATCH v5 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
1 sibling, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-26 11:32 UTC (permalink / raw)
To: dev
In the current memory hierarchy, memsegs are groups of physically
contiguous hugepages, memzones are slices of memsegs and malloc further
slices memzones into smaller memory chunks.
This patch modifies malloc so it partitions memsegs instead of memzones.
Thus memzones would call malloc internally for memory allocation while
maintaining its ABI.
It would be possible to free memzones and therefore any other structure
based on memzones, ie. mempools
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
lib/librte_eal/common/eal_common_memzone.c | 274 ++++++----------------
lib/librte_eal/common/include/rte_eal_memconfig.h | 2 +-
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/malloc_elem.c | 68 ++++--
lib/librte_eal/common/malloc_elem.h | 14 +-
lib/librte_eal/common/malloc_heap.c | 140 ++++++-----
lib/librte_eal/common/malloc_heap.h | 6 +-
lib/librte_eal/common/rte_malloc.c | 7 +-
8 files changed, 197 insertions(+), 317 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c
index aee184a..943012b 100644
--- a/lib/librte_eal/common/eal_common_memzone.c
+++ b/lib/librte_eal/common/eal_common_memzone.c
@@ -50,15 +50,15 @@
#include <rte_string_fns.h>
#include <rte_common.h>
+#include "malloc_heap.h"
+#include "malloc_elem.h"
#include "eal_private.h"
-/* internal copy of free memory segments */
-static struct rte_memseg *free_memseg = NULL;
-
static inline const struct rte_memzone *
memzone_lookup_thread_unsafe(const char *name)
{
const struct rte_mem_config *mcfg;
+ const struct rte_memzone *mz;
unsigned i = 0;
/* get pointer to global configuration */
@@ -68,8 +68,9 @@ memzone_lookup_thread_unsafe(const char *name)
* the algorithm is not optimal (linear), but there are few
* zones and this function should be called at init only
*/
- for (i = 0; i < RTE_MAX_MEMZONE && mcfg->memzone[i].addr != NULL; i++) {
- if (!strncmp(name, mcfg->memzone[i].name, RTE_MEMZONE_NAMESIZE))
+ for (i = 0; i < RTE_MAX_MEMZONE; i++) {
+ mz = &mcfg->memzone[i];
+ if (mz->addr != NULL && !strncmp(name, mz->name, RTE_MEMZONE_NAMESIZE))
return &mcfg->memzone[i];
}
@@ -88,39 +89,45 @@ rte_memzone_reserve(const char *name, size_t len, int socket_id,
len, socket_id, flags, RTE_CACHE_LINE_SIZE);
}
-/*
- * Helper function for memzone_reserve_aligned_thread_unsafe().
- * Calculate address offset from the start of the segment.
- * Align offset in that way that it satisfy istart alignmnet and
- * buffer of the requested length would not cross specified boundary.
- */
-static inline phys_addr_t
-align_phys_boundary(const struct rte_memseg *ms, size_t len, size_t align,
- size_t bound)
+/* Find the heap with the greatest free block size */
+static void
+find_heap_max_free_elem(int *s, size_t *len, unsigned align)
{
- phys_addr_t addr_offset, bmask, end, start;
- size_t step;
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- step = RTE_MAX(align, bound);
- bmask = ~((phys_addr_t)bound - 1);
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate offset to closest alignment */
- start = RTE_ALIGN_CEIL(ms->phys_addr, align);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size > *len) {
+ *len = stats.greatest_free_size;
+ *s = i;
+ }
+ }
+ *len -= (MALLOC_ELEM_OVERHEAD + align);
+}
- while (addr_offset + len < ms->len) {
+/* Find a heap that can allocate the requested size */
+static void
+find_heap_suitable(int *s, size_t len, unsigned align)
+{
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- /* check, do we meet boundary condition */
- end = start + len - (len != 0);
- if ((start & bmask) == (end & bmask))
- break;
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate next offset */
- start = RTE_ALIGN_CEIL(start + 1, step);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size >= len + MALLOC_ELEM_OVERHEAD + align) {
+ *s = i;
+ break;
+ }
}
-
- return addr_offset;
}
static const struct rte_memzone *
@@ -128,13 +135,7 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
int socket_id, unsigned flags, unsigned align, unsigned bound)
{
struct rte_mem_config *mcfg;
- unsigned i = 0;
- int memseg_idx = -1;
- uint64_t addr_offset, seg_offset = 0;
size_t requested_len;
- size_t memseg_len = 0;
- phys_addr_t memseg_physaddr;
- void *memseg_addr;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
@@ -166,7 +167,6 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
if (align < RTE_CACHE_LINE_SIZE)
align = RTE_CACHE_LINE_SIZE;
-
/* align length on cache boundary. Check for overflow before doing so */
if (len > SIZE_MAX - RTE_CACHE_LINE_MASK) {
rte_errno = EINVAL; /* requested size too big */
@@ -180,129 +180,50 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
requested_len = RTE_MAX((size_t)RTE_CACHE_LINE_SIZE, len);
/* check that boundary condition is valid */
- if (bound != 0 &&
- (requested_len > bound || !rte_is_power_of_2(bound))) {
+ if (bound != 0 && (requested_len > bound || !rte_is_power_of_2(bound))) {
rte_errno = EINVAL;
return NULL;
}
- /* find the smallest segment matching requirements */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- /* last segment */
- if (free_memseg[i].addr == NULL)
- break;
+ if (len == 0) {
+ if (bound != 0)
+ requested_len = bound;
+ else
+ requested_len = 0;
+ }
- /* empty segment, skip it */
- if (free_memseg[i].len == 0)
- continue;
-
- /* bad socket ID */
- if (socket_id != SOCKET_ID_ANY &&
- free_memseg[i].socket_id != SOCKET_ID_ANY &&
- socket_id != free_memseg[i].socket_id)
- continue;
-
- /*
- * calculate offset to closest alignment that
- * meets boundary conditions.
- */
- addr_offset = align_phys_boundary(free_memseg + i,
- requested_len, align, bound);
-
- /* check len */
- if ((requested_len + addr_offset) > free_memseg[i].len)
- continue;
-
- /* check flags for hugepage sizes */
- if ((flags & RTE_MEMZONE_2MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_1G)
- continue;
- if ((flags & RTE_MEMZONE_1GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_2M)
- continue;
- if ((flags & RTE_MEMZONE_16MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16G)
- continue;
- if ((flags & RTE_MEMZONE_16GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16M)
- continue;
-
- /* this segment is the best until now */
- if (memseg_idx == -1) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- /* find the biggest contiguous zone */
- else if (len == 0) {
- if (free_memseg[i].len > memseg_len) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- }
- /*
- * find the smallest (we already checked that current
- * zone length is > len
- */
- else if (free_memseg[i].len + align < memseg_len ||
- (free_memseg[i].len <= memseg_len + align &&
- addr_offset < seg_offset)) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
+ if (socket_id == SOCKET_ID_ANY) {
+ if (requested_len == 0)
+ find_heap_max_free_elem(&socket_id, &requested_len, align);
+ else
+ find_heap_suitable(&socket_id, requested_len, align);
+
+ if (socket_id == SOCKET_ID_ANY) {
+ rte_errno = ENOMEM;
+ return NULL;
}
}
- /* no segment found */
- if (memseg_idx == -1) {
- /*
- * If RTE_MEMZONE_SIZE_HINT_ONLY flag is specified,
- * try allocating again without the size parameter otherwise -fail.
- */
- if ((flags & RTE_MEMZONE_SIZE_HINT_ONLY) &&
- ((flags & RTE_MEMZONE_1GB) || (flags & RTE_MEMZONE_2MB)
- || (flags & RTE_MEMZONE_16MB) || (flags & RTE_MEMZONE_16GB)))
- return memzone_reserve_aligned_thread_unsafe(name,
- len, socket_id, 0, align, bound);
-
+ /* allocate memory on heap */
+ void *mz_addr = malloc_heap_alloc(&mcfg->malloc_heaps[socket_id], NULL,
+ requested_len, flags, align, bound);
+ if (mz_addr == NULL) {
rte_errno = ENOMEM;
return NULL;
}
- /* save aligned physical and virtual addresses */
- memseg_physaddr = free_memseg[memseg_idx].phys_addr + seg_offset;
- memseg_addr = RTE_PTR_ADD(free_memseg[memseg_idx].addr,
- (uintptr_t) seg_offset);
-
- /* if we are looking for a biggest memzone */
- if (len == 0) {
- if (bound == 0)
- requested_len = memseg_len - seg_offset;
- else
- requested_len = RTE_ALIGN_CEIL(memseg_physaddr + 1,
- bound) - memseg_physaddr;
- }
-
- /* set length to correct value */
- len = (size_t)seg_offset + requested_len;
-
- /* update our internal state */
- free_memseg[memseg_idx].len -= len;
- free_memseg[memseg_idx].phys_addr += len;
- free_memseg[memseg_idx].addr =
- (char *)free_memseg[memseg_idx].addr + len;
+ const struct malloc_elem *elem = malloc_elem_from_data(mz_addr);
/* fill the zone in config */
struct rte_memzone *mz = &mcfg->memzone[mcfg->memzone_idx++];
snprintf(mz->name, sizeof(mz->name), "%s", name);
- mz->phys_addr = memseg_physaddr;
- mz->addr = memseg_addr;
- mz->len = requested_len;
- mz->hugepage_sz = free_memseg[memseg_idx].hugepage_sz;
- mz->socket_id = free_memseg[memseg_idx].socket_id;
+ mz->phys_addr = rte_malloc_virt2phy(mz_addr);
+ mz->addr = mz_addr;
+ mz->len = (requested_len == 0 ? elem->size : requested_len);
+ mz->hugepage_sz = elem->ms->hugepage_sz;
+ mz->socket_id = elem->ms->socket_id;
mz->flags = 0;
- mz->memseg_id = memseg_idx;
+ mz->memseg_id = elem->ms - rte_eal_get_configuration()->mem_config->memseg;
return mz;
}
@@ -419,45 +340,6 @@ rte_memzone_dump(FILE *f)
}
/*
- * called by init: modify the free memseg list to have cache-aligned
- * addresses and cache-aligned lengths
- */
-static int
-memseg_sanitize(struct rte_memseg *memseg)
-{
- unsigned phys_align;
- unsigned virt_align;
- unsigned off;
-
- phys_align = memseg->phys_addr & RTE_CACHE_LINE_MASK;
- virt_align = (unsigned long)memseg->addr & RTE_CACHE_LINE_MASK;
-
- /*
- * sanity check: phys_addr and addr must have the same
- * alignment
- */
- if (phys_align != virt_align)
- return -1;
-
- /* memseg is really too small, don't bother with it */
- if (memseg->len < (2 * RTE_CACHE_LINE_SIZE)) {
- memseg->len = 0;
- return 0;
- }
-
- /* align start address */
- off = (RTE_CACHE_LINE_SIZE - phys_align) & RTE_CACHE_LINE_MASK;
- memseg->phys_addr += off;
- memseg->addr = (char *)memseg->addr + off;
- memseg->len -= off;
-
- /* align end address */
- memseg->len &= ~((uint64_t)RTE_CACHE_LINE_MASK);
-
- return 0;
-}
-
-/*
* Init the memzone subsystem
*/
int
@@ -465,14 +347,10 @@ rte_eal_memzone_init(void)
{
struct rte_mem_config *mcfg;
const struct rte_memseg *memseg;
- unsigned i = 0;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
- /* mirror the runtime memsegs from config */
- free_memseg = mcfg->free_memseg;
-
/* secondary processes don't need to initialise anything */
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
return 0;
@@ -485,33 +363,13 @@ rte_eal_memzone_init(void)
rte_rwlock_write_lock(&mcfg->mlock);
- /* fill in uninitialized free_memsegs */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (memseg[i].addr == NULL)
- break;
- if (free_memseg[i].addr != NULL)
- continue;
- memcpy(&free_memseg[i], &memseg[i], sizeof(struct rte_memseg));
- }
-
- /* make all zones cache-aligned */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (free_memseg[i].addr == NULL)
- break;
- if (memseg_sanitize(&free_memseg[i]) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Sanity check failed\n", __func__);
- rte_rwlock_write_unlock(&mcfg->mlock);
- return -1;
- }
- }
-
/* delete all zones */
mcfg->memzone_idx = 0;
memset(mcfg->memzone, 0, sizeof(mcfg->memzone));
rte_rwlock_write_unlock(&mcfg->mlock);
- return 0;
+ return rte_eal_malloc_heap_init();
}
/* Walk all reserved memory zones */
diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h
index 34f5abc..055212a 100644
--- a/lib/librte_eal/common/include/rte_eal_memconfig.h
+++ b/lib/librte_eal/common/include/rte_eal_memconfig.h
@@ -73,7 +73,7 @@ struct rte_mem_config {
struct rte_memseg memseg[RTE_MAX_MEMSEG]; /**< Physmem descriptors. */
struct rte_memzone memzone[RTE_MAX_MEMZONE]; /**< Memzone descriptors. */
- /* Runtime Physmem descriptors. */
+ /* Runtime Physmem descriptors - NOT USED */
struct rte_memseg free_memseg[RTE_MAX_MEMSEG];
struct rte_tailq_head tailq_head[RTE_MAX_TAILQ]; /**< Tailqs for objects */
diff --git a/lib/librte_eal/common/include/rte_malloc_heap.h b/lib/librte_eal/common/include/rte_malloc_heap.h
index 716216f..b270356 100644
--- a/lib/librte_eal/common/include/rte_malloc_heap.h
+++ b/lib/librte_eal/common/include/rte_malloc_heap.h
@@ -40,7 +40,7 @@
#include <rte_memory.h>
/* Number of free lists per heap, grouped by size. */
-#define RTE_HEAP_NUM_FREELISTS 5
+#define RTE_HEAP_NUM_FREELISTS 13
/**
* Structure to hold malloc heap
@@ -48,7 +48,6 @@
struct malloc_heap {
rte_spinlock_t lock;
LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
- unsigned mz_count;
unsigned alloc_count;
size_t total_size;
} __rte_cache_aligned;
diff --git a/lib/librte_eal/common/malloc_elem.c b/lib/librte_eal/common/malloc_elem.c
index a5e1248..b54ee33 100644
--- a/lib/librte_eal/common/malloc_elem.c
+++ b/lib/librte_eal/common/malloc_elem.c
@@ -37,7 +37,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_per_lcore.h>
@@ -56,10 +55,10 @@
*/
void
malloc_elem_init(struct malloc_elem *elem,
- struct malloc_heap *heap, const struct rte_memzone *mz, size_t size)
+ struct malloc_heap *heap, const struct rte_memseg *ms, size_t size)
{
elem->heap = heap;
- elem->mz = mz;
+ elem->ms = ms;
elem->prev = NULL;
memset(&elem->free_list, 0, sizeof(elem->free_list));
elem->state = ELEM_FREE;
@@ -70,12 +69,12 @@ malloc_elem_init(struct malloc_elem *elem,
}
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
{
- malloc_elem_init(elem, prev->heap, prev->mz, 0);
+ malloc_elem_init(elem, prev->heap, prev->ms, 0);
elem->prev = prev;
elem->state = ELEM_BUSY; /* mark busy so its never merged */
}
@@ -86,12 +85,24 @@ malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
* fit, return NULL.
*/
static void *
-elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
+elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- const uintptr_t end_pt = (uintptr_t)elem +
+ const size_t bmask = ~(bound - 1);
+ uintptr_t end_pt = (uintptr_t)elem +
elem->size - MALLOC_ELEM_TRAILER_LEN;
- const uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
- const uintptr_t new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
+ uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ uintptr_t new_elem_start;
+
+ /* check boundary */
+ if ((new_data_start & bmask) != ((end_pt - 1) & bmask)) {
+ end_pt = RTE_ALIGN_FLOOR(end_pt, bound);
+ new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ if (((end_pt - 1) & bmask) != (new_data_start & bmask))
+ return NULL;
+ }
+
+ new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
/* if the new start point is before the exist start, it won't fit */
return (new_elem_start < (uintptr_t)elem) ? NULL : (void *)new_elem_start;
@@ -102,9 +113,10 @@ elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
* alignment request from the current element
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- return elem_start_pt(elem, size, align) != NULL;
+ return elem_start_pt(elem, size, align, bound) != NULL;
}
/*
@@ -115,10 +127,10 @@ static void
split_elem(struct malloc_elem *elem, struct malloc_elem *split_pt)
{
struct malloc_elem *next_elem = RTE_PTR_ADD(elem, elem->size);
- const unsigned old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
- const unsigned new_elem_size = elem->size - old_elem_size;
+ const size_t old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
+ const size_t new_elem_size = elem->size - old_elem_size;
- malloc_elem_init(split_pt, elem->heap, elem->mz, new_elem_size);
+ malloc_elem_init(split_pt, elem->heap, elem->ms, new_elem_size);
split_pt->prev = elem;
next_elem->prev = split_pt;
elem->size = old_elem_size;
@@ -168,8 +180,9 @@ malloc_elem_free_list_index(size_t size)
void
malloc_elem_free_list_insert(struct malloc_elem *elem)
{
- size_t idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
+ size_t idx;
+ idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
elem->state = ELEM_FREE;
LIST_INSERT_HEAD(&elem->heap->free_head[idx], elem, free_list);
}
@@ -190,12 +203,26 @@ elem_free_list_remove(struct malloc_elem *elem)
* is not done here, as it's done there previously.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- struct malloc_elem *new_elem = elem_start_pt(elem, size, align);
- const unsigned old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ struct malloc_elem *new_elem = elem_start_pt(elem, size, align, bound);
+ const size_t old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ const size_t trailer_size = elem->size - old_elem_size - size -
+ MALLOC_ELEM_OVERHEAD;
+
+ elem_free_list_remove(elem);
- if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE){
+ if (trailer_size > MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
+ /* split it, too much free space after elem */
+ struct malloc_elem *new_free_elem =
+ RTE_PTR_ADD(new_elem, size + MALLOC_ELEM_OVERHEAD);
+
+ split_elem(elem, new_free_elem);
+ malloc_elem_free_list_insert(new_free_elem);
+ }
+
+ if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
/* don't split it, pad the element instead */
elem->state = ELEM_BUSY;
elem->pad = old_elem_size;
@@ -208,8 +235,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
new_elem->size = elem->size - elem->pad;
set_header(new_elem);
}
- /* remove element from free list */
- elem_free_list_remove(elem);
return new_elem;
}
@@ -219,7 +244,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
* Re-insert original element, in case its new size makes it
* belong on a different list.
*/
- elem_free_list_remove(elem);
split_elem(elem, new_elem);
new_elem->state = ELEM_BUSY;
malloc_elem_free_list_insert(elem);
diff --git a/lib/librte_eal/common/malloc_elem.h b/lib/librte_eal/common/malloc_elem.h
index 9790b1a..e05d2ea 100644
--- a/lib/librte_eal/common/malloc_elem.h
+++ b/lib/librte_eal/common/malloc_elem.h
@@ -47,9 +47,9 @@ enum elem_state {
struct malloc_elem {
struct malloc_heap *heap;
- struct malloc_elem *volatile prev; /* points to prev elem in memzone */
+ struct malloc_elem *volatile prev; /* points to prev elem in memseg */
LIST_ENTRY(malloc_elem) free_list; /* list of free elements in heap */
- const struct rte_memzone *mz;
+ const struct rte_memseg *ms;
volatile enum elem_state state;
uint32_t pad;
size_t size;
@@ -136,11 +136,11 @@ malloc_elem_from_data(const void *data)
void
malloc_elem_init(struct malloc_elem *elem,
struct malloc_heap *heap,
- const struct rte_memzone *mz,
+ const struct rte_memseg *ms,
size_t size);
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem,
@@ -151,14 +151,16 @@ malloc_elem_mkend(struct malloc_elem *elem,
* of the requested size and with the requested alignment
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* reserve a block of data in an existing malloc_elem. If the malloc_elem
* is much larger than the data block requested, we split the element in two.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_alloc(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* free a malloc_elem block by adding it to the free list. If the
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index 8861d27..f5fff96 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -39,7 +39,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_launch.h>
@@ -54,123 +53,104 @@
#include "malloc_elem.h"
#include "malloc_heap.h"
-/* since the memzone size starts with a digit, it will appear unquoted in
- * rte_config.h, so quote it so it can be passed to rte_str_to_size */
-#define MALLOC_MEMZONE_SIZE RTE_STR(RTE_MALLOC_MEMZONE_SIZE)
-
-/*
- * returns the configuration setting for the memzone size as a size_t value
- */
-static inline size_t
-get_malloc_memzone_size(void)
+static unsigned
+check_hugepage_sz(unsigned flags, size_t hugepage_sz)
{
- return rte_str_to_size(MALLOC_MEMZONE_SIZE);
+ unsigned ret = 1;
+
+ if ((flags & RTE_MEMZONE_2MB) && hugepage_sz == RTE_PGSIZE_1G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_1GB) && hugepage_sz == RTE_PGSIZE_2M)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16MB) && hugepage_sz == RTE_PGSIZE_16G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16GB) && hugepage_sz == RTE_PGSIZE_16M)
+ ret = 0;
+
+ return ret;
}
/*
- * reserve an extra memory zone and make it available for use by a particular
- * heap. This reserves the zone and sets a dummy malloc_elem header at the end
+ * Expand the heap with a memseg.
+ * This reserves the zone and sets a dummy malloc_elem header at the end
* to prevent overflow. The rest of the zone is added to free list as a single
* large free block
*/
-static int
-malloc_heap_add_memzone(struct malloc_heap *heap, size_t size, unsigned align)
+static void
+malloc_heap_add_memseg(struct malloc_heap *heap, struct rte_memseg *ms)
{
- const unsigned mz_flags = 0;
- const size_t block_size = get_malloc_memzone_size();
- /* ensure the data we want to allocate will fit in the memzone */
- const size_t min_size = size + align + MALLOC_ELEM_OVERHEAD * 2;
- const struct rte_memzone *mz = NULL;
- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- unsigned numa_socket = heap - mcfg->malloc_heaps;
-
- size_t mz_size = min_size;
- if (mz_size < block_size)
- mz_size = block_size;
-
- char mz_name[RTE_MEMZONE_NAMESIZE];
- snprintf(mz_name, sizeof(mz_name), "MALLOC_S%u_HEAP_%u",
- numa_socket, heap->mz_count++);
-
- /* try getting a block. if we fail and we don't need as big a block
- * as given in the config, we can shrink our request and try again
- */
- do {
- mz = rte_memzone_reserve(mz_name, mz_size, numa_socket,
- mz_flags);
- if (mz == NULL)
- mz_size /= 2;
- } while (mz == NULL && mz_size > min_size);
- if (mz == NULL)
- return -1;
-
/* allocate the memory block headers, one at end, one at start */
- struct malloc_elem *start_elem = (struct malloc_elem *)mz->addr;
- struct malloc_elem *end_elem = RTE_PTR_ADD(mz->addr,
- mz_size - MALLOC_ELEM_OVERHEAD);
+ struct malloc_elem *start_elem = (struct malloc_elem *)ms->addr;
+ struct malloc_elem *end_elem = RTE_PTR_ADD(ms->addr,
+ ms->len - MALLOC_ELEM_OVERHEAD);
end_elem = RTE_PTR_ALIGN_FLOOR(end_elem, RTE_CACHE_LINE_SIZE);
+ const size_t elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- const unsigned elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- malloc_elem_init(start_elem, heap, mz, elem_size);
+ malloc_elem_init(start_elem, heap, ms, elem_size);
malloc_elem_mkend(end_elem, start_elem);
malloc_elem_free_list_insert(start_elem);
- /* increase heap total size by size of new memzone */
- heap->total_size+=mz_size - MALLOC_ELEM_OVERHEAD;
- return 0;
+ heap->total_size += elem_size;
}
/*
* Iterates through the freelist for a heap to find a free element
* which can store data of the required size and with the requested alignment.
+ * If size is 0, find the biggest available elem.
* Returns null on failure, or pointer to element on success.
*/
static struct malloc_elem *
-find_suitable_element(struct malloc_heap *heap, size_t size, unsigned align)
+find_suitable_element(struct malloc_heap *heap, size_t size,
+ unsigned flags, size_t align, size_t bound)
{
size_t idx;
- struct malloc_elem *elem;
+ struct malloc_elem *elem, *alt_elem = NULL;
for (idx = malloc_elem_free_list_index(size);
- idx < RTE_HEAP_NUM_FREELISTS; idx++)
- {
+ idx < RTE_HEAP_NUM_FREELISTS; idx++) {
for (elem = LIST_FIRST(&heap->free_head[idx]);
- !!elem; elem = LIST_NEXT(elem, free_list))
- {
- if (malloc_elem_can_hold(elem, size, align))
- return elem;
+ !!elem; elem = LIST_NEXT(elem, free_list)) {
+ if (malloc_elem_can_hold(elem, size, align, bound)) {
+ if (check_hugepage_sz(flags, elem->ms->hugepage_sz))
+ return elem;
+ alt_elem = elem;
+ }
}
}
+
+ if ((alt_elem != NULL) && (flags & RTE_MEMZONE_SIZE_HINT_ONLY))
+ return alt_elem;
+
return NULL;
}
/*
- * Main function called by malloc to allocate a block of memory from the
- * heap. It locks the free list, scans it, and adds a new memzone if the
- * scan fails. Once the new memzone is added, it re-scans and should return
+ * Main function to allocate a block of memory from the heap.
+ * It locks the free list, scans it, and adds a new memseg if the
+ * scan fails. Once the new memseg is added, it re-scans and should return
* the new element after releasing the lock.
*/
void *
malloc_heap_alloc(struct malloc_heap *heap,
- const char *type __attribute__((unused)), size_t size, unsigned align)
+ const char *type __attribute__((unused)), size_t size, unsigned flags,
+ size_t align, size_t bound)
{
+ struct malloc_elem *elem;
+
size = RTE_CACHE_LINE_ROUNDUP(size);
align = RTE_CACHE_LINE_ROUNDUP(align);
+
rte_spinlock_lock(&heap->lock);
- struct malloc_elem *elem = find_suitable_element(heap, size, align);
- if (elem == NULL){
- if ((malloc_heap_add_memzone(heap, size, align)) == 0)
- elem = find_suitable_element(heap, size, align);
- }
- if (elem != NULL){
- elem = malloc_elem_alloc(elem, size, align);
+ elem = find_suitable_element(heap, size, flags, align, bound);
+ if (elem != NULL) {
+ elem = malloc_elem_alloc(elem, size, align, bound);
/* increase heap's count of allocated elements */
heap->alloc_count++;
}
rte_spinlock_unlock(&heap->lock);
- return elem == NULL ? NULL : (void *)(&elem[1]);
+ return elem == NULL ? NULL : (void *)(&elem[1]);
}
/*
@@ -206,3 +186,21 @@ malloc_heap_get_stats(const struct malloc_heap *heap,
socket_stats->alloc_count = heap->alloc_count;
return 0;
}
+
+int
+rte_eal_malloc_heap_init(void)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ unsigned ms_cnt;
+ struct rte_memseg *ms;
+
+ if (mcfg == NULL)
+ return -1;
+
+ for (ms = &mcfg->memseg[0], ms_cnt = 0;
+ (ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0);
+ ms_cnt++, ms++)
+ malloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms);
+
+ return 0;
+}
diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h
index a47136d..3ccbef0 100644
--- a/lib/librte_eal/common/malloc_heap.h
+++ b/lib/librte_eal/common/malloc_heap.h
@@ -53,15 +53,15 @@ malloc_get_numa_socket(void)
}
void *
-malloc_heap_alloc(struct malloc_heap *heap, const char *type,
- size_t size, unsigned align);
+malloc_heap_alloc(struct malloc_heap *heap, const char *type, size_t size,
+ unsigned flags, size_t align, size_t bound);
int
malloc_heap_get_stats(const struct malloc_heap *heap,
struct rte_malloc_socket_stats *socket_stats);
int
-rte_eal_heap_memzone_init(void);
+rte_eal_malloc_heap_init(void);
#ifdef __cplusplus
}
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index c313a57..54c2bd8 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -39,7 +39,6 @@
#include <rte_memcpy.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_branch_prediction.h>
@@ -87,7 +86,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
return NULL;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[socket], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL || socket_arg != SOCKET_ID_ANY)
return ret;
@@ -98,7 +97,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
continue;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[i], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL)
return ret;
}
@@ -256,5 +255,5 @@ rte_malloc_virt2phy(const void *addr)
const struct malloc_elem *elem = malloc_elem_from_data(addr);
if (elem == NULL)
return 0;
- return elem->mz->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->mz->addr);
+ return elem->ms->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->ms->addr);
}
--
1.9.3
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v5 0/9] Dynamic memzones
2015-06-19 17:21 4% ` [dpdk-dev] [PATCH v3 0/9] Dynamic memzone Sergio Gonzalez Monroy
2015-06-25 14:05 4% ` [dpdk-dev] [PATCH v4 0/9] Dynamic memzone Sergio Gonzalez Monroy
@ 2015-06-26 11:32 4% ` Sergio Gonzalez Monroy
2015-06-26 11:32 1% ` [dpdk-dev] [PATCH v5 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-06-26 11:32 14% ` [dpdk-dev] [PATCH v5 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
2015-06-26 15:29 4% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Sergio Gonzalez Monroy
3 siblings, 2 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-26 11:32 UTC (permalink / raw)
To: dev
Current implemetation allows reserving/creating memzones but not the opposite
(unreserve/free). This affects mempools and other memzone based objects.
>From my point of view, implementing free functionality for memzones would look
like malloc over memsegs.
Thus, this approach moves malloc inside eal (which in turn removes a circular
dependency), where malloc heaps are composed of memsegs.
We keep both malloc and memzone APIs as they are, but memzones allocate its
memory by calling malloc_heap_alloc.
Some extra functionality is required in malloc to allow for boundary constrained
memory requests.
In summary, currently malloc is based on memzones, and with this approach
memzones are based on malloc.
v5:
- Fix rte_memzone_free
- Improve rte_memzone_free unit test
v4:
- Rebase and fix couple of merge issues
v3:
- Create dummy librte_malloc
- Add deprecation notice
- Rework some of the code
- Doc update
- checkpatch
v2:
- New rte_memzone_free
- Support memzone len = 0
- Add all available memsegs to malloc heap at init
- Update memzone/malloc unit tests
Sergio Gonzalez Monroy (9):
eal: move librte_malloc to eal/common
eal: memzone allocated by malloc
app/test: update malloc/memzone unit tests
config: remove CONFIG_RTE_MALLOC_MEMZONE_SIZE
eal: remove free_memseg and references to it
eal: new rte_memzone_free
app/test: update unit test with rte_memzone_free
doc: announce ABI change of librte_malloc
doc: update malloc documentation
MAINTAINERS | 9 +-
app/test/test_malloc.c | 86 ----
app/test/test_memzone.c | 454 ++++------------------
config/common_bsdapp | 8 +-
config/common_linuxapp | 8 +-
doc/guides/prog_guide/env_abstraction_layer.rst | 220 ++++++++++-
doc/guides/prog_guide/img/malloc_heap.png | Bin 81329 -> 80952 bytes
doc/guides/prog_guide/index.rst | 1 -
doc/guides/prog_guide/malloc_lib.rst | 233 -----------
doc/guides/prog_guide/overview.rst | 11 +-
doc/guides/rel_notes/abi.rst | 1 +
drivers/net/af_packet/Makefile | 1 -
drivers/net/bonding/Makefile | 1 -
drivers/net/e1000/Makefile | 2 +-
drivers/net/enic/Makefile | 2 +-
drivers/net/fm10k/Makefile | 2 +-
drivers/net/i40e/Makefile | 2 +-
drivers/net/ixgbe/Makefile | 2 +-
drivers/net/mlx4/Makefile | 1 -
drivers/net/null/Makefile | 1 -
drivers/net/pcap/Makefile | 1 -
drivers/net/virtio/Makefile | 2 +-
drivers/net/vmxnet3/Makefile | 2 +-
drivers/net/xenvirt/Makefile | 2 +-
lib/Makefile | 2 +-
lib/librte_acl/Makefile | 2 +-
lib/librte_eal/bsdapp/eal/Makefile | 4 +-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 19 +
lib/librte_eal/common/Makefile | 1 +
lib/librte_eal/common/eal_common_memzone.c | 340 +++++++---------
lib/librte_eal/common/include/rte_eal_memconfig.h | 5 +-
lib/librte_eal/common/include/rte_malloc.h | 342 ++++++++++++++++
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/include/rte_memzone.h | 11 +
lib/librte_eal/common/malloc_elem.c | 344 ++++++++++++++++
lib/librte_eal/common/malloc_elem.h | 192 +++++++++
lib/librte_eal/common/malloc_heap.c | 206 ++++++++++
lib/librte_eal/common/malloc_heap.h | 70 ++++
lib/librte_eal/common/rte_malloc.c | 259 ++++++++++++
lib/librte_eal/linuxapp/eal/Makefile | 4 +-
lib/librte_eal/linuxapp/eal/eal_ivshmem.c | 17 +-
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 19 +
lib/librte_hash/Makefile | 2 +-
lib/librte_lpm/Makefile | 2 +-
lib/librte_malloc/Makefile | 6 +-
lib/librte_malloc/malloc_elem.c | 320 ---------------
lib/librte_malloc/malloc_elem.h | 190 ---------
lib/librte_malloc/malloc_heap.c | 208 ----------
lib/librte_malloc/malloc_heap.h | 70 ----
lib/librte_malloc/rte_malloc.c | 228 +----------
lib/librte_malloc/rte_malloc.h | 342 ----------------
lib/librte_malloc/rte_malloc_version.map | 16 -
lib/librte_mempool/Makefile | 2 -
lib/librte_port/Makefile | 1 -
lib/librte_ring/Makefile | 3 +-
lib/librte_table/Makefile | 1 -
56 files changed, 1929 insertions(+), 2354 deletions(-)
delete mode 100644 doc/guides/prog_guide/malloc_lib.rst
create mode 100644 lib/librte_eal/common/include/rte_malloc.h
create mode 100644 lib/librte_eal/common/malloc_elem.c
create mode 100644 lib/librte_eal/common/malloc_elem.h
create mode 100644 lib/librte_eal/common/malloc_heap.c
create mode 100644 lib/librte_eal/common/malloc_heap.h
create mode 100644 lib/librte_eal/common/rte_malloc.c
delete mode 100644 lib/librte_malloc/malloc_elem.c
delete mode 100644 lib/librte_malloc/malloc_elem.h
delete mode 100644 lib/librte_malloc/malloc_heap.c
delete mode 100644 lib/librte_malloc/malloc_heap.h
delete mode 100644 lib/librte_malloc/rte_malloc.h
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v5 8/9] doc: announce ABI change of librte_malloc
2015-06-26 11:32 4% ` [dpdk-dev] [PATCH v5 0/9] Dynamic memzones Sergio Gonzalez Monroy
2015-06-26 11:32 1% ` [dpdk-dev] [PATCH v5 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
@ 2015-06-26 11:32 14% ` Sergio Gonzalez Monroy
1 sibling, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-26 11:32 UTC (permalink / raw)
To: dev
Announce the creation of dummy malloc library for 2.1 and removal of
such library, now integrated in librte_eal, for 2.2 release.
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
doc/guides/rel_notes/abi.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..2aaf900 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,4 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* librte_malloc library has been integrated into librte_eal. The 2.1 release creates a dummy/empty malloc library to fulfill binaries with dynamic linking dependencies on librte_malloc.so. Such dummy library will not be created from release 2.2 so binaries will need to be rebuilt.
--
1.9.3
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [PATCH v3 0/7] Expose IXGBE extended stats to DPDK apps
@ 2015-06-26 12:59 3% Maryam Tahhan
2015-06-26 12:59 9% ` [dpdk-dev] [PATCH v3 4/7] ethdev: remove HW specific stats in stats structs Maryam Tahhan
2015-07-01 14:27 0% ` [dpdk-dev] [PATCH v3 0/7] Expose IXGBE extended stats to DPDK apps Tahhan, Maryam
0 siblings, 2 replies; 200+ results
From: Maryam Tahhan @ 2015-06-26 12:59 UTC (permalink / raw)
To: dev
This patch set implements xstats_get() and xstats_reset() in dev_ops for
ixgbe to expose detailed error statistics to DPDK applications. The
dump_cfg application was extended to demonstrate the usage of
retrieving statistics for DPDK interfaces and renamed to proc_info
in order reflect this new functionality. This patch set also removes non
generic statistics from the statistics strings at the ethdev level and
marks the relevant registers as depricated in struct rte_eth_stats.
v2:
- Fixed patch dependencies.
- Broke down patches into smaller logical changes.
v3:
- Removes non-generic stats fields in rte_stats_strings and deprecates
the fields related to them in struct rte_eth_stats.
- Modifies rte_eth_xstats_get() to return generic stats and extended stats.
Maryam Tahhan (7):
ixgbe: move stats register reads to a new function
ixgbe: add functions to get and reset xstats
ethdev: expose extended error stats
ethdev: remove HW specific stats in stats structs
ixgbe: add NIC specific stats removed from ethdev
app: remove dump_cfg
app: add a new app proc_info
MAINTAINERS | 4 +
app/Makefile | 2 +-
app/dump_cfg/Makefile | 45 ----
app/dump_cfg/main.c | 92 -------
app/proc_info/Makefile | 45 ++++
app/proc_info/main.c | 512 +++++++++++++++++++++++++++++++++++++++
doc/guides/rel_notes/abi.rst | 11 +
drivers/net/ixgbe/ixgbe_ethdev.c | 192 ++++++++++++---
lib/librte_ether/rte_ethdev.c | 29 ++-
lib/librte_ether/rte_ethdev.h | 30 ++-
mk/rte.sdktest.mk | 4 +-
11 files changed, 762 insertions(+), 204 deletions(-)
delete mode 100644 app/dump_cfg/Makefile
delete mode 100644 app/dump_cfg/main.c
create mode 100644 app/proc_info/Makefile
create mode 100644 app/proc_info/main.c
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v3 4/7] ethdev: remove HW specific stats in stats structs
2015-06-26 12:59 3% [dpdk-dev] [PATCH v3 0/7] Expose IXGBE extended stats to DPDK apps Maryam Tahhan
@ 2015-06-26 12:59 9% ` Maryam Tahhan
2015-06-26 14:03 0% ` Kyle Larose
2015-07-01 14:27 0% ` [dpdk-dev] [PATCH v3 0/7] Expose IXGBE extended stats to DPDK apps Tahhan, Maryam
1 sibling, 1 reply; 200+ results
From: Maryam Tahhan @ 2015-06-26 12:59 UTC (permalink / raw)
To: dev
Remove non generic stats in rte_stats_strings and mark the relevant
fields in struct rte_eth_stats as deprecated.
Signed-off-by: Maryam Tahhan <maryam.tahhan@intel.com>
---
doc/guides/rel_notes/abi.rst | 11 +++++++++++
lib/librte_ether/rte_ethdev.c | 9 ---------
lib/librte_ether/rte_ethdev.h | 30 ++++++++++++++++++++----------
3 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..957b13f 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,14 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* The following fields have been deprecated in rte_eth_stats:
+ * uint64_t imissed
+ * uint64_t ibadcrc
+ * uint64_t ibadlen
+ * uint64_t imcasts
+ * uint64_t fdirmatch
+ * uint64_t fdirmiss
+ * uint64_t tx_pause_xon
+ * uint64_t rx_pause_xon
+ * uint64_t tx_pause_xoff
+ * uint64_t rx_pause_xoff
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 6451621..8176baf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -125,17 +125,8 @@ static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
{"rx_bytes", offsetof(struct rte_eth_stats, ibytes)},
{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
- {"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)},
- {"rx_crc_errors", offsetof(struct rte_eth_stats, ibadcrc)},
- {"rx_bad_length_errors", offsetof(struct rte_eth_stats, ibadlen)},
{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
{"alloc_rx_buff_failed", offsetof(struct rte_eth_stats, rx_nombuf)},
- {"fdir_match", offsetof(struct rte_eth_stats, fdirmatch)},
- {"fdir_miss", offsetof(struct rte_eth_stats, fdirmiss)},
- {"tx_flow_control_xon", offsetof(struct rte_eth_stats, tx_pause_xon)},
- {"rx_flow_control_xon", offsetof(struct rte_eth_stats, rx_pause_xon)},
- {"tx_flow_control_xoff", offsetof(struct rte_eth_stats, tx_pause_xoff)},
- {"rx_flow_control_xoff", offsetof(struct rte_eth_stats, rx_pause_xoff)},
};
#define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index f1219ac..a38d49a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -193,19 +193,29 @@ struct rte_eth_stats {
uint64_t opackets; /**< Total number of successfully transmitted packets.*/
uint64_t ibytes; /**< Total number of successfully received bytes. */
uint64_t obytes; /**< Total number of successfully transmitted bytes. */
- uint64_t imissed; /**< Total of RX missed packets (e.g full FIFO). */
- uint64_t ibadcrc; /**< Total of RX packets with CRC error. */
- uint64_t ibadlen; /**< Total of RX packets with bad length. */
+ /**< Deprecated; Total of RX missed packets (e.g full FIFO). */
+ uint64_t imissed;
+ /**< Deprecated; Total of RX packets with CRC error. */
+ uint64_t ibadcrc;
+ /**< Deprecated; Total of RX packets with bad length. */
+ uint64_t ibadlen;
uint64_t ierrors; /**< Total number of erroneous received packets. */
uint64_t oerrors; /**< Total number of failed transmitted packets. */
- uint64_t imcasts; /**< Total number of multicast received packets. */
+ uint64_t imcasts;
+ /**< Deprecated; Total number of multicast received packets. */
uint64_t rx_nombuf; /**< Total number of RX mbuf allocation failures. */
- uint64_t fdirmatch; /**< Total number of RX packets matching a filter. */
- uint64_t fdirmiss; /**< Total number of RX packets not matching any filter. */
- uint64_t tx_pause_xon; /**< Total nb. of XON pause frame sent. */
- uint64_t rx_pause_xon; /**< Total nb. of XON pause frame received. */
- uint64_t tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */
- uint64_t rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */
+ uint64_t fdirmatch;
+ /**< Deprecated; Total number of RX packets matching a filter. */
+ uint64_t fdirmiss;
+ /**< Deprecated; Total number of RX packets not matching any filter. */
+ uint64_t tx_pause_xon;
+ /**< Deprecated; Total nb. of XON pause frame sent. */
+ uint64_t rx_pause_xon;
+ /**< Deprecated; Total nb. of XON pause frame received. */
+ uint64_t tx_pause_xoff;
+ /**< Deprecated; Total nb. of XOFF pause frame sent. */
+ uint64_t rx_pause_xoff;
+ /**< Deprecated; Total nb. of XOFF pause frame received. */
uint64_t q_ipackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
/**< Total number of queue RX packets. */
uint64_t q_opackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
--
1.9.3
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCHv3 3/3] ABI: Add some documentation
2015-06-25 14:35 28% ` [dpdk-dev] [PATCHv3 3/3] ABI: Add some documentation Neil Horman
@ 2015-06-26 13:00 4% ` Thomas Monjalon
2015-06-26 14:54 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-06-26 13:00 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-25 10:35, Neil Horman:
> v3)
> * Fixed in tact -> intact
> * Added docs to address static linking
> * Removed duplicate documentation from release notes
It seems you missed some of my previous comments.
[...]
> +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
> + unversioned symbol ``b`` to the internal function ``b_e``.
Should a versioned symbol <b>@DPDK_<n>
> +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
> + unversioned symbol ``b`` to the internal function ``b_e``.
Please give a use case of BASE_SYMBOL.
[...]
> +The addition of the new block tells the linker that a new version node is
> +available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
> +symbols from the DPDK_2.0 node.
which contains the old version of the symbol rte_acl_create
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 4/7] ethdev: remove HW specific stats in stats structs
2015-06-26 12:59 9% ` [dpdk-dev] [PATCH v3 4/7] ethdev: remove HW specific stats in stats structs Maryam Tahhan
@ 2015-06-26 14:03 0% ` Kyle Larose
2015-06-26 14:30 11% ` Tahhan, Maryam
0 siblings, 1 reply; 200+ results
From: Kyle Larose @ 2015-06-26 14:03 UTC (permalink / raw)
To: Maryam Tahhan; +Cc: dev
On Fri, Jun 26, 2015 at 8:59 AM, Maryam Tahhan <maryam.tahhan@intel.com>
wrote:
> Remove non generic stats in rte_stats_strings and mark the relevant
> fields in struct rte_eth_stats as deprecated.
>
> Signed-off-by: Maryam Tahhan <maryam.tahhan@intel.com>
> ---
> doc/guides/rel_notes/abi.rst | 11 +++++++++++
> lib/librte_ether/rte_ethdev.c | 9 ---------
> lib/librte_ether/rte_ethdev.h | 30 ++++++++++++++++++++----------
> 3 files changed, 31 insertions(+), 19 deletions(-)
>
> diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
> index f00a6ee..957b13f 100644
> --- a/doc/guides/rel_notes/abi.rst
> +++ b/doc/guides/rel_notes/abi.rst
> @@ -38,3 +38,14 @@ Examples of Deprecation Notices
>
> Deprecation Notices
> -------------------
> +* The following fields have been deprecated in rte_eth_stats:
> + * uint64_t imissed
> + * uint64_t ibadcrc
> + * uint64_t ibadlen
> + * uint64_t imcasts
> + * uint64_t fdirmatch
> + * uint64_t fdirmiss
> + * uint64_t tx_pause_xon
> + * uint64_t rx_pause_xon
> + * uint64_t tx_pause_xoff
> + * uint64_t rx_pause_xoff
>
>
Are CRC errors (ibadcrc) truly hardware specific? Which NIC (aside from
purely virtual ones) does not have a MAC which does frame checksumming?
Likewise, which NIC doesn't drop because the PCI bus/cpu/etc is too busy to
pull packets off of it (imissed)?
Debugging interactions with NICs is hard enough with only CRC errors and
missed packets to go on. Without those it is close to impossible. CRC
errors are almost guaranteed any time a bare-metal application is deployed:
dirty fiber, bad SFPs, etc. How will users of the application be able to
determine why their packets are dropping if they can only see "in errors"?
I understand that we want to avoid placing too much useless information
into these statistics structures. However, without a hardware-independent
way of accessing fairly standard networking-equipment diagnostics, I feel
like any real-world application using DPDK will be terribly cumbersome to
build: every single one will need to develop an abstraction layer which
detects the attached NICs, and loads an appropriate driver to integrate
with the xstats api.
Is there any plan for such an API? If not, is it really a good idea to
deprecate these stats?
Thanks,
Kyle
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 4/7] ethdev: remove HW specific stats in stats structs
2015-06-26 14:03 0% ` Kyle Larose
@ 2015-06-26 14:30 11% ` Tahhan, Maryam
2015-06-26 14:37 0% ` Kyle Larose
0 siblings, 1 reply; 200+ results
From: Tahhan, Maryam @ 2015-06-26 14:30 UTC (permalink / raw)
To: Kyle Larose; +Cc: dev
On Fri, Jun 26, 2015 at 8:59 AM, Maryam Tahhan <maryam.tahhan@intel.com<mailto:maryam.tahhan@intel.com>> wrote:
Remove non generic stats in rte_stats_strings and mark the relevant
fields in struct rte_eth_stats as deprecated.
Signed-off-by: Maryam Tahhan <maryam.tahhan@intel.com<mailto:maryam.tahhan@intel.com>>
---
doc/guides/rel_notes/abi.rst | 11 +++++++++++
lib/librte_ether/rte_ethdev.c | 9 ---------
lib/librte_ether/rte_ethdev.h | 30 ++++++++++++++++++++----------
3 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..957b13f 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,14 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* The following fields have been deprecated in rte_eth_stats:
+ * uint64_t imissed
+ * uint64_t ibadcrc
+ * uint64_t ibadlen
+ * uint64_t imcasts
+ * uint64_t fdirmatch
+ * uint64_t fdirmiss
+ * uint64_t tx_pause_xon
+ * uint64_t rx_pause_xon
+ * uint64_t tx_pause_xoff
+ * uint64_t rx_pause_xoff
Are CRC errors (ibadcrc) truly hardware specific? Which NIC (aside from purely virtual ones) does not have a MAC which does frame checksumming? Likewise, which NIC doesn't drop because the PCI bus/cpu/etc is too busy to pull packets off of it (imissed)?
Debugging interactions with NICs is hard enough with only CRC errors and missed packets to go on. Without those it is close to impossible. CRC errors are almost guaranteed any time a bare-metal application is deployed: dirty fiber, bad SFPs, etc. How will users of the application be able to determine why their packets are dropping if they can only see "in errors"?
I understand that we want to avoid placing too much useless information into these statistics structures. However, without a hardware-independent way of accessing fairly standard networking-equipment diagnostics, I feel like any real-world application using DPDK will be terribly cumbersome to build: every single one will need to develop an abstraction layer which detects the attached NICs, and loads an appropriate driver to integrate with the xstats api.
Is there any plan for such an API? If not, is it really a good idea to deprecate these stats?
Thanks,
Kyle
Hi Kyle
If it’s just for debug/diagnostic purposes that this information is being used then I would recommend using the proc_info app which is already integrated with xstats will give you detailed error statistics. It runs as a DPDK secondary process.
I’m not sure about crcerrors and imissed, I had taken feedback to my previous version of the patches onboard and made the changes based on that.
Regards
Maryam
^ permalink raw reply [relevance 11%]
* Re: [dpdk-dev] [PATCHv3 2/3] rte_compat: Add MAP_STATIC_SYMBOL macro
@ 2015-06-26 14:30 3% ` Neil Horman
2015-06-28 20:13 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-06-26 14:30 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Fri, Jun 26, 2015 at 02:52:50PM +0200, Thomas Monjalon wrote:
> 2015-06-25 10:35, Neil Horman:
> > +/*
> > + * MAP_STATIC_SYMBOL
> > + * If a function has been bifurcated into multiple versions, none of which
> > + * are defined as the exported symbol name in the map file, this macro can be
> > + * used to alias a specific version of the symbol to its exported name. For
> > + * example, if you have 2 versions of a function foo_v1 and foo_v2, where the
> > + * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when
> > + * building a shared library, this macro can be used to map either foo_v1 or
> > + * foo_v2 to the symbol foo when building a static library, e.g.:
> > + * MAP_STATIC_SYMBOL(void foo(), foo_v2);
> > + */
> > +#define MAP_STATIC_SYMBOL(f, p)
> > +
> > #else
> > /*
> > * No symbol versioning in use
> > @@ -104,7 +105,7 @@
> > #define __vsym
> > #define BASE_SYMBOL(b, n)
> > #define BIND_DEFAULT_SYMBOL(b, e, n)
> > -
> > +#define MAP_STATIC_SYMBOL(f, p) f __attribute__((alias( RTE_STR(p))))
>
> Is it working with clang and icc?
No idea. It should work with clang (though I don't have it installed at the
moment), as the docs say the .symver directive is supported
as for icc, thats out of my control completely, as I don't have any access to
it.
> Why not just define foo as foo_v2?
I'm not sure what you mean here. Are you suggesting that we just change the abi
so applications have to call foo_v2 rather than foo when we change the
prototype. I suppose we could do that, but that seems like it would be an awful
irritant to users. They would rather have a single symbol to call if it does
the same function.
> As this is the equivalent of BIND_DEFAULT_SYMBOL for the static case,
> it would be easier to mix them in only one macro.
>
Because of where its used. If you use BIND_DEFAULT_SYMBOL to do the work of
MAP_STATIC_SYMBOL, every compilation unit will define its own alias and you'll
get symbol conflicts.
Neil
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 4/7] ethdev: remove HW specific stats in stats structs
2015-06-26 14:30 11% ` Tahhan, Maryam
@ 2015-06-26 14:37 0% ` Kyle Larose
0 siblings, 0 replies; 200+ results
From: Kyle Larose @ 2015-06-26 14:37 UTC (permalink / raw)
To: Tahhan, Maryam; +Cc: dev
Hi Maryam,
I was not aware of the proc_info app. Is there any documentation on dpdk.org
about it, or should I browse the code?
Thanks,
Kyle
On Fri, Jun 26, 2015 at 10:30 AM, Tahhan, Maryam <maryam.tahhan@intel.com>
wrote:
>
>
> On Fri, Jun 26, 2015 at 8:59 AM, Maryam Tahhan <maryam.tahhan@intel.com>
> wrote:
>
> Remove non generic stats in rte_stats_strings and mark the relevant
> fields in struct rte_eth_stats as deprecated.
>
> Signed-off-by: Maryam Tahhan <maryam.tahhan@intel.com>
> ---
> doc/guides/rel_notes/abi.rst | 11 +++++++++++
> lib/librte_ether/rte_ethdev.c | 9 ---------
> lib/librte_ether/rte_ethdev.h | 30 ++++++++++++++++++++----------
> 3 files changed, 31 insertions(+), 19 deletions(-)
>
> diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
> index f00a6ee..957b13f 100644
> --- a/doc/guides/rel_notes/abi.rst
> +++ b/doc/guides/rel_notes/abi.rst
> @@ -38,3 +38,14 @@ Examples of Deprecation Notices
>
> Deprecation Notices
> -------------------
> +* The following fields have been deprecated in rte_eth_stats:
> + * uint64_t imissed
> + * uint64_t ibadcrc
> + * uint64_t ibadlen
> + * uint64_t imcasts
> + * uint64_t fdirmatch
> + * uint64_t fdirmiss
> + * uint64_t tx_pause_xon
> + * uint64_t rx_pause_xon
> + * uint64_t tx_pause_xoff
> + * uint64_t rx_pause_xoff
>
>
>
> Are CRC errors (ibadcrc) truly hardware specific? Which NIC (aside from
> purely virtual ones) does not have a MAC which does frame checksumming?
> Likewise, which NIC doesn't drop because the PCI bus/cpu/etc is too busy to
> pull packets off of it (imissed)?
>
> Debugging interactions with NICs is hard enough with only CRC errors and
> missed packets to go on. Without those it is close to impossible. CRC
> errors are almost guaranteed any time a bare-metal application is deployed:
> dirty fiber, bad SFPs, etc. How will users of the application be able to
> determine why their packets are dropping if they can only see "in errors"?
>
> I understand that we want to avoid placing too much useless information
> into these statistics structures. However, without a hardware-independent
> way of accessing fairly standard networking-equipment diagnostics, I feel
> like any real-world application using DPDK will be terribly cumbersome to
> build: every single one will need to develop an abstraction layer which
> detects the attached NICs, and loads an appropriate driver to integrate
> with the xstats api.
>
>
>
> Is there any plan for such an API? If not, is it really a good idea to
> deprecate these stats?
>
> Thanks,
>
> Kyle
>
>
>
> Hi Kyle
>
>
>
> If it’s just for debug/diagnostic purposes that this information is being
> used then I would recommend using the proc_info app which is already
> integrated with xstats will give you detailed error statistics. It runs as
> a DPDK secondary process.
>
>
>
> I’m not sure about crcerrors and imissed, I had taken feedback to my
> previous version of the patches onboard and made the changes based on that.
>
>
>
> Regards
>
> Maryam
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3 3/3] ABI: Add some documentation
2015-06-26 13:00 4% ` Thomas Monjalon
@ 2015-06-26 14:54 4% ` Neil Horman
2015-06-28 20:24 8% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-06-26 14:54 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Fri, Jun 26, 2015 at 03:00:17PM +0200, Thomas Monjalon wrote:
> 2015-06-25 10:35, Neil Horman:
> > v3)
> > * Fixed in tact -> intact
> > * Added docs to address static linking
> > * Removed duplicate documentation from release notes
>
> It seems you missed some of my previous comments.
>
> [...]
> > +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
> > + unversioned symbol ``b`` to the internal function ``b_e``.
>
> Should a versioned symbol <b>@DPDK_<n>
>
Sure.
> > +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
> > + unversioned symbol ``b`` to the internal function ``b_e``.
>
> Please give a use case of BASE_SYMBOL.
>
No, I'd rather remove it if you really insist. As noted before the way we set
up the version map files means we currently have no need for this particular
directive. I only included it for completeness. I think an example use in
light of that fact would only confuse people. If you're going to draw a line in
the sand around it, I'll just remove it.
> [...]
> > +The addition of the new block tells the linker that a new version node is
> > +available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
> > +symbols from the DPDK_2.0 node.
>
> which contains the old version of the symbol rte_acl_create
>
I don't understand, is it not obvious that the DPDK_2.0 node contains the 2.0
version of the symbol and the DPDK_2.1 node contains the 2.1 version of the
symbol?
Neil
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v6 8/9] doc: announce ABI change of librte_malloc
2015-06-26 15:29 4% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Sergio Gonzalez Monroy
2015-06-26 15:29 1% ` [dpdk-dev] [PATCH v6 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
@ 2015-06-26 15:29 14% ` Sergio Gonzalez Monroy
2015-06-26 16:13 0% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Ananyev, Konstantin
2015-07-03 9:55 4% ` [dpdk-dev] [PATCH v7 " Sergio Gonzalez Monroy
3 siblings, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-26 15:29 UTC (permalink / raw)
To: dev
Announce the creation of dummy malloc library for 2.1 and removal of
such library, now integrated in librte_eal, for 2.2 release.
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
doc/guides/rel_notes/abi.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..2aaf900 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,4 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* librte_malloc library has been integrated into librte_eal. The 2.1 release creates a dummy/empty malloc library to fulfill binaries with dynamic linking dependencies on librte_malloc.so. Such dummy library will not be created from release 2.2 so binaries will need to be rebuilt.
--
1.9.3
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [PATCH v6 0/9] Dynamic memzones
` (2 preceding siblings ...)
2015-06-26 11:32 4% ` [dpdk-dev] [PATCH v5 0/9] Dynamic memzones Sergio Gonzalez Monroy
@ 2015-06-26 15:29 4% ` Sergio Gonzalez Monroy
2015-06-26 15:29 1% ` [dpdk-dev] [PATCH v6 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
` (3 more replies)
3 siblings, 4 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-26 15:29 UTC (permalink / raw)
To: dev
Current implemetation allows reserving/creating memzones but not the opposite
(unreserve/free). This affects mempools and other memzone based objects.
>From my point of view, implementing free functionality for memzones would look
like malloc over memsegs.
Thus, this approach moves malloc inside eal (which in turn removes a circular
dependency), where malloc heaps are composed of memsegs.
We keep both malloc and memzone APIs as they are, but memzones allocate its
memory by calling malloc_heap_alloc.
Some extra functionality is required in malloc to allow for boundary constrained
memory requests.
In summary, currently malloc is based on memzones, and with this approach
memzones are based on malloc.
v6:
- fix bad patch for rte_memzone_free
v5:
- Fix rte_memzone_free
- Improve rte_memzone_free unit test
v4:
- Rebase and fix couple of merge issues
v3:
- Create dummy librte_malloc
- Add deprecation notice
- Rework some of the code
- Doc update
- checkpatch
v2:
- New rte_memzone_free
- Support memzone len = 0
- Add all available memsegs to malloc heap at init
- Update memzone/malloc unit tests
Sergio Gonzalez Monroy (9):
eal: move librte_malloc to eal/common
eal: memzone allocated by malloc
app/test: update malloc/memzone unit tests
config: remove CONFIG_RTE_MALLOC_MEMZONE_SIZE
eal: remove free_memseg and references to it
eal: new rte_memzone_free
app/test: rte_memzone_free unit test
doc: announce ABI change of librte_malloc
doc: update malloc documentation
MAINTAINERS | 9 +-
app/test/test_malloc.c | 86 ----
app/test/test_memzone.c | 456 ++++------------------
config/common_bsdapp | 8 +-
config/common_linuxapp | 8 +-
doc/guides/prog_guide/env_abstraction_layer.rst | 220 ++++++++++-
doc/guides/prog_guide/img/malloc_heap.png | Bin 81329 -> 80952 bytes
doc/guides/prog_guide/index.rst | 1 -
doc/guides/prog_guide/malloc_lib.rst | 233 -----------
doc/guides/prog_guide/overview.rst | 11 +-
doc/guides/rel_notes/abi.rst | 1 +
drivers/net/af_packet/Makefile | 1 -
drivers/net/bonding/Makefile | 1 -
drivers/net/e1000/Makefile | 2 +-
drivers/net/enic/Makefile | 2 +-
drivers/net/fm10k/Makefile | 2 +-
drivers/net/i40e/Makefile | 2 +-
drivers/net/ixgbe/Makefile | 2 +-
drivers/net/mlx4/Makefile | 1 -
drivers/net/null/Makefile | 1 -
drivers/net/pcap/Makefile | 1 -
drivers/net/virtio/Makefile | 2 +-
drivers/net/vmxnet3/Makefile | 2 +-
drivers/net/xenvirt/Makefile | 2 +-
lib/Makefile | 2 +-
lib/librte_acl/Makefile | 2 +-
lib/librte_eal/bsdapp/eal/Makefile | 4 +-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 19 +
lib/librte_eal/common/Makefile | 1 +
lib/librte_eal/common/eal_common_memzone.c | 339 ++++++----------
lib/librte_eal/common/include/rte_eal_memconfig.h | 5 +-
lib/librte_eal/common/include/rte_malloc.h | 342 ++++++++++++++++
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/include/rte_memzone.h | 11 +
lib/librte_eal/common/malloc_elem.c | 344 ++++++++++++++++
lib/librte_eal/common/malloc_elem.h | 192 +++++++++
lib/librte_eal/common/malloc_heap.c | 206 ++++++++++
lib/librte_eal/common/malloc_heap.h | 70 ++++
lib/librte_eal/common/rte_malloc.c | 259 ++++++++++++
lib/librte_eal/linuxapp/eal/Makefile | 4 +-
lib/librte_eal/linuxapp/eal/eal_ivshmem.c | 17 +-
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 19 +
lib/librte_hash/Makefile | 2 +-
lib/librte_lpm/Makefile | 2 +-
lib/librte_malloc/Makefile | 6 +-
lib/librte_malloc/malloc_elem.c | 320 ---------------
lib/librte_malloc/malloc_elem.h | 190 ---------
lib/librte_malloc/malloc_heap.c | 208 ----------
lib/librte_malloc/malloc_heap.h | 70 ----
lib/librte_malloc/rte_malloc.c | 228 +----------
lib/librte_malloc/rte_malloc.h | 342 ----------------
lib/librte_malloc/rte_malloc_version.map | 16 -
lib/librte_mempool/Makefile | 2 -
lib/librte_port/Makefile | 1 -
lib/librte_ring/Makefile | 3 +-
lib/librte_table/Makefile | 1 -
56 files changed, 1928 insertions(+), 2356 deletions(-)
delete mode 100644 doc/guides/prog_guide/malloc_lib.rst
create mode 100644 lib/librte_eal/common/include/rte_malloc.h
create mode 100644 lib/librte_eal/common/malloc_elem.c
create mode 100644 lib/librte_eal/common/malloc_elem.h
create mode 100644 lib/librte_eal/common/malloc_heap.c
create mode 100644 lib/librte_eal/common/malloc_heap.h
create mode 100644 lib/librte_eal/common/rte_malloc.c
delete mode 100644 lib/librte_malloc/malloc_elem.c
delete mode 100644 lib/librte_malloc/malloc_elem.h
delete mode 100644 lib/librte_malloc/malloc_heap.c
delete mode 100644 lib/librte_malloc/malloc_heap.h
delete mode 100644 lib/librte_malloc/rte_malloc.h
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v6 2/9] eal: memzone allocated by malloc
2015-06-26 15:29 4% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Sergio Gonzalez Monroy
@ 2015-06-26 15:29 1% ` Sergio Gonzalez Monroy
2015-06-26 15:29 14% ` [dpdk-dev] [PATCH v6 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
` (2 subsequent siblings)
3 siblings, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-06-26 15:29 UTC (permalink / raw)
To: dev
In the current memory hierarchy, memsegs are groups of physically
contiguous hugepages, memzones are slices of memsegs and malloc further
slices memzones into smaller memory chunks.
This patch modifies malloc so it partitions memsegs instead of memzones.
Thus memzones would call malloc internally for memory allocation while
maintaining its ABI.
It would be possible to free memzones and therefore any other structure
based on memzones, ie. mempools
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
lib/librte_eal/common/eal_common_memzone.c | 274 ++++++----------------
lib/librte_eal/common/include/rte_eal_memconfig.h | 2 +-
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/malloc_elem.c | 68 ++++--
lib/librte_eal/common/malloc_elem.h | 14 +-
lib/librte_eal/common/malloc_heap.c | 140 ++++++-----
lib/librte_eal/common/malloc_heap.h | 6 +-
lib/librte_eal/common/rte_malloc.c | 7 +-
8 files changed, 197 insertions(+), 317 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c
index aee184a..943012b 100644
--- a/lib/librte_eal/common/eal_common_memzone.c
+++ b/lib/librte_eal/common/eal_common_memzone.c
@@ -50,15 +50,15 @@
#include <rte_string_fns.h>
#include <rte_common.h>
+#include "malloc_heap.h"
+#include "malloc_elem.h"
#include "eal_private.h"
-/* internal copy of free memory segments */
-static struct rte_memseg *free_memseg = NULL;
-
static inline const struct rte_memzone *
memzone_lookup_thread_unsafe(const char *name)
{
const struct rte_mem_config *mcfg;
+ const struct rte_memzone *mz;
unsigned i = 0;
/* get pointer to global configuration */
@@ -68,8 +68,9 @@ memzone_lookup_thread_unsafe(const char *name)
* the algorithm is not optimal (linear), but there are few
* zones and this function should be called at init only
*/
- for (i = 0; i < RTE_MAX_MEMZONE && mcfg->memzone[i].addr != NULL; i++) {
- if (!strncmp(name, mcfg->memzone[i].name, RTE_MEMZONE_NAMESIZE))
+ for (i = 0; i < RTE_MAX_MEMZONE; i++) {
+ mz = &mcfg->memzone[i];
+ if (mz->addr != NULL && !strncmp(name, mz->name, RTE_MEMZONE_NAMESIZE))
return &mcfg->memzone[i];
}
@@ -88,39 +89,45 @@ rte_memzone_reserve(const char *name, size_t len, int socket_id,
len, socket_id, flags, RTE_CACHE_LINE_SIZE);
}
-/*
- * Helper function for memzone_reserve_aligned_thread_unsafe().
- * Calculate address offset from the start of the segment.
- * Align offset in that way that it satisfy istart alignmnet and
- * buffer of the requested length would not cross specified boundary.
- */
-static inline phys_addr_t
-align_phys_boundary(const struct rte_memseg *ms, size_t len, size_t align,
- size_t bound)
+/* Find the heap with the greatest free block size */
+static void
+find_heap_max_free_elem(int *s, size_t *len, unsigned align)
{
- phys_addr_t addr_offset, bmask, end, start;
- size_t step;
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- step = RTE_MAX(align, bound);
- bmask = ~((phys_addr_t)bound - 1);
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate offset to closest alignment */
- start = RTE_ALIGN_CEIL(ms->phys_addr, align);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size > *len) {
+ *len = stats.greatest_free_size;
+ *s = i;
+ }
+ }
+ *len -= (MALLOC_ELEM_OVERHEAD + align);
+}
- while (addr_offset + len < ms->len) {
+/* Find a heap that can allocate the requested size */
+static void
+find_heap_suitable(int *s, size_t len, unsigned align)
+{
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- /* check, do we meet boundary condition */
- end = start + len - (len != 0);
- if ((start & bmask) == (end & bmask))
- break;
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate next offset */
- start = RTE_ALIGN_CEIL(start + 1, step);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size >= len + MALLOC_ELEM_OVERHEAD + align) {
+ *s = i;
+ break;
+ }
}
-
- return addr_offset;
}
static const struct rte_memzone *
@@ -128,13 +135,7 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
int socket_id, unsigned flags, unsigned align, unsigned bound)
{
struct rte_mem_config *mcfg;
- unsigned i = 0;
- int memseg_idx = -1;
- uint64_t addr_offset, seg_offset = 0;
size_t requested_len;
- size_t memseg_len = 0;
- phys_addr_t memseg_physaddr;
- void *memseg_addr;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
@@ -166,7 +167,6 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
if (align < RTE_CACHE_LINE_SIZE)
align = RTE_CACHE_LINE_SIZE;
-
/* align length on cache boundary. Check for overflow before doing so */
if (len > SIZE_MAX - RTE_CACHE_LINE_MASK) {
rte_errno = EINVAL; /* requested size too big */
@@ -180,129 +180,50 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
requested_len = RTE_MAX((size_t)RTE_CACHE_LINE_SIZE, len);
/* check that boundary condition is valid */
- if (bound != 0 &&
- (requested_len > bound || !rte_is_power_of_2(bound))) {
+ if (bound != 0 && (requested_len > bound || !rte_is_power_of_2(bound))) {
rte_errno = EINVAL;
return NULL;
}
- /* find the smallest segment matching requirements */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- /* last segment */
- if (free_memseg[i].addr == NULL)
- break;
+ if (len == 0) {
+ if (bound != 0)
+ requested_len = bound;
+ else
+ requested_len = 0;
+ }
- /* empty segment, skip it */
- if (free_memseg[i].len == 0)
- continue;
-
- /* bad socket ID */
- if (socket_id != SOCKET_ID_ANY &&
- free_memseg[i].socket_id != SOCKET_ID_ANY &&
- socket_id != free_memseg[i].socket_id)
- continue;
-
- /*
- * calculate offset to closest alignment that
- * meets boundary conditions.
- */
- addr_offset = align_phys_boundary(free_memseg + i,
- requested_len, align, bound);
-
- /* check len */
- if ((requested_len + addr_offset) > free_memseg[i].len)
- continue;
-
- /* check flags for hugepage sizes */
- if ((flags & RTE_MEMZONE_2MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_1G)
- continue;
- if ((flags & RTE_MEMZONE_1GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_2M)
- continue;
- if ((flags & RTE_MEMZONE_16MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16G)
- continue;
- if ((flags & RTE_MEMZONE_16GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16M)
- continue;
-
- /* this segment is the best until now */
- if (memseg_idx == -1) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- /* find the biggest contiguous zone */
- else if (len == 0) {
- if (free_memseg[i].len > memseg_len) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- }
- /*
- * find the smallest (we already checked that current
- * zone length is > len
- */
- else if (free_memseg[i].len + align < memseg_len ||
- (free_memseg[i].len <= memseg_len + align &&
- addr_offset < seg_offset)) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
+ if (socket_id == SOCKET_ID_ANY) {
+ if (requested_len == 0)
+ find_heap_max_free_elem(&socket_id, &requested_len, align);
+ else
+ find_heap_suitable(&socket_id, requested_len, align);
+
+ if (socket_id == SOCKET_ID_ANY) {
+ rte_errno = ENOMEM;
+ return NULL;
}
}
- /* no segment found */
- if (memseg_idx == -1) {
- /*
- * If RTE_MEMZONE_SIZE_HINT_ONLY flag is specified,
- * try allocating again without the size parameter otherwise -fail.
- */
- if ((flags & RTE_MEMZONE_SIZE_HINT_ONLY) &&
- ((flags & RTE_MEMZONE_1GB) || (flags & RTE_MEMZONE_2MB)
- || (flags & RTE_MEMZONE_16MB) || (flags & RTE_MEMZONE_16GB)))
- return memzone_reserve_aligned_thread_unsafe(name,
- len, socket_id, 0, align, bound);
-
+ /* allocate memory on heap */
+ void *mz_addr = malloc_heap_alloc(&mcfg->malloc_heaps[socket_id], NULL,
+ requested_len, flags, align, bound);
+ if (mz_addr == NULL) {
rte_errno = ENOMEM;
return NULL;
}
- /* save aligned physical and virtual addresses */
- memseg_physaddr = free_memseg[memseg_idx].phys_addr + seg_offset;
- memseg_addr = RTE_PTR_ADD(free_memseg[memseg_idx].addr,
- (uintptr_t) seg_offset);
-
- /* if we are looking for a biggest memzone */
- if (len == 0) {
- if (bound == 0)
- requested_len = memseg_len - seg_offset;
- else
- requested_len = RTE_ALIGN_CEIL(memseg_physaddr + 1,
- bound) - memseg_physaddr;
- }
-
- /* set length to correct value */
- len = (size_t)seg_offset + requested_len;
-
- /* update our internal state */
- free_memseg[memseg_idx].len -= len;
- free_memseg[memseg_idx].phys_addr += len;
- free_memseg[memseg_idx].addr =
- (char *)free_memseg[memseg_idx].addr + len;
+ const struct malloc_elem *elem = malloc_elem_from_data(mz_addr);
/* fill the zone in config */
struct rte_memzone *mz = &mcfg->memzone[mcfg->memzone_idx++];
snprintf(mz->name, sizeof(mz->name), "%s", name);
- mz->phys_addr = memseg_physaddr;
- mz->addr = memseg_addr;
- mz->len = requested_len;
- mz->hugepage_sz = free_memseg[memseg_idx].hugepage_sz;
- mz->socket_id = free_memseg[memseg_idx].socket_id;
+ mz->phys_addr = rte_malloc_virt2phy(mz_addr);
+ mz->addr = mz_addr;
+ mz->len = (requested_len == 0 ? elem->size : requested_len);
+ mz->hugepage_sz = elem->ms->hugepage_sz;
+ mz->socket_id = elem->ms->socket_id;
mz->flags = 0;
- mz->memseg_id = memseg_idx;
+ mz->memseg_id = elem->ms - rte_eal_get_configuration()->mem_config->memseg;
return mz;
}
@@ -419,45 +340,6 @@ rte_memzone_dump(FILE *f)
}
/*
- * called by init: modify the free memseg list to have cache-aligned
- * addresses and cache-aligned lengths
- */
-static int
-memseg_sanitize(struct rte_memseg *memseg)
-{
- unsigned phys_align;
- unsigned virt_align;
- unsigned off;
-
- phys_align = memseg->phys_addr & RTE_CACHE_LINE_MASK;
- virt_align = (unsigned long)memseg->addr & RTE_CACHE_LINE_MASK;
-
- /*
- * sanity check: phys_addr and addr must have the same
- * alignment
- */
- if (phys_align != virt_align)
- return -1;
-
- /* memseg is really too small, don't bother with it */
- if (memseg->len < (2 * RTE_CACHE_LINE_SIZE)) {
- memseg->len = 0;
- return 0;
- }
-
- /* align start address */
- off = (RTE_CACHE_LINE_SIZE - phys_align) & RTE_CACHE_LINE_MASK;
- memseg->phys_addr += off;
- memseg->addr = (char *)memseg->addr + off;
- memseg->len -= off;
-
- /* align end address */
- memseg->len &= ~((uint64_t)RTE_CACHE_LINE_MASK);
-
- return 0;
-}
-
-/*
* Init the memzone subsystem
*/
int
@@ -465,14 +347,10 @@ rte_eal_memzone_init(void)
{
struct rte_mem_config *mcfg;
const struct rte_memseg *memseg;
- unsigned i = 0;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
- /* mirror the runtime memsegs from config */
- free_memseg = mcfg->free_memseg;
-
/* secondary processes don't need to initialise anything */
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
return 0;
@@ -485,33 +363,13 @@ rte_eal_memzone_init(void)
rte_rwlock_write_lock(&mcfg->mlock);
- /* fill in uninitialized free_memsegs */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (memseg[i].addr == NULL)
- break;
- if (free_memseg[i].addr != NULL)
- continue;
- memcpy(&free_memseg[i], &memseg[i], sizeof(struct rte_memseg));
- }
-
- /* make all zones cache-aligned */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (free_memseg[i].addr == NULL)
- break;
- if (memseg_sanitize(&free_memseg[i]) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Sanity check failed\n", __func__);
- rte_rwlock_write_unlock(&mcfg->mlock);
- return -1;
- }
- }
-
/* delete all zones */
mcfg->memzone_idx = 0;
memset(mcfg->memzone, 0, sizeof(mcfg->memzone));
rte_rwlock_write_unlock(&mcfg->mlock);
- return 0;
+ return rte_eal_malloc_heap_init();
}
/* Walk all reserved memory zones */
diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h
index 34f5abc..055212a 100644
--- a/lib/librte_eal/common/include/rte_eal_memconfig.h
+++ b/lib/librte_eal/common/include/rte_eal_memconfig.h
@@ -73,7 +73,7 @@ struct rte_mem_config {
struct rte_memseg memseg[RTE_MAX_MEMSEG]; /**< Physmem descriptors. */
struct rte_memzone memzone[RTE_MAX_MEMZONE]; /**< Memzone descriptors. */
- /* Runtime Physmem descriptors. */
+ /* Runtime Physmem descriptors - NOT USED */
struct rte_memseg free_memseg[RTE_MAX_MEMSEG];
struct rte_tailq_head tailq_head[RTE_MAX_TAILQ]; /**< Tailqs for objects */
diff --git a/lib/librte_eal/common/include/rte_malloc_heap.h b/lib/librte_eal/common/include/rte_malloc_heap.h
index 716216f..b270356 100644
--- a/lib/librte_eal/common/include/rte_malloc_heap.h
+++ b/lib/librte_eal/common/include/rte_malloc_heap.h
@@ -40,7 +40,7 @@
#include <rte_memory.h>
/* Number of free lists per heap, grouped by size. */
-#define RTE_HEAP_NUM_FREELISTS 5
+#define RTE_HEAP_NUM_FREELISTS 13
/**
* Structure to hold malloc heap
@@ -48,7 +48,6 @@
struct malloc_heap {
rte_spinlock_t lock;
LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
- unsigned mz_count;
unsigned alloc_count;
size_t total_size;
} __rte_cache_aligned;
diff --git a/lib/librte_eal/common/malloc_elem.c b/lib/librte_eal/common/malloc_elem.c
index a5e1248..b54ee33 100644
--- a/lib/librte_eal/common/malloc_elem.c
+++ b/lib/librte_eal/common/malloc_elem.c
@@ -37,7 +37,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_per_lcore.h>
@@ -56,10 +55,10 @@
*/
void
malloc_elem_init(struct malloc_elem *elem,
- struct malloc_heap *heap, const struct rte_memzone *mz, size_t size)
+ struct malloc_heap *heap, const struct rte_memseg *ms, size_t size)
{
elem->heap = heap;
- elem->mz = mz;
+ elem->ms = ms;
elem->prev = NULL;
memset(&elem->free_list, 0, sizeof(elem->free_list));
elem->state = ELEM_FREE;
@@ -70,12 +69,12 @@ malloc_elem_init(struct malloc_elem *elem,
}
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
{
- malloc_elem_init(elem, prev->heap, prev->mz, 0);
+ malloc_elem_init(elem, prev->heap, prev->ms, 0);
elem->prev = prev;
elem->state = ELEM_BUSY; /* mark busy so its never merged */
}
@@ -86,12 +85,24 @@ malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
* fit, return NULL.
*/
static void *
-elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
+elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- const uintptr_t end_pt = (uintptr_t)elem +
+ const size_t bmask = ~(bound - 1);
+ uintptr_t end_pt = (uintptr_t)elem +
elem->size - MALLOC_ELEM_TRAILER_LEN;
- const uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
- const uintptr_t new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
+ uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ uintptr_t new_elem_start;
+
+ /* check boundary */
+ if ((new_data_start & bmask) != ((end_pt - 1) & bmask)) {
+ end_pt = RTE_ALIGN_FLOOR(end_pt, bound);
+ new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ if (((end_pt - 1) & bmask) != (new_data_start & bmask))
+ return NULL;
+ }
+
+ new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
/* if the new start point is before the exist start, it won't fit */
return (new_elem_start < (uintptr_t)elem) ? NULL : (void *)new_elem_start;
@@ -102,9 +113,10 @@ elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
* alignment request from the current element
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- return elem_start_pt(elem, size, align) != NULL;
+ return elem_start_pt(elem, size, align, bound) != NULL;
}
/*
@@ -115,10 +127,10 @@ static void
split_elem(struct malloc_elem *elem, struct malloc_elem *split_pt)
{
struct malloc_elem *next_elem = RTE_PTR_ADD(elem, elem->size);
- const unsigned old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
- const unsigned new_elem_size = elem->size - old_elem_size;
+ const size_t old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
+ const size_t new_elem_size = elem->size - old_elem_size;
- malloc_elem_init(split_pt, elem->heap, elem->mz, new_elem_size);
+ malloc_elem_init(split_pt, elem->heap, elem->ms, new_elem_size);
split_pt->prev = elem;
next_elem->prev = split_pt;
elem->size = old_elem_size;
@@ -168,8 +180,9 @@ malloc_elem_free_list_index(size_t size)
void
malloc_elem_free_list_insert(struct malloc_elem *elem)
{
- size_t idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
+ size_t idx;
+ idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
elem->state = ELEM_FREE;
LIST_INSERT_HEAD(&elem->heap->free_head[idx], elem, free_list);
}
@@ -190,12 +203,26 @@ elem_free_list_remove(struct malloc_elem *elem)
* is not done here, as it's done there previously.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- struct malloc_elem *new_elem = elem_start_pt(elem, size, align);
- const unsigned old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ struct malloc_elem *new_elem = elem_start_pt(elem, size, align, bound);
+ const size_t old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ const size_t trailer_size = elem->size - old_elem_size - size -
+ MALLOC_ELEM_OVERHEAD;
+
+ elem_free_list_remove(elem);
- if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE){
+ if (trailer_size > MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
+ /* split it, too much free space after elem */
+ struct malloc_elem *new_free_elem =
+ RTE_PTR_ADD(new_elem, size + MALLOC_ELEM_OVERHEAD);
+
+ split_elem(elem, new_free_elem);
+ malloc_elem_free_list_insert(new_free_elem);
+ }
+
+ if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
/* don't split it, pad the element instead */
elem->state = ELEM_BUSY;
elem->pad = old_elem_size;
@@ -208,8 +235,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
new_elem->size = elem->size - elem->pad;
set_header(new_elem);
}
- /* remove element from free list */
- elem_free_list_remove(elem);
return new_elem;
}
@@ -219,7 +244,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
* Re-insert original element, in case its new size makes it
* belong on a different list.
*/
- elem_free_list_remove(elem);
split_elem(elem, new_elem);
new_elem->state = ELEM_BUSY;
malloc_elem_free_list_insert(elem);
diff --git a/lib/librte_eal/common/malloc_elem.h b/lib/librte_eal/common/malloc_elem.h
index 9790b1a..e05d2ea 100644
--- a/lib/librte_eal/common/malloc_elem.h
+++ b/lib/librte_eal/common/malloc_elem.h
@@ -47,9 +47,9 @@ enum elem_state {
struct malloc_elem {
struct malloc_heap *heap;
- struct malloc_elem *volatile prev; /* points to prev elem in memzone */
+ struct malloc_elem *volatile prev; /* points to prev elem in memseg */
LIST_ENTRY(malloc_elem) free_list; /* list of free elements in heap */
- const struct rte_memzone *mz;
+ const struct rte_memseg *ms;
volatile enum elem_state state;
uint32_t pad;
size_t size;
@@ -136,11 +136,11 @@ malloc_elem_from_data(const void *data)
void
malloc_elem_init(struct malloc_elem *elem,
struct malloc_heap *heap,
- const struct rte_memzone *mz,
+ const struct rte_memseg *ms,
size_t size);
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem,
@@ -151,14 +151,16 @@ malloc_elem_mkend(struct malloc_elem *elem,
* of the requested size and with the requested alignment
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* reserve a block of data in an existing malloc_elem. If the malloc_elem
* is much larger than the data block requested, we split the element in two.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_alloc(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* free a malloc_elem block by adding it to the free list. If the
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index 8861d27..f5fff96 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -39,7 +39,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_launch.h>
@@ -54,123 +53,104 @@
#include "malloc_elem.h"
#include "malloc_heap.h"
-/* since the memzone size starts with a digit, it will appear unquoted in
- * rte_config.h, so quote it so it can be passed to rte_str_to_size */
-#define MALLOC_MEMZONE_SIZE RTE_STR(RTE_MALLOC_MEMZONE_SIZE)
-
-/*
- * returns the configuration setting for the memzone size as a size_t value
- */
-static inline size_t
-get_malloc_memzone_size(void)
+static unsigned
+check_hugepage_sz(unsigned flags, size_t hugepage_sz)
{
- return rte_str_to_size(MALLOC_MEMZONE_SIZE);
+ unsigned ret = 1;
+
+ if ((flags & RTE_MEMZONE_2MB) && hugepage_sz == RTE_PGSIZE_1G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_1GB) && hugepage_sz == RTE_PGSIZE_2M)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16MB) && hugepage_sz == RTE_PGSIZE_16G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16GB) && hugepage_sz == RTE_PGSIZE_16M)
+ ret = 0;
+
+ return ret;
}
/*
- * reserve an extra memory zone and make it available for use by a particular
- * heap. This reserves the zone and sets a dummy malloc_elem header at the end
+ * Expand the heap with a memseg.
+ * This reserves the zone and sets a dummy malloc_elem header at the end
* to prevent overflow. The rest of the zone is added to free list as a single
* large free block
*/
-static int
-malloc_heap_add_memzone(struct malloc_heap *heap, size_t size, unsigned align)
+static void
+malloc_heap_add_memseg(struct malloc_heap *heap, struct rte_memseg *ms)
{
- const unsigned mz_flags = 0;
- const size_t block_size = get_malloc_memzone_size();
- /* ensure the data we want to allocate will fit in the memzone */
- const size_t min_size = size + align + MALLOC_ELEM_OVERHEAD * 2;
- const struct rte_memzone *mz = NULL;
- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- unsigned numa_socket = heap - mcfg->malloc_heaps;
-
- size_t mz_size = min_size;
- if (mz_size < block_size)
- mz_size = block_size;
-
- char mz_name[RTE_MEMZONE_NAMESIZE];
- snprintf(mz_name, sizeof(mz_name), "MALLOC_S%u_HEAP_%u",
- numa_socket, heap->mz_count++);
-
- /* try getting a block. if we fail and we don't need as big a block
- * as given in the config, we can shrink our request and try again
- */
- do {
- mz = rte_memzone_reserve(mz_name, mz_size, numa_socket,
- mz_flags);
- if (mz == NULL)
- mz_size /= 2;
- } while (mz == NULL && mz_size > min_size);
- if (mz == NULL)
- return -1;
-
/* allocate the memory block headers, one at end, one at start */
- struct malloc_elem *start_elem = (struct malloc_elem *)mz->addr;
- struct malloc_elem *end_elem = RTE_PTR_ADD(mz->addr,
- mz_size - MALLOC_ELEM_OVERHEAD);
+ struct malloc_elem *start_elem = (struct malloc_elem *)ms->addr;
+ struct malloc_elem *end_elem = RTE_PTR_ADD(ms->addr,
+ ms->len - MALLOC_ELEM_OVERHEAD);
end_elem = RTE_PTR_ALIGN_FLOOR(end_elem, RTE_CACHE_LINE_SIZE);
+ const size_t elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- const unsigned elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- malloc_elem_init(start_elem, heap, mz, elem_size);
+ malloc_elem_init(start_elem, heap, ms, elem_size);
malloc_elem_mkend(end_elem, start_elem);
malloc_elem_free_list_insert(start_elem);
- /* increase heap total size by size of new memzone */
- heap->total_size+=mz_size - MALLOC_ELEM_OVERHEAD;
- return 0;
+ heap->total_size += elem_size;
}
/*
* Iterates through the freelist for a heap to find a free element
* which can store data of the required size and with the requested alignment.
+ * If size is 0, find the biggest available elem.
* Returns null on failure, or pointer to element on success.
*/
static struct malloc_elem *
-find_suitable_element(struct malloc_heap *heap, size_t size, unsigned align)
+find_suitable_element(struct malloc_heap *heap, size_t size,
+ unsigned flags, size_t align, size_t bound)
{
size_t idx;
- struct malloc_elem *elem;
+ struct malloc_elem *elem, *alt_elem = NULL;
for (idx = malloc_elem_free_list_index(size);
- idx < RTE_HEAP_NUM_FREELISTS; idx++)
- {
+ idx < RTE_HEAP_NUM_FREELISTS; idx++) {
for (elem = LIST_FIRST(&heap->free_head[idx]);
- !!elem; elem = LIST_NEXT(elem, free_list))
- {
- if (malloc_elem_can_hold(elem, size, align))
- return elem;
+ !!elem; elem = LIST_NEXT(elem, free_list)) {
+ if (malloc_elem_can_hold(elem, size, align, bound)) {
+ if (check_hugepage_sz(flags, elem->ms->hugepage_sz))
+ return elem;
+ alt_elem = elem;
+ }
}
}
+
+ if ((alt_elem != NULL) && (flags & RTE_MEMZONE_SIZE_HINT_ONLY))
+ return alt_elem;
+
return NULL;
}
/*
- * Main function called by malloc to allocate a block of memory from the
- * heap. It locks the free list, scans it, and adds a new memzone if the
- * scan fails. Once the new memzone is added, it re-scans and should return
+ * Main function to allocate a block of memory from the heap.
+ * It locks the free list, scans it, and adds a new memseg if the
+ * scan fails. Once the new memseg is added, it re-scans and should return
* the new element after releasing the lock.
*/
void *
malloc_heap_alloc(struct malloc_heap *heap,
- const char *type __attribute__((unused)), size_t size, unsigned align)
+ const char *type __attribute__((unused)), size_t size, unsigned flags,
+ size_t align, size_t bound)
{
+ struct malloc_elem *elem;
+
size = RTE_CACHE_LINE_ROUNDUP(size);
align = RTE_CACHE_LINE_ROUNDUP(align);
+
rte_spinlock_lock(&heap->lock);
- struct malloc_elem *elem = find_suitable_element(heap, size, align);
- if (elem == NULL){
- if ((malloc_heap_add_memzone(heap, size, align)) == 0)
- elem = find_suitable_element(heap, size, align);
- }
- if (elem != NULL){
- elem = malloc_elem_alloc(elem, size, align);
+ elem = find_suitable_element(heap, size, flags, align, bound);
+ if (elem != NULL) {
+ elem = malloc_elem_alloc(elem, size, align, bound);
/* increase heap's count of allocated elements */
heap->alloc_count++;
}
rte_spinlock_unlock(&heap->lock);
- return elem == NULL ? NULL : (void *)(&elem[1]);
+ return elem == NULL ? NULL : (void *)(&elem[1]);
}
/*
@@ -206,3 +186,21 @@ malloc_heap_get_stats(const struct malloc_heap *heap,
socket_stats->alloc_count = heap->alloc_count;
return 0;
}
+
+int
+rte_eal_malloc_heap_init(void)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ unsigned ms_cnt;
+ struct rte_memseg *ms;
+
+ if (mcfg == NULL)
+ return -1;
+
+ for (ms = &mcfg->memseg[0], ms_cnt = 0;
+ (ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0);
+ ms_cnt++, ms++)
+ malloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms);
+
+ return 0;
+}
diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h
index a47136d..3ccbef0 100644
--- a/lib/librte_eal/common/malloc_heap.h
+++ b/lib/librte_eal/common/malloc_heap.h
@@ -53,15 +53,15 @@ malloc_get_numa_socket(void)
}
void *
-malloc_heap_alloc(struct malloc_heap *heap, const char *type,
- size_t size, unsigned align);
+malloc_heap_alloc(struct malloc_heap *heap, const char *type, size_t size,
+ unsigned flags, size_t align, size_t bound);
int
malloc_heap_get_stats(const struct malloc_heap *heap,
struct rte_malloc_socket_stats *socket_stats);
int
-rte_eal_heap_memzone_init(void);
+rte_eal_malloc_heap_init(void);
#ifdef __cplusplus
}
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index c313a57..54c2bd8 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -39,7 +39,6 @@
#include <rte_memcpy.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_branch_prediction.h>
@@ -87,7 +86,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
return NULL;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[socket], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL || socket_arg != SOCKET_ID_ANY)
return ret;
@@ -98,7 +97,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
continue;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[i], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL)
return ret;
}
@@ -256,5 +255,5 @@ rte_malloc_virt2phy(const void *addr)
const struct malloc_elem *elem = malloc_elem_from_data(addr);
if (elem == NULL)
return 0;
- return elem->mz->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->mz->addr);
+ return elem->ms->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->ms->addr);
}
--
1.9.3
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH v6 0/9] Dynamic memzones
2015-06-26 15:29 4% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Sergio Gonzalez Monroy
2015-06-26 15:29 1% ` [dpdk-dev] [PATCH v6 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-06-26 15:29 14% ` [dpdk-dev] [PATCH v6 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
@ 2015-06-26 16:13 0% ` Ananyev, Konstantin
2015-07-03 9:55 4% ` [dpdk-dev] [PATCH v7 " Sergio Gonzalez Monroy
3 siblings, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2015-06-26 16:13 UTC (permalink / raw)
To: Gonzalez Monroy, Sergio, dev
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Sergio Gonzalez Monroy
> Sent: Friday, June 26, 2015 4:29 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v6 0/9] Dynamic memzones
>
> Current implemetation allows reserving/creating memzones but not the opposite
> (unreserve/free). This affects mempools and other memzone based objects.
>
> From my point of view, implementing free functionality for memzones would look
> like malloc over memsegs.
> Thus, this approach moves malloc inside eal (which in turn removes a circular
> dependency), where malloc heaps are composed of memsegs.
> We keep both malloc and memzone APIs as they are, but memzones allocate its
> memory by calling malloc_heap_alloc.
> Some extra functionality is required in malloc to allow for boundary constrained
> memory requests.
> In summary, currently malloc is based on memzones, and with this approach
> memzones are based on malloc.
>
> v6:
> - fix bad patch for rte_memzone_free
>
> v5:
> - Fix rte_memzone_free
> - Improve rte_memzone_free unit test
>
> v4:
> - Rebase and fix couple of merge issues
>
> v3:
> - Create dummy librte_malloc
> - Add deprecation notice
> - Rework some of the code
> - Doc update
> - checkpatch
>
> v2:
> - New rte_memzone_free
> - Support memzone len = 0
> - Add all available memsegs to malloc heap at init
> - Update memzone/malloc unit tests
>
> Sergio Gonzalez Monroy (9):
> eal: move librte_malloc to eal/common
> eal: memzone allocated by malloc
> app/test: update malloc/memzone unit tests
> config: remove CONFIG_RTE_MALLOC_MEMZONE_SIZE
> eal: remove free_memseg and references to it
> eal: new rte_memzone_free
> app/test: rte_memzone_free unit test
> doc: announce ABI change of librte_malloc
> doc: update malloc documentation
>
> MAINTAINERS | 9 +-
> app/test/test_malloc.c | 86 ----
> app/test/test_memzone.c | 456 ++++------------------
> config/common_bsdapp | 8 +-
> config/common_linuxapp | 8 +-
> doc/guides/prog_guide/env_abstraction_layer.rst | 220 ++++++++++-
> doc/guides/prog_guide/img/malloc_heap.png | Bin 81329 -> 80952 bytes
> doc/guides/prog_guide/index.rst | 1 -
> doc/guides/prog_guide/malloc_lib.rst | 233 -----------
> doc/guides/prog_guide/overview.rst | 11 +-
> doc/guides/rel_notes/abi.rst | 1 +
> drivers/net/af_packet/Makefile | 1 -
> drivers/net/bonding/Makefile | 1 -
> drivers/net/e1000/Makefile | 2 +-
> drivers/net/enic/Makefile | 2 +-
> drivers/net/fm10k/Makefile | 2 +-
> drivers/net/i40e/Makefile | 2 +-
> drivers/net/ixgbe/Makefile | 2 +-
> drivers/net/mlx4/Makefile | 1 -
> drivers/net/null/Makefile | 1 -
> drivers/net/pcap/Makefile | 1 -
> drivers/net/virtio/Makefile | 2 +-
> drivers/net/vmxnet3/Makefile | 2 +-
> drivers/net/xenvirt/Makefile | 2 +-
> lib/Makefile | 2 +-
> lib/librte_acl/Makefile | 2 +-
> lib/librte_eal/bsdapp/eal/Makefile | 4 +-
> lib/librte_eal/bsdapp/eal/rte_eal_version.map | 19 +
> lib/librte_eal/common/Makefile | 1 +
> lib/librte_eal/common/eal_common_memzone.c | 339 ++++++----------
> lib/librte_eal/common/include/rte_eal_memconfig.h | 5 +-
> lib/librte_eal/common/include/rte_malloc.h | 342 ++++++++++++++++
> lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
> lib/librte_eal/common/include/rte_memzone.h | 11 +
> lib/librte_eal/common/malloc_elem.c | 344 ++++++++++++++++
> lib/librte_eal/common/malloc_elem.h | 192 +++++++++
> lib/librte_eal/common/malloc_heap.c | 206 ++++++++++
> lib/librte_eal/common/malloc_heap.h | 70 ++++
> lib/librte_eal/common/rte_malloc.c | 259 ++++++++++++
> lib/librte_eal/linuxapp/eal/Makefile | 4 +-
> lib/librte_eal/linuxapp/eal/eal_ivshmem.c | 17 +-
> lib/librte_eal/linuxapp/eal/rte_eal_version.map | 19 +
> lib/librte_hash/Makefile | 2 +-
> lib/librte_lpm/Makefile | 2 +-
> lib/librte_malloc/Makefile | 6 +-
> lib/librte_malloc/malloc_elem.c | 320 ---------------
> lib/librte_malloc/malloc_elem.h | 190 ---------
> lib/librte_malloc/malloc_heap.c | 208 ----------
> lib/librte_malloc/malloc_heap.h | 70 ----
> lib/librte_malloc/rte_malloc.c | 228 +----------
> lib/librte_malloc/rte_malloc.h | 342 ----------------
> lib/librte_malloc/rte_malloc_version.map | 16 -
> lib/librte_mempool/Makefile | 2 -
> lib/librte_port/Makefile | 1 -
> lib/librte_ring/Makefile | 3 +-
> lib/librte_table/Makefile | 1 -
> 56 files changed, 1928 insertions(+), 2356 deletions(-)
> delete mode 100644 doc/guides/prog_guide/malloc_lib.rst
> create mode 100644 lib/librte_eal/common/include/rte_malloc.h
> create mode 100644 lib/librte_eal/common/malloc_elem.c
> create mode 100644 lib/librte_eal/common/malloc_elem.h
> create mode 100644 lib/librte_eal/common/malloc_heap.c
> create mode 100644 lib/librte_eal/common/malloc_heap.h
> create mode 100644 lib/librte_eal/common/rte_malloc.c
> delete mode 100644 lib/librte_malloc/malloc_elem.c
> delete mode 100644 lib/librte_malloc/malloc_elem.h
> delete mode 100644 lib/librte_malloc/malloc_heap.c
> delete mode 100644 lib/librte_malloc/malloc_heap.h
> delete mode 100644 lib/librte_malloc/rte_malloc.h
>
> --
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> 1.9.3
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3 2/3] rte_compat: Add MAP_STATIC_SYMBOL macro
2015-06-26 14:30 3% ` Neil Horman
@ 2015-06-28 20:13 0% ` Thomas Monjalon
2015-06-29 13:44 0% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-06-28 20:13 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-26 10:30, Neil Horman:
> On Fri, Jun 26, 2015 at 02:52:50PM +0200, Thomas Monjalon wrote:
> > 2015-06-25 10:35, Neil Horman:
> > > +/*
> > > + * MAP_STATIC_SYMBOL
> > > + * If a function has been bifurcated into multiple versions, none of which
> > > + * are defined as the exported symbol name in the map file, this macro can be
> > > + * used to alias a specific version of the symbol to its exported name. For
> > > + * example, if you have 2 versions of a function foo_v1 and foo_v2, where the
> > > + * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when
> > > + * building a shared library, this macro can be used to map either foo_v1 or
> > > + * foo_v2 to the symbol foo when building a static library, e.g.:
> > > + * MAP_STATIC_SYMBOL(void foo(), foo_v2);
> > > + */
> > > +#define MAP_STATIC_SYMBOL(f, p)
> > > +
> > > #else
> > > /*
> > > * No symbol versioning in use
> > > @@ -104,7 +105,7 @@
> > > #define __vsym
> > > #define BASE_SYMBOL(b, n)
> > > #define BIND_DEFAULT_SYMBOL(b, e, n)
> > > -
> > > +#define MAP_STATIC_SYMBOL(f, p) f __attribute__((alias( RTE_STR(p))))
> >
> > Is it working with clang and icc?
> No idea. It should work with clang (though I don't have it installed at the
> moment), as the docs say the .symver directive is supported
>
> as for icc, thats out of my control completely, as I don't have any access to
> it.
>
> > Why not just define foo as foo_v2?
> I'm not sure what you mean here. Are you suggesting that we just change the abi
> so applications have to call foo_v2 rather than foo when we change the
> prototype. I suppose we could do that, but that seems like it would be an awful
> irritant to users. They would rather have a single symbol to call if it does
> the same function.
>
> > As this is the equivalent of BIND_DEFAULT_SYMBOL for the static case,
> > it would be easier to mix them in only one macro.
> >
> Because of where its used. If you use BIND_DEFAULT_SYMBOL to do the work of
> MAP_STATIC_SYMBOL, every compilation unit will define its own alias and you'll
> get symbol conflicts.
Oh, you mean it shouldn't be used in a .h file?
If so, this limitation should be noted in the description above.
OK for that solution, that's the best we have at the moment.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3 3/3] ABI: Add some documentation
2015-06-26 14:54 4% ` Neil Horman
@ 2015-06-28 20:24 8% ` Thomas Monjalon
2015-06-29 13:53 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-06-28 20:24 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-26 10:54, Neil Horman:
> On Fri, Jun 26, 2015 at 03:00:17PM +0200, Thomas Monjalon wrote:
> > 2015-06-25 10:35, Neil Horman:
> > > +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
> > > + unversioned symbol ``b`` to the internal function ``b_e``.
> >
> > Should a versioned symbol <b>@DPDK_<n>
> >
> Sure.
When fixed, this series can be applied.
> > > +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
> > > + unversioned symbol ``b`` to the internal function ``b_e``.
> >
> > Please give a use case of BASE_SYMBOL.
> >
> No, I'd rather remove it if you really insist. As noted before the way we set
> up the version map files means we currently have no need for this particular
> directive. I only included it for completeness. I think an example use in
> light of that fact would only confuse people. If you're going to draw a line in
> the sand around it, I'll just remove it.
No line in the sand, but it seems better to remove it to avoid confusing people.
ABI compat is already enough difficult to understand ;)
> > [...]
> > > +The addition of the new block tells the linker that a new version node is
> > > +available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
> > > +symbols from the DPDK_2.0 node.
> >
> > which contains the old version of the symbol rte_acl_create
> >
> I don't understand, is it not obvious that the DPDK_2.0 node contains the 2.0
> version of the symbol and the DPDK_2.1 node contains the 2.1 version of the
> symbol?
Yes it is.
I thought it was needed to insist on the existence of a new symbol while the
old one still exists. Just trying to be didactic.
Hope this documentation will help to unlock the patch series currently
breaking the ABI.
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v3 2/7] mbuf: use the reserved 16 bits for double vlan
2015-06-25 8:31 3% ` Zhang, Helin
@ 2015-06-28 20:36 0% ` Thomas Monjalon
2015-06-30 7:33 3% ` Olivier MATZ
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-06-28 20:36 UTC (permalink / raw)
To: Neil Horman, olivier.matz; +Cc: dev
Neil, Olivier,
Your opinions are requested here.
Thanks
2015-06-25 08:31, Zhang, Helin:
> Hi Neil
[...]
> > -279,7 +285,7 @@ struct rte_mbuf {
> > 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;
> > + uint16_t vlan_tci_outer; /**< Outer VLAN Tag Control Identifier (CPU
> > +order) */
> Do you think here is a ABI break or not? Just using the reserved 16 bits, which was
> intended for the second_vlan_tag. Thanks in advance!
> I did not see any "Incompatible" reported by validate_abi.sh.
>
> Regards,
> Helin
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3 00/11] Cuckoo hash
2015-06-25 22:05 4% ` [dpdk-dev] [PATCH v2 00/11] " Pablo de Lara
2015-06-25 22:05 14% ` [dpdk-dev] [PATCH v2 10/11] doc: announce ABI change of librte_hash Pablo de Lara
@ 2015-06-28 22:25 4% ` Pablo de Lara
2015-06-28 22:25 14% ` [dpdk-dev] [PATCH v3 10/11] doc: announce ABI change of librte_hash Pablo de Lara
2015-07-08 23:23 0% ` [dpdk-dev] [PATCH v3 00/11] Cuckoo hash Thomas Monjalon
2 siblings, 2 replies; 200+ results
From: Pablo de Lara @ 2015-06-28 22:25 UTC (permalink / raw)
To: dev
This patchset is to replace the existing hash library with
a more efficient and functional approach, using the Cuckoo hash
method to deal with collisions. This method is based on using
two different hash functions to have two possible locations
in the hash table where an entry can be.
So, if a bucket is full, a new entry can push one of the items
in that bucket to its alternative location, making space for itself.
Advantages
~~~~~~
- Offers the option to store more entries when the target bucket is full
(unlike the previous implementation)
- Memory efficient: for storing those entries, it is not necessary to
request new memory, as the entries will be stored in the same table
- Constant worst lookup time: in worst case scenario, it always takes
the same time to look up an entry, as there are only two possible locations
where an entry can be.
- Storing data: user can store data in the hash table, unlike the
previous implementation, but he can still use the old API
This implementation tipically offers over 90% utilization.
Notice that API has been extended, but old API remains. The main
change in ABI is that rte_hash structure is now private and the
deprecation of two macros.
Changes in v3:
- Now user can store variable size data, instead of 32 or 64-bit size data,
using the new parameter "data_len" in rte_hash_parameters
- Add lookup_bulk_with_hash function in performance unit tests
- Add new functions that handle data in performance unit tests
- Remove duplicates in performance unit tests
- Fix rte_hash_reset, which was not reseting the last entry
Changes in v2:
- Fixed issue where table could not store maximum number of entries
- Fixed issue where lookup burst could not be more than 32 (instead of 64)
- Remove unnecessary macros and add other useful ones
- Added missing library dependencies
- Used directly rte_hash_secondary instead of rte_hash_alt
- Renamed rte_hash.c to rte_cuckoo_hash.c to ease the view of the new library
- Renamed test_hash_perf.c temporarily to ease the view of the improved unit test
- Moved rte_hash, rte_bucket and rte_hash_key structures to rte_cuckoo_hash.c to
make them private
- Corrected copyright dates
- Added an optimized function to compare keys that are multiple of 16 bytes
- Improved the way to use primary/secondary signatures. Now both are stored in
the bucket, so there is no need to calculate them if required.
Also, there is no need to use the MSB of a signature to differenciate between
an empty entry and signature 0, since we are storing both signatures,
which cannot be both 0.
- Removed rte_hash_rehash, as it was a very expensive operation.
Therefore, the add function returns now -ENOSPC if key cannot be added
because of a loop.
- Prefetched new slot for new key in add function to improve performance.
- Made doxygen comments more clear.
- Removed unnecessary rte_hash_del_key_data and rte_hash_del_key_with_data,
as we can use the lookup functions if we want to get the data before deleting.
- Removed some unnecessary includes in rte_hash.h
- Removed some unnecessary variables in rte_cuckoo_hash.c
- Removed some unnecessary checks before creating a new hash table
- Added documentation (in release notes and programmers guide)
- Added new unit tests and replaced the performance one for hash tables
Pablo de Lara (11):
eal: add const in prefetch functions
hash: move rte_hash structure to C file and make it internal
test/hash: enhance hash unit tests
test/hash: rename new hash perf unit test back to original name
hash: replace existing hash library with cuckoo hash implementation
hash: add new lookup_bulk_with_hash function
hash: add new function rte_hash_reset
hash: add new functionality to store data in hash table
MAINTAINERS: claim responsability for hash library
doc: announce ABI change of librte_hash
doc: update hash documentation
MAINTAINERS | 1 +
app/test/Makefile | 1 +
app/test/test_hash.c | 189 +--
app/test/test_hash_perf.c | 965 ++++++--------
doc/guides/prog_guide/hash_lib.rst | 77 +-
doc/guides/rel_notes/abi.rst | 2 +
.../common/include/arch/ppc_64/rte_prefetch.h | 6 +-
.../common/include/arch/x86/rte_prefetch.h | 14 +-
.../common/include/generic/rte_prefetch.h | 8 +-
lib/librte_hash/Makefile | 8 +-
lib/librte_hash/rte_cuckoo_hash.c | 1393 ++++++++++++++++++++
lib/librte_hash/rte_hash.c | 471 -------
lib/librte_hash/rte_hash.h | 275 +++-
lib/librte_hash/rte_hash_version.map | 15 +
14 files changed, 2250 insertions(+), 1175 deletions(-)
create mode 100644 lib/librte_hash/rte_cuckoo_hash.c
delete mode 100644 lib/librte_hash/rte_hash.c
--
2.4.2
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3 10/11] doc: announce ABI change of librte_hash
2015-06-28 22:25 4% ` [dpdk-dev] [PATCH v3 00/11] Cuckoo hash Pablo de Lara
@ 2015-06-28 22:25 14% ` Pablo de Lara
2015-07-08 23:23 0% ` [dpdk-dev] [PATCH v3 00/11] Cuckoo hash Thomas Monjalon
1 sibling, 0 replies; 200+ results
From: Pablo de Lara @ 2015-06-28 22:25 UTC (permalink / raw)
To: dev
rte_hash structure is now private for version 2.1, and two
of the macros in rte_hash.h are now deprecated, so this patch
adds notice of these changes.
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
doc/guides/rel_notes/abi.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..fae09fd 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,5 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* Structure rte_hash in librte_hash library has been changed and has been made private in relese 2.1, as applications should have never accessed to its internal data (library should have been marked as internal).
+* The Macros #RTE_HASH_BUCKET_ENTRIES_MAX and #RTE_HASH_KEY_LENGTH_MAX are deprecated and will be removed with version 2.2.
--
2.4.2
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping
@ 2015-06-29 13:42 4% John McNamara
2015-06-29 13:42 14% ` [dpdk-dev] [PATCH v2 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: John McNamara @ 2015-06-29 13:42 UTC (permalink / raw)
To: dev
This patchset adds ethdev API to enable and read IEEE1588/802.1AS PTP
timestamps from devices that support it. The following functions are added:
rte_eth_timesync_enable()
rte_eth_timesync_disable()
rte_eth_timesync_read_rx_timestamp()
rte_eth_timesync_read_tx_timestamp()
The "ieee1588" forwarding mode in testpmd is also refactored to demonstrate
the new API and to clean up the code.
Adds support for igb, ixgbe and i40e.
V2:
* Added i40e support.
* Renamed ethdev functions from rte_eth_ieee15888_*() to rte_eth_timesync_*()
since 802.1AS can be supported through the same interfaces.
V1:
* Initial version for
John McNamara (7):
ethdev: add support for ieee1588 timestamping
e1000: add support for ieee1588 timestamping
ixgbe: add support for ieee1588 timestamping
i40e: add support for ieee1588 timestamping
app/testpmd: refactor ieee1588 forwarding
doc: document ieee1588 forwarding mode
abi: announce mbuf addition for ieee1588 in DPDK 2.2
app/test-pmd/ieee1588fwd.c | 466 ++--------------------------
doc/guides/rel_notes/abi.rst | 5 +
doc/guides/testpmd_app_ug/run_app.rst | 2 +-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +
drivers/net/e1000/igb_ethdev.c | 115 +++++++
drivers/net/i40e/i40e_ethdev.c | 143 +++++++++
drivers/net/i40e/i40e_rxtx.c | 39 ++-
drivers/net/ixgbe/ixgbe_ethdev.c | 122 ++++++++
lib/librte_ether/rte_ethdev.c | 70 ++++-
lib/librte_ether/rte_ethdev.h | 90 +++++-
lib/librte_ether/rte_ether_version.map | 4 +
11 files changed, 615 insertions(+), 443 deletions(-)
--
1.8.1.4
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2
2015-06-29 13:42 4% [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping John McNamara
@ 2015-06-29 13:42 14% ` John McNamara
2015-07-02 1:24 0% ` [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping Lu, Wenzhuo
2015-07-02 15:16 4% ` [dpdk-dev] [PATCH v3 " John McNamara
2 siblings, 0 replies; 200+ results
From: John McNamara @ 2015-06-29 13:42 UTC (permalink / raw)
To: dev
Add announcement of a dedicated additional field in the mbuf
to support ieee1588 in DPDK 2.2.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/rel_notes/abi.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..51dacb2 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,8 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+
+* In DPDK 2.1 the IEEE1588/802.1AS support in the i40e driver makes use of the
+ ``udata64`` field in the mbuf to pass the timesync register index to the
+ user. In DPDK 2.2 this will be moved to a new field in the mbuf.
+
--
1.8.1.4
^ permalink raw reply [relevance 14%]
* Re: [dpdk-dev] [PATCHv3 2/3] rte_compat: Add MAP_STATIC_SYMBOL macro
2015-06-28 20:13 0% ` Thomas Monjalon
@ 2015-06-29 13:44 0% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2015-06-29 13:44 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Sun, Jun 28, 2015 at 10:13:31PM +0200, Thomas Monjalon wrote:
> 2015-06-26 10:30, Neil Horman:
> > On Fri, Jun 26, 2015 at 02:52:50PM +0200, Thomas Monjalon wrote:
> > > 2015-06-25 10:35, Neil Horman:
> > > > +/*
> > > > + * MAP_STATIC_SYMBOL
> > > > + * If a function has been bifurcated into multiple versions, none of which
> > > > + * are defined as the exported symbol name in the map file, this macro can be
> > > > + * used to alias a specific version of the symbol to its exported name. For
> > > > + * example, if you have 2 versions of a function foo_v1 and foo_v2, where the
> > > > + * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when
> > > > + * building a shared library, this macro can be used to map either foo_v1 or
> > > > + * foo_v2 to the symbol foo when building a static library, e.g.:
> > > > + * MAP_STATIC_SYMBOL(void foo(), foo_v2);
> > > > + */
> > > > +#define MAP_STATIC_SYMBOL(f, p)
> > > > +
> > > > #else
> > > > /*
> > > > * No symbol versioning in use
> > > > @@ -104,7 +105,7 @@
> > > > #define __vsym
> > > > #define BASE_SYMBOL(b, n)
> > > > #define BIND_DEFAULT_SYMBOL(b, e, n)
> > > > -
> > > > +#define MAP_STATIC_SYMBOL(f, p) f __attribute__((alias( RTE_STR(p))))
> > >
> > > Is it working with clang and icc?
> > No idea. It should work with clang (though I don't have it installed at the
> > moment), as the docs say the .symver directive is supported
> >
> > as for icc, thats out of my control completely, as I don't have any access to
> > it.
> >
> > > Why not just define foo as foo_v2?
> > I'm not sure what you mean here. Are you suggesting that we just change the abi
> > so applications have to call foo_v2 rather than foo when we change the
> > prototype. I suppose we could do that, but that seems like it would be an awful
> > irritant to users. They would rather have a single symbol to call if it does
> > the same function.
> >
> > > As this is the equivalent of BIND_DEFAULT_SYMBOL for the static case,
> > > it would be easier to mix them in only one macro.
> > >
> > Because of where its used. If you use BIND_DEFAULT_SYMBOL to do the work of
> > MAP_STATIC_SYMBOL, every compilation unit will define its own alias and you'll
> > get symbol conflicts.
>
> Oh, you mean it shouldn't be used in a .h file?
> If so, this limitation should be noted in the description above.
>
Its already noted in the example, I'd rather not make a unilateral statement
about where to use it above because there can be cause to use it internally as
well.
> OK for that solution, that's the best we have at the moment.
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3 3/3] ABI: Add some documentation
2015-06-28 20:24 8% ` Thomas Monjalon
@ 2015-06-29 13:53 4% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2015-06-29 13:53 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Sun, Jun 28, 2015 at 10:24:42PM +0200, Thomas Monjalon wrote:
> 2015-06-26 10:54, Neil Horman:
> > On Fri, Jun 26, 2015 at 03:00:17PM +0200, Thomas Monjalon wrote:
> > > 2015-06-25 10:35, Neil Horman:
> > > > +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
> > > > + unversioned symbol ``b`` to the internal function ``b_e``.
> > >
> > > Should a versioned symbol <b>@DPDK_<n>
> > >
> > Sure.
>
> When fixed, this series can be applied.
>
> > > > +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
> > > > + unversioned symbol ``b`` to the internal function ``b_e``.
> > >
> > > Please give a use case of BASE_SYMBOL.
> > >
> > No, I'd rather remove it if you really insist. As noted before the way we set
> > up the version map files means we currently have no need for this particular
> > directive. I only included it for completeness. I think an example use in
> > light of that fact would only confuse people. If you're going to draw a line in
> > the sand around it, I'll just remove it.
>
> No line in the sand, but it seems better to remove it to avoid confusing people.
> ABI compat is already enough difficult to understand ;)
>
> > > [...]
> > > > +The addition of the new block tells the linker that a new version node is
> > > > +available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
> > > > +symbols from the DPDK_2.0 node.
> > >
> > > which contains the old version of the symbol rte_acl_create
> > >
> > I don't understand, is it not obvious that the DPDK_2.0 node contains the 2.0
> > version of the symbol and the DPDK_2.1 node contains the 2.1 version of the
> > symbol?
>
> Yes it is.
> I thought it was needed to insist on the existence of a new symbol while the
> old one still exists. Just trying to be didactic.
>
Ah, no its not a mandate (though doing so is an optional aproach, which trades
off the need to use MAP_STATIC_SYMBOL for the maintain a public symbol with the
same name). I can include an alternate example of the same exercize that
follows that approach, but given our time contraints would rather to that in a
follow up patch series
Neil
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCHv4 4/4] ABI: Add some documentation
@ 2015-06-29 13:59 28% ` Neil Horman
2015-06-29 15:07 7% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-06-29 13:59 UTC (permalink / raw)
To: dev
People have been asking for ways to use the ABI macros, heres some docs to
clarify their use. Included is:
* An overview of what ABI is
* Details of the ABI deprecation process
* Details of the versioning macros
* Examples of their use
* Details of how to use the ABI validator
Thanks to John Mcnamara, who duplicated much of this effort at Intel while I was
working on it. Much of the introductory material was gathered and cleaned up by
him
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: john.mcnamara@intel.com
CC: thomas.monjalon@6wind.com
Change notes:
v2)
* Fixed RST indentations and spelling errors
* Rebased to upstream to fix index.rst conflict
v3)
* Fixed in tact -> intact
* Added docs to address static linking
* Removed duplicate documentation from release notes
v4)
* Fixed more grammatical errors / etc
* removed BASE_SYMBOL from documentation
---
doc/guides/guidelines/index.rst | 1 +
doc/guides/guidelines/versioning.rst | 480 +++++++++++++++++++++++++++++++++++
doc/guides/rel_notes/abi.rst | 30 +--
3 files changed, 483 insertions(+), 28 deletions(-)
create mode 100644 doc/guides/guidelines/versioning.rst
diff --git a/doc/guides/guidelines/index.rst b/doc/guides/guidelines/index.rst
index 0ee9ab3..bfb9fa3 100644
--- a/doc/guides/guidelines/index.rst
+++ b/doc/guides/guidelines/index.rst
@@ -7,3 +7,4 @@ Guidelines
coding_style
design
+ versioning
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
new file mode 100644
index 0000000..63526db
--- /dev/null
+++ b/doc/guides/guidelines/versioning.rst
@@ -0,0 +1,480 @@
+Managing ABI updates
+====================
+
+Description
+-----------
+
+This document details some methods for handling ABI management in the DPDK.
+Note this document is not exhaustive, in that C library versioning is flexible
+allowing multiple methods to achieve various goals, but it will provide the user
+with some introductory methods
+
+General Guidelines
+------------------
+
+#. Whenever possible, ABI should be preserved
+#. The addition of symbols is generally not problematic
+#. The modification of symbols can generally be managed with versioning
+#. The removal of symbols generally is an ABI break and requires bumping of the
+ LIBABIVER macro
+
+What is an ABI
+--------------
+
+An ABI (Application Binary Interface) is the set of runtime interfaces exposed
+by a library. It is similar to an API (Application Programming Interface) but
+is the result of compilation. It is also effectively cloned when applications
+link to dynamic libraries. That is to say when an application is compiled to
+link against dynamic libraries, it is assumed that the ABI remains constant
+between the time the application is compiled/linked, and the time that it runs.
+Therefore, in the case of dynamic linking, it is critical that an ABI is
+preserved, or (when modified), done in such a way that the application is unable
+to behave improperly or in an unexpected fashion.
+
+The DPDK ABI policy
+-------------------
+
+ABI versions are set at the time of major release labeling, and the ABI may
+change multiple times, without warning, between the last release label and the
+HEAD label of the git tree.
+
+ABI versions, once released, are available until such time as their
+deprecation has been noted in the Release Notes for at least one major release
+cycle. For example consider the case where the ABI for DPDK 2.0 has been
+shipped and then a decision is made to modify it during the development of
+DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
+release and the modification will be made available in the DPDK 2.2 release.
+
+ABI versions may be deprecated in whole or in part as needed by a given
+update.
+
+Some ABI changes may be too significant to reasonably maintain multiple
+versions. In those cases ABI's may be updated without backward compatibility
+being provided. The requirements for doing so are:
+
+#. At least 3 acknowledgments of the need to do so must be made on the
+ dpdk.org mailing list.
+
+#. A full deprecation cycle, as explained above, must be made to offer
+ downstream consumers sufficient warning of the change.
+
+#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
+ incorporated must be incremented in parallel with the ABI changes
+ themselves.
+
+Note that the above process for ABI deprecation should not be undertaken
+lightly. ABI stability is extremely important for downstream consumers of the
+DPDK, especially when distributed in shared object form. Every effort should
+be made to preserve the ABI whenever possible. The ABI should only be changed
+for significant reasons, such as performance enhancements. ABI breakage due to
+changes such as reorganizing public structure fields for aesthetic or
+readability purposes should be avoided.
+
+Examples of Deprecation Notices
+-------------------------------
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+ to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+ in version 2.0. Backwards compatibility will be maintained for this function
+ until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+ performance reasons. Existing binary applications will have backwards
+ compatibility in release 2.0, while newly built binaries will need to
+ reference the new structure variant ``struct rte_foo2``. Compatibility will
+ be removed in release 2.2, and all applications will require updating and
+ rebuilding to the new structure at that time, which will be renamed to the
+ original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+ upcoming release 2.0 will not contain these changes, but release 2.1 will,
+ and no backwards compatibility is planned due to the extensive nature of
+ these changes. Binaries using this library built prior to version 2.1 will
+ require updating and recompilation.
+
+Versioning Macros
+-----------------
+
+When a symbol is exported from a library to provide an API, it also provides a
+calling convention (ABI) that is embodied in its name, return type and
+arguments. Occasionally that function may need to change to accommodate new
+functionality or behavior. When that occurs, it is desirable to allow for
+backward compatibility for a time with older binaries that are dynamically
+linked to the DPDK.
+
+To support backward compatibility the ``lib/librte_compat/rte_compat.h``
+header file provides macros to use when updating exported functions. These
+macros are used in conjunction with the ``rte_<library>_version.map`` file for
+a given library to allow multiple versions of a symbol to exist in a shared
+library so that older binaries need not be immediately recompiled.
+
+The macros exported are:
+
+* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
+ versioned symbol ``b@DPDK_n`` to the internal function ``b_e``.
+
+* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
+ the linker to bind references to symbol ``b`` to the internal symbol
+ ``b_e``.
+
+* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the fully
+qualified function ``p``, so that if a symbol becomes versioned, it can still be
+mapped back to the public symbol name.
+
+Examples of ABI Macro use
+-------------------------
+
+Updating a public API
+~~~~~~~~~~~~~~~~~~~~~
+
+Assume we have a function as follows
+
+.. code-block:: c
+
+ /*
+ * Create an acl context object for apps to
+ * manipulate
+ */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param)
+ {
+ ...
+ }
+
+
+Assume that struct rte_acl_ctx is a private structure, and that a developer
+wishes to enhance the acl api so that a debugging flag can be enabled on a
+per-context basis. This requires an addition to the structure (which, being
+private, is safe), but it also requires modifying the code as follows
+
+.. code-block:: c
+
+ /*
+ * Create an acl context object for apps to
+ * manipulate
+ */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param, int debug)
+ {
+ ...
+ }
+
+
+Note also that, being a public function, the header file prototype must also be
+changed, as must all the call sites, to reflect the new ABI footprint. We will
+maintain previous ABI versions that are accessible only to previously compiled
+binaries
+
+The addition of a parameter to the function is ABI breaking as the function is
+public, and existing application may use it in its current form. However, the
+compatibility macros in DPDK allow a developer to use symbol versioning so that
+multiple functions can be mapped to the same public symbol based on when an
+application was linked to it. To see how this is done, we start with the
+requisite libraries version map file. Initially the version map file for the
+acl library looks like this
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_create;
+ rte_acl_dump;
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+This file needs to be modified as follows
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_create;
+ rte_acl_dump;
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+ DPDK_2.1 {
+ global:
+ rte_acl_create;
+
+ } DPDK_2.0;
+
+The addition of the new block tells the linker that a new version node is
+available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
+symbols from the DPDK_2.0 node. This list is directly translated into a list of
+exported symbols when DPDK is compiled as a shared library
+
+Next, we need to specify in the code which function map to the rte_acl_create
+symbol at which versions. First, at the site of the initial symbol definition,
+we need to update the function so that it is uniquely named, and not in conflict
+with the public symbol name
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param)
+ +rte_acl_create_v20(const struct rte_acl_param *param)
+ {
+ size_t sz;
+ struct rte_acl_ctx *ctx;
+ ...
+
+Note that the base name of the symbol was kept intact, as this is condusive to
+the macros used for versioning symbols. That is our next step, mapping this new
+symbol name to the initial symbol name at version node 2.0. Immediately after
+the function, we add this line of code
+
+.. code-block:: c
+
+ VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+Remembering to also add the rte_compat.h header to the requisite c file where
+these changes are being made. The above macro instructs the linker to create a
+new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
+builds, but now points to the above newly named function. We have now mapped
+the original rte_acl_create symbol to the original function (but with a new
+name)
+
+Next, we need to create the 2.1 version of the symbol. We create a new function
+name, with a different suffix, and implement it appropriately
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+ {
+ struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
+
+ ctx->debug = debug;
+
+ return ctx;
+ }
+
+This code serves as our new API call. Its the same as our old call, but adds
+the new parameter in place. Next we need to map this function to the symbol
+``rte_acl_create@DPDK_2.1``. To do this, we modify the public prototype of the call
+in the header file, adding the macro there to inform all including applications,
+that on re-link, the default rte_acl_create symbol should point to this
+function. Note that we could do this by simply naming the function above
+rte_acl_create, and the linker would chose the most recent version tag to apply
+in the version script, but we can also do this in the header file
+
+.. code-block:: c
+
+ struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param);
+ +rte_acl_create(const struct rte_acl_param *param, int debug);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
+header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
+version node to it. This method is more explicit and flexible than just
+re-implementing the exact symbol name, and allows for other features (such as
+linking to the old symbol version by default, when the new ABI is to be opt-in
+for a period.
+
+One last thing we need to do. Note that we've taken what was a public symbol,
+and duplicated it into two uniquely and differently named symbols. We've then
+mapped each of those back to the public symbol ``rte_acl_create`` with different
+version tags. This only applies to dynamic linking, as static linking has no
+notion of versioning. That leaves this code in a position of no longer having a
+symbol simply named ``rte_acl_create`` and a static build will fail on that
+missing symbol.
+
+To correct this, we can simply map a function of our choosing back to the public
+symbol in the static build with the ``MAP_STATIC_SYMBOL`` macro. Generally the
+assumption is that the most recent version of the symbol is the one you want to
+map. So, back in the C file where, immediately after ``rte_acl_create_v21`` is
+defined, we add this
+
+.. code-block:: c
+
+ struct rte_acl_create_v21(const struct rte_acl_param *param, int debug)
+ {
+ ...
+ }
+ MAP_STATIC_SYMBOL(struct rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v21);
+
+That tells the compiler that, when building a static library, any calls to the
+symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
+
+That's it, on the next shared library rebuild, there will be two versions of
+rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
+and a new DPDK_2.1 version, used by future built applications.
+
+
+Deprecating part of a public API
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Lets assume that you've done the above update, and after a few releases have
+passed you decide you would like to retire the old version of the function.
+After having gone through the ABI deprecation announcement process, removal is
+easy. Start by removing the symbol from the requisite version map file:
+
+.. code-block:: none
+
+ DPDK_2.0 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_dump;
+ - rte_acl_create
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+ DPDK_2.1 {
+ global:
+ rte_acl_create;
+ } DPDK_2.0;
+
+
+Next remove the corresponding versioned export
+.. code-block:: c
+
+ -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+
+Note that the internal function definition could also be removed, but its used
+in our example by the newer version _v21, so we leave it in place. This is a
+coding style choice.
+
+Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
+indicate to applications doing dynamic linking that this is a later, and
+possibly incompatible library version:
+
+.. code-block:: c
+
+ -LIBABIVER := 1
+ +LIBABIVER := 2
+
+Deprecating an entire ABI version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+While removing a symbol from and ABI may be useful, it is often more practical
+to remove an entire version node at once. If a version node completely
+specifies an API, then removing part of it, typically makes it incomplete. In
+those cases it is better to remove the entire node
+
+To do this, start by modifying the version map file, such that all symbols from
+the node to be removed are merged into the next node in the map
+
+In the case of our map above, it would transform to look as follows
+
+.. code-block:: none
+
+ DPDK_2.1 {
+ global:
+
+ rte_acl_add_rules;
+ rte_acl_build;
+ rte_acl_classify;
+ rte_acl_classify_alg;
+ rte_acl_classify_scalar;
+ rte_acl_dump;
+ rte_acl_create
+ rte_acl_find_existing;
+ rte_acl_free;
+ rte_acl_ipv4vlan_add_rules;
+ rte_acl_ipv4vlan_build;
+ rte_acl_list_dump;
+ rte_acl_reset;
+ rte_acl_reset_rules;
+ rte_acl_set_ctx_classify;
+
+ local: *;
+ };
+
+Then any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be
+updated to point to the new version node in any header files for all affected
+symbols.
+
+.. code-block:: c
+
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+Lastly, any VERSION_SYMBOL macros that point to the old version node should be
+removed, taking care to keep, where need old code in place to support newer
+versions of the symbol.
+
+Running the ABI Validator
+-------------------------
+
+The ``scripts`` directory in the DPDK source tree contains a utility program,
+``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
+Compliance Checker
+<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
+
+This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
+utilities which can be installed via a package manager. For example::
+
+ sudo yum install abi-compliance-checker
+ sudo yum install abi-dumper
+
+The syntax of the ``validate-abi.sh`` utility is::
+
+ ./scripts/validate-abi.sh <TAG1> <TAG2> <TARGET>
+
+Where ``TAG1`` and ``TAG2`` are valid git tags on the local repo and target is
+the usual DPDK compilation target.
+
+For example to test the current committed HEAD against a previous release tag
+we could add a temporary tag and run the utility as follows::
+
+ git tag MY_TEMP_TAG
+ ./scripts/validate-abi.sh v2.0.0 MY_TEMP_TAG x86_64-native-linuxapp-gcc
+
+After the validation script completes (it can take a while since it need to
+compile both tags) it will create compatibility reports in the
+``./compat_report`` directory. Listed incompatibilities can be found as
+follows::
+
+ grep -lr Incompatible compat_reports/
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..4086198 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -1,33 +1,7 @@
ABI policy
==========
-ABI versions are set at the time of major release labeling, and ABI may change
-multiple times between the last labeling and the HEAD label of the git tree
-without warning.
-
-ABI versions, once released are available until such time as their
-deprecation has been noted here for at least one major release cycle, after it
-has been tagged. E.g. the ABI for DPDK 2.0 is shipped, and then the decision to
-remove it is made during the development of DPDK 2.1. The decision will be
-recorded here, shipped with the DPDK 2.1 release, and actually removed when DPDK
-2.2 ships.
-
-ABI versions may be deprecated in whole, or in part as needed by a given update.
-
-Some ABI changes may be too significant to reasonably maintain multiple
-versions of. In those events ABI's may be updated without backward
-compatibility provided. The requirements for doing so are:
-
-#. At least 3 acknowledgments of the need on the dpdk.org
-#. A full deprecation cycle must be made to offer downstream consumers sufficient warning of the change. E.g. if dpdk 2.0 is under development when the change is proposed, a deprecation notice must be added to this file, and released with dpdk 2.0. Then the change may be incorporated for dpdk 2.1
-#. The LIBABIVER variable in the makefile(s) where the ABI changes are incorporated must be incremented in parallel with the ABI changes themselves
-
-Note that the above process for ABI deprecation should not be undertaken
-lightly. ABI stability is extremely important for downstream consumers of the
-DPDK, especially when distributed in shared object form. Every effort should be
-made to preserve ABI whenever possible. For instance, reorganizing public
-structure field for aesthetic or readability purposes should be avoided as it will
-cause ABI breakage. Only significant (e.g. performance) reasons should be seen
-as cause to alter ABI.
+See the guidelines document for details of the ABI policy. ABI deprecation
+notices are to be posted here
Examples of Deprecation Notices
-------------------------------
--
2.1.0
^ permalink raw reply [relevance 28%]
* Re: [dpdk-dev] [PATCHv4 4/4] ABI: Add some documentation
2015-06-29 13:59 28% ` [dpdk-dev] [PATCHv4 4/4] ABI: Add some documentation Neil Horman
@ 2015-06-29 15:07 7% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-06-29 15:07 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-06-29 09:59, Neil Horman:
> People have been asking for ways to use the ABI macros, heres some docs to
> clarify their use. Included is:
>
> * An overview of what ABI is
> * Details of the ABI deprecation process
> * Details of the versioning macros
> * Examples of their use
> * Details of how to use the ABI validator
>
> Thanks to John Mcnamara, who duplicated much of this effort at Intel while I was
> working on it. Much of the introductory material was gathered and cleaned up by
> him
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: john.mcnamara@intel.com
> CC: thomas.monjalon@6wind.com
>
> Change notes:
>
> v2)
> * Fixed RST indentations and spelling errors
> * Rebased to upstream to fix index.rst conflict
>
> v3)
> * Fixed in tact -> intact
> * Added docs to address static linking
> * Removed duplicate documentation from release notes
>
> v4)
> * Fixed more grammatical errors / etc
> * removed BASE_SYMBOL from documentation
Series applied with minor fixes, thanks
This doc should help to produce patches with new ABI without breaking
the old one.
For cases where the backward compatibility is impossible to achieve,
a patch amending this doc to suggest a NEXT_ABI option can be discussed.
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH v3 2/7] mbuf: use the reserved 16 bits for double vlan
2015-06-28 20:36 0% ` Thomas Monjalon
@ 2015-06-30 7:33 3% ` Olivier MATZ
0 siblings, 0 replies; 200+ results
From: Olivier MATZ @ 2015-06-30 7:33 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman; +Cc: dev
Hi,
On 06/28/2015 10:36 PM, Thomas Monjalon wrote:
> Neil, Olivier,
> Your opinions are requested here.
> Thanks
>
> 2015-06-25 08:31, Zhang, Helin:
>> Hi Neil
> [...]
>>> -279,7 +285,7 @@ struct rte_mbuf {
>>> 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;
>>> + uint16_t vlan_tci_outer; /**< Outer VLAN Tag Control Identifier (CPU
>>> +order) */
>> Do you think here is a ABI break or not? Just using the reserved 16 bits, which was
>> intended for the second_vlan_tag. Thanks in advance!
>> I did not see any "Incompatible" reported by validate_abi.sh.
I don't feel there's any ABI break here. I think an application
should not use the "reserved" fields.
Regards,
Olivier
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 08/11] hash: add new functionality to store data in hash table
@ 2015-06-30 7:36 3% ` Stephen Hemminger
0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2015-06-30 7:36 UTC (permalink / raw)
To: De Lara Guarch, Pablo; +Cc: dev
On Sun, 28 Jun 2015 22:23:28 +0000
"De Lara Guarch, Pablo" <pablo.de.lara.guarch@intel.com> wrote:
> Hi Stephen,
>
> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Friday, June 26, 2015 5:50 PM
> > To: De Lara Guarch, Pablo
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v2 08/11] hash: add new functionality to
> > store data in hash table
> >
> > We did same thing with a slightly different method.
> >
> > Subject: rte_hash: split key and bucket size
> >
> > It is useful to store more data in the has bucket than just the key size.
> > For example, storing an addresss and additional data.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
> Did you send this patch? I did not see it in the mailing list...
> Anyway, I like the idea of allowing the user to store variable size data (I was storing 8-byte data).
> So I have sent a v3 with a more similar method, although I still use the new functions,
> and use the parameter data_len for knowing the amount of bytes of data, and I keep constant the input key,
> and return the data in another parameter.
>
> Thanks for it!
> Pablo
I did not send the patch upstream because it would break the ABI and didn't
want to bother fighting that.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types Helin Zhang
@ 2015-06-30 8:43 0% ` Olivier MATZ
2015-07-02 1:30 0% ` Zhang, Helin
0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2015-06-30 8:43 UTC (permalink / raw)
To: Helin Zhang, dev
Hi Helin,
This is greatly documented, thanks!
Please find a small comment below.
On 06/23/2015 03:50 AM, Helin Zhang wrote:
> As there are only 6 bit flags in ol_flags for indicating packet
> types, which is not enough to describe all the possible packet
> types hardware can recognize. For example, i40e hardware can
> recognize more than 150 packet types. Unified packet type is
> composed of L2 type, L3 type, L4 type, tunnel type, inner L2 type,
> inner L3 type and inner L4 type fields, and can be stored in
> 'struct rte_mbuf' of 32 bits field 'packet_type'.
> To avoid breaking ABI compatibility, all the changes would be
> enabled by RTE_NEXT_ABI, which is disabled by default.
>
> [...]
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index 0315561..0ee0c55 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -201,6 +201,493 @@ extern "C" {
> /* 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.
> + * - Bit 3:0 is for L2 types.
> + * - Bit 7:4 is for L3 or outer L3 (for tunneling case) types.
> + * - Bit 11:8 is for L4 or outer L4 (for tunneling case) types.
> + * - Bit 15:12 is for tunnel types.
> + * - Bit 19:16 is for inner L2 types.
> + * - Bit 23:20 is for inner L3 types.
> + * - Bit 27:24 is for inner L4 types.
> + * - Bit 31:28 is reserved.
> + *
> + * To be compatible with Vector PMD, RTE_PTYPE_L3_IPV4, RTE_PTYPE_L3_IPV4_EXT,
> + * RTE_PTYPE_L3_IPV6, RTE_PTYPE_L3_IPV6_EXT, RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP
> + * and RTE_PTYPE_L4_SCTP should be kept as below in a contiguous 7 bits.
> + *
> + * Note that L3 types values are selected for checking IPV4/IPV6 header from
> + * performance point of view. Reading annotations of RTE_ETH_IS_IPV4_HDR and
> + * RTE_ETH_IS_IPV6_HDR is needed for any future changes of L3 type values.
> + *
> + * Note that the packet types of the same packet recognized by different
> + * hardware may be different, as different hardware may have different
> + * capability of packet type recognition.
> + *
> + * examples:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=0x29
> + * | 'version'=6, 'next header'=0x3A
> + * | 'ICMPv6 header'>
> + * will be recognized on i40e hardware as packet type combination of,
> + * RTE_PTYPE_L2_MAC |
> + * RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
> + * RTE_PTYPE_TUNNEL_IP |
> + * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
> + * RTE_PTYPE_INNER_L4_ICMP.
> + *
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=0x2F
> + * | 'GRE header'
> + * | 'version'=6, 'next header'=0x11
> + * | 'UDP header'>
> + * will be recognized on i40e hardware as packet type combination of,
> + * RTE_PTYPE_L2_MAC |
> + * RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
> + * RTE_PTYPE_TUNNEL_GRENAT |
> + * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
> + * RTE_PTYPE_INNER_L4_UDP.
> + */
> +#define RTE_PTYPE_UNKNOWN 0x00000000
> +/**
> + * MAC (Media Access Control) packet type.
> + * It is used for outer packet for tunneling cases.
> + *
> + * Packet format:
> + * <'ether type'=[0x0800|0x86DD|others]>
> + */
> +#define RTE_PTYPE_L2_MAC 0x00000001
I'm wondering if RTE_PTYPE_L2_ETHER is not a better name?
> +/**
> + * MAC (Media Access Control) packet type for time sync.
> + *
> + * Packet format:
> + * <'ether type'=0x88F7>
> + */
> +#define RTE_PTYPE_L2_MAC_TIMESYNC 0x00000002
> +/**
> + * ARP (Address Resolution Protocol) packet type.
> + *
> + * Packet format:
> + * <'ether type'=0x0806>
> + */
> +#define RTE_PTYPE_L2_ARP 0x00000003
> +/**
> + * LLDP (Link Layer Discovery Protocol) packet type.
> + *
> + * Packet format:
> + * <'ether type'=0x88CC>
> + */
> +#define RTE_PTYPE_L2_LLDP 0x00000004
Maybe ETHER should appear in these names too, what do you think?
> +/**
> + * Mask of layer 2 packet types.
> + * It is used for outer packet for tunneling cases.
> + */
> +#define RTE_PTYPE_L2_MASK 0x0000000f
> +/**
> + * IP (Internet Protocol) version 4 packet type.
> + * It is used for outer packet for tunneling cases, and does not contain any
> + * header option.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'ihl'=5>
> + */
> +#define RTE_PTYPE_L3_IPV4 0x00000010
> +/**
> + * IP (Internet Protocol) version 4 packet type.
> + * It is used for outer packet for tunneling cases, and contains header
> + * options.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'ihl'=[6-15], 'options'>
> + */
> +#define RTE_PTYPE_L3_IPV4_EXT 0x00000030
> +/**
> + * IP (Internet Protocol) version 6 packet type.
> + * It is used for outer packet for tunneling cases, and does not contain any
> + * extension header.
> + *
> + * Packet format:
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=0x3B>
> + */
> +#define RTE_PTYPE_L3_IPV6 0x00000040
> +/**
> + * IP (Internet Protocol) version 4 packet type.
> + * It is used for outer packet for tunneling cases, and may or maynot contain
> + * header options.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'ihl'=[5-15], <'options'>>
> + */
> +#define RTE_PTYPE_L3_IPV4_EXT_UNKNOWN 0x00000090
> +/**
> + * IP (Internet Protocol) version 6 packet type.
> + * It is used for outer packet for tunneling cases, and contains extension
> + * headers.
> + *
> + * Packet format:
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> + * 'extension headers'>
> + */
> +#define RTE_PTYPE_L3_IPV6_EXT 0x000000c0
> +/**
> + * IP (Internet Protocol) version 6 packet type.
> + * It is used for outer packet for tunneling cases, and may or maynot contain
> + * extension headers.
> + *
> + * Packet format:
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> + * <'extension headers'>>
> + */
> +#define RTE_PTYPE_L3_IPV6_EXT_UNKNOWN 0x000000e0
> +/**
> + * Mask of layer 3 packet types.
> + * It is used for outer packet for tunneling cases.
> + */
> +#define RTE_PTYPE_L3_MASK 0x000000f0
> +/**
> + * TCP (Transmission Control Protocol) packet type.
> + * It is used for outer packet for tunneling cases.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=6, 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=6>
> + */
> +#define RTE_PTYPE_L4_TCP 0x00000100
> +/**
> + * UDP (User Datagram Protocol) packet type.
> + * It is used for outer packet for tunneling cases.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=17, 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=17>
> + */
> +#define RTE_PTYPE_L4_UDP 0x00000200
> +/**
> + * Fragmented IP (Internet Protocol) packet type.
> + * It is used for outer packet for tunneling cases.
> + *
> + * It refers to those packets of any IP types, which can be recognized as
> + * fragmented. A fragmented packet cannot be recognized as any other L4 types
> + * (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP,
> + * RTE_PTYPE_L4_NONFRAG).
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'MF'=1>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=44>
> + */
> +#define RTE_PTYPE_L4_FRAG 0x00000300
> +/**
> + * SCTP (Stream Control Transmission Protocol) packet type.
> + * It is used for outer packet for tunneling cases.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=132, 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=132>
> + */
> +#define RTE_PTYPE_L4_SCTP 0x00000400
> +/**
> + * ICMP (Internet Control Message Protocol) packet type.
> + * It is used for outer packet for tunneling cases.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=1, 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=1>
> + */
> +#define RTE_PTYPE_L4_ICMP 0x00000500
> +/**
> + * Non-fragmented IP (Internet Protocol) packet type.
> + * It is used for outer packet for tunneling cases.
> + *
> + * It refers to those packets of any IP types, while cannot be recognized as
> + * any of above L4 types (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP,
> + * RTE_PTYPE_L4_FRAG, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP).
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'!=[6|17|44|132|1]>
> + */
> +#define RTE_PTYPE_L4_NONFRAG 0x00000600
> +/**
> + * Mask of layer 4 packet types.
> + * It is used for outer packet for tunneling cases.
> + */
> +#define RTE_PTYPE_L4_MASK 0x00000f00
> +/**
> + * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=[4|41]>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=[4|41]>
> + */
> +#define RTE_PTYPE_TUNNEL_IP 0x00001000
> +/**
> + * GRE (Generic Routing Encapsulation) tunneling packet type.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=47>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=47>
> + */
> +#define RTE_PTYPE_TUNNEL_GRE 0x00002000
> +/**
> + * VXLAN (Virtual eXtensible Local Area Network) tunneling packet type.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=17
> + * | 'destination port'=4798>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=17
> + * | 'destination port'=4798>
> + */
> +#define RTE_PTYPE_TUNNEL_VXLAN 0x00003000
> +/**
> + * NVGRE (Network Virtualization using Generic Routing Encapsulation) tunneling
> + * packet type.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=47
> + * | 'protocol type'=0x6558>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=47
> + * | 'protocol type'=0x6558'>
> + */
> +#define RTE_PTYPE_TUNNEL_NVGRE 0x00004000
> +/**
> + * GENEVE (Generic Network Virtualization Encapsulation) tunneling packet type.
> + *
> + * Packet format:
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=17
> + * | 'destination port'=6081>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=17
> + * | 'destination port'=6081>
> + */
> +#define RTE_PTYPE_TUNNEL_GENEVE 0x00005000
> +/**
> + * Tunneling packet type of Teredo, VXLAN (Virtual eXtensible Local Area
> + * Network) or GRE (Generic Routing Encapsulation) could be recognized as this
> + * packet type, if they can not be recognized independently as of hardware
> + * capability.
> + */
> +#define RTE_PTYPE_TUNNEL_GRENAT 0x00006000
> +/**
> + * Mask of tunneling packet types.
> + */
> +#define RTE_PTYPE_TUNNEL_MASK 0x0000f000
> +/**
> + * MAC (Media Access Control) packet type.
> + * It is used for inner packet type only.
> + *
> + * Packet format (inner only):
> + * <'ether type'=[0x800|0x86DD]>
> + */
> +#define RTE_PTYPE_INNER_L2_MAC 0x00010000
> +/**
> + * MAC (Media Access Control) packet type with VLAN (Virtual Local Area
> + * Network) tag.
> + *
> + * Packet format (inner only):
> + * <'ether type'=[0x800|0x86DD], vlan=[1-4095]>
> + */
> +#define RTE_PTYPE_INNER_L2_MAC_VLAN 0x00020000
> +/**
> + * Mask of inner layer 2 packet types.
> + */
> +#define RTE_PTYPE_INNER_L2_MASK 0x000f0000
> +/**
> + * IP (Internet Protocol) version 4 packet type.
> + * It is used for inner packet only, and does not contain any header option.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'ihl'=5>
> + */
> +#define RTE_PTYPE_INNER_L3_IPV4 0x00100000
> +/**
> + * IP (Internet Protocol) version 4 packet type.
> + * It is used for inner packet only, and contains header options.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'ihl'=[6-15], 'options'>
> + */
> +#define RTE_PTYPE_INNER_L3_IPV4_EXT 0x00200000
> +/**
> + * IP (Internet Protocol) version 6 packet type.
> + * It is used for inner packet only, and does not contain any extension header.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=0x3B>
> + */
> +#define RTE_PTYPE_INNER_L3_IPV6 0x00300000
> +/**
> + * IP (Internet Protocol) version 4 packet type.
> + * It is used for inner packet only, and may or maynot contain header options.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'ihl'=[5-15], <'options'>>
> + */
> +#define RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN 0x00400000
> +/**
> + * IP (Internet Protocol) version 6 packet type.
> + * It is used for inner packet only, and contains extension headers.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> + * 'extension headers'>
> + */
> +#define RTE_PTYPE_INNER_L3_IPV6_EXT 0x00500000
> +/**
> + * IP (Internet Protocol) version 6 packet type.
> + * It is used for inner packet only, and may or maynot contain extension
> + * headers.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> + * <'extension headers'>>
> + */
> +#define RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN 0x00600000
> +/**
> + * Mask of inner layer 3 packet types.
> + */
> +#define RTE_PTYPE_INNER_INNER_L3_MASK 0x00f00000
> +/**
> + * TCP (Transmission Control Protocol) packet type.
> + * It is used for inner packet only.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=6, 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=6>
> + */
> +#define RTE_PTYPE_INNER_L4_TCP 0x01000000
> +/**
> + * UDP (User Datagram Protocol) packet type.
> + * It is used for inner packet only.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=17, 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=17>
> + */
> +#define RTE_PTYPE_INNER_L4_UDP 0x02000000
> +/**
> + * Fragmented IP (Internet Protocol) packet type.
> + * It is used for inner packet only, and may or maynot have layer 4 packet.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'MF'=1>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=44>
> + */
> +#define RTE_PTYPE_INNER_L4_FRAG 0x03000000
> +/**
> + * SCTP (Stream Control Transmission Protocol) packet type.
> + * It is used for inner packet only.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=132, 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=132>
> + */
> +#define RTE_PTYPE_INNER_L4_SCTP 0x04000000
> +/**
> + * ICMP (Internet Control Message Protocol) packet type.
> + * It is used for inner packet only.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'=1, 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'=1>
> + */
> +#define RTE_PTYPE_INNER_L4_ICMP 0x05000000
> +/**
> + * Non-fragmented IP (Internet Protocol) packet type.
> + * It is used for inner packet only, and may or maynot have other unknown layer
> + * 4 packet types.
> + *
> + * Packet format (inner only):
> + * <'ether type'=0x0800
> + * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
> + * or,
> + * <'ether type'=0x86DD
> + * | 'version'=6, 'next header'!=[6|17|44|132|1]>
> + */
> +#define RTE_PTYPE_INNER_L4_NONFRAG 0x06000000
> +/**
> + * Mask of inner layer 4 packet types.
> + */
> +#define RTE_PTYPE_INNER_L4_MASK 0x0f000000
> +
> +/**
> + * 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.
> + */
> +#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.
> + */
> +#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 */
> +
> /**
> * Get the name of a RX offload flag
> *
>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] rte_lpm4 with expanded next hop support now available
@ 2015-07-01 6:18 3% Matthew Hall
2015-07-01 11:20 4% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: Matthew Hall @ 2015-07-01 6:18 UTC (permalink / raw)
To: <dev@dpdk.org>
Hello,
Based on the wonderful assistance from Vladimir and Stephen and a close friend of mine that is a hypervisor developer who helped me reverse engineer and rewrite rte_lpm_lookupx4, I have got a known-working version of rte_lpm4 with expanded 24 bit next hop support available here:
https://github.com/megahall/dpdk_mhall/tree/megahall/lpm-expansion
I'm going to be working on rte_lpm6 next, it seems to take a whole ton of memory to run the self-test, if anybody knows how much that would help, as it seems to run out when I tried it.
Sadly this change is not ABI compatible or performance compatible with the original rte_lpm because I had to hack on the bitwise layout to get more data in there, and it will run maybe 50% slower because it has to access some more memory.
Despite all this I'd really like to do the right thing find a way to contribute it back, perhaps as a second kind of rte_lpm, so I wouldn't be the only person using it and forking the code when I already met several others who needed it. I could use some ideas how to handle the situation.
Matthew.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] rte_lpm4 with expanded next hop support now available
2015-07-01 6:18 3% [dpdk-dev] rte_lpm4 with expanded next hop support now available Matthew Hall
@ 2015-07-01 11:20 4% ` Bruce Richardson
2015-07-01 15:59 0% ` Matthew Hall
0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2015-07-01 11:20 UTC (permalink / raw)
To: Matthew Hall; +Cc: <dev@dpdk.org>
On Tue, Jun 30, 2015 at 11:18:35PM -0700, Matthew Hall wrote:
> Hello,
>
> Based on the wonderful assistance from Vladimir and Stephen and a close friend of mine that is a hypervisor developer who helped me reverse engineer and rewrite rte_lpm_lookupx4, I have got a known-working version of rte_lpm4 with expanded 24 bit next hop support available here:
>
> https://github.com/megahall/dpdk_mhall/tree/megahall/lpm-expansion
>
> I'm going to be working on rte_lpm6 next, it seems to take a whole ton of memory to run the self-test, if anybody knows how much that would help, as it seems to run out when I tried it.
>
> Sadly this change is not ABI compatible or performance compatible with the original rte_lpm because I had to hack on the bitwise layout to get more data in there, and it will run maybe 50% slower because it has to access some more memory.
>
> Despite all this I'd really like to do the right thing find a way to contribute it back, perhaps as a second kind of rte_lpm, so I wouldn't be the only person using it and forking the code when I already met several others who needed it. I could use some ideas how to handle the situation.
>
> Matthew.
Could you maybe send a patch (or set) with all your changes in it here for us
to look at? [I did look at it in github, but I'm not very familiar with github
and the changes seem to be spread over a whole series of commits]
In terms of ABI issues, the overall function set for lpm4 library is not that
big, so it may be possible to maintain old a new copies of the functions in parallel
for one release, and solve the ABI issues that way. I'm quite keen to get these
changes in, since I think being limited to 255 next hops is quite a limitation
for many cases.
A final interesting suggestion I might throw out, is: can we make the lpm library
configurable in that it can use either 8-bit, 16/24 bit or even pointer based
next hops (I won't say 64-bit, as for pointers we might be able to get away
with less than 64-bits being stored)? Would such a thing be useful to people?
Regards,
/Bruce
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 0/7] Expose IXGBE extended stats to DPDK apps
2015-06-26 12:59 3% [dpdk-dev] [PATCH v3 0/7] Expose IXGBE extended stats to DPDK apps Maryam Tahhan
2015-06-26 12:59 9% ` [dpdk-dev] [PATCH v3 4/7] ethdev: remove HW specific stats in stats structs Maryam Tahhan
@ 2015-07-01 14:27 0% ` Tahhan, Maryam
1 sibling, 0 replies; 200+ results
From: Tahhan, Maryam @ 2015-07-01 14:27 UTC (permalink / raw)
To: dev, Olivier MATZ
> This patch set implements xstats_get() and xstats_reset() in dev_ops for ixgbe
> to expose detailed error statistics to DPDK applications. The dump_cfg
> application was extended to demonstrate the usage of retrieving statistics for
> DPDK interfaces and renamed to proc_info in order reflect this new
> functionality. This patch set also removes non generic statistics from the
> statistics strings at the ethdev level and marks the relevant registers as
> depricated in struct rte_eth_stats.
>
> v2:
> - Fixed patch dependencies.
> - Broke down patches into smaller logical changes.
>
> v3:
> - Removes non-generic stats fields in rte_stats_strings and deprecates
> the fields related to them in struct rte_eth_stats.
> - Modifies rte_eth_xstats_get() to return generic stats and extended stats.
>
> Maryam Tahhan (7):
> ixgbe: move stats register reads to a new function
> ixgbe: add functions to get and reset xstats
> ethdev: expose extended error stats
> ethdev: remove HW specific stats in stats structs
> ixgbe: add NIC specific stats removed from ethdev
> app: remove dump_cfg
> app: add a new app proc_info
>
> MAINTAINERS | 4 +
> app/Makefile | 2 +-
> app/dump_cfg/Makefile | 45 ----
> app/dump_cfg/main.c | 92 -------
> app/proc_info/Makefile | 45 ++++
> app/proc_info/main.c | 512
> +++++++++++++++++++++++++++++++++++++++
> doc/guides/rel_notes/abi.rst | 11 +
> drivers/net/ixgbe/ixgbe_ethdev.c | 192 ++++++++++++---
> lib/librte_ether/rte_ethdev.c | 29 ++-
> lib/librte_ether/rte_ethdev.h | 30 ++-
> mk/rte.sdktest.mk | 4 +-
> 11 files changed, 762 insertions(+), 204 deletions(-) delete mode 100644
> app/dump_cfg/Makefile delete mode 100644 app/dump_cfg/main.c create
> mode 100644 app/proc_info/Makefile create mode 100644
> app/proc_info/main.c
>
> --
> 1.9.3
Hi Olivier,
I posted a new patch set with the suggested mods. Let me know if there are any issues.
Thanks in advance.
Best Regards,
Maryam
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] rte_lpm4 with expanded next hop support now available
2015-07-01 11:20 4% ` Bruce Richardson
@ 2015-07-01 15:59 0% ` Matthew Hall
0 siblings, 0 replies; 200+ results
From: Matthew Hall @ 2015-07-01 15:59 UTC (permalink / raw)
To: Bruce Richardson; +Cc: <dev@dpdk.org>
On Jul 1, 2015, at 4:20 AM, Bruce Richardson <bruce.richardson@intel.com> wrote:
> Could you maybe send a patch (or set) with all your changes in it here for us
> to look at? [I did look at it in github, but I'm not very familiar with github
> and the changes seem to be spread over a whole series of commits]
Here is a view of the specific commits:
https://github.com/megahall/dpdk_mhall/compare/megahall/lpm-expansion
I'll work on emails when I get a moment. I was hoping since the branch is open to all for download someone could sync it and try it in an environment that has some kind of performance tests / known results for the self-tests as my development setup is not that great compared to some of the other DPDK engineers out there.
> In terms of ABI issues, the overall function set for lpm4 library is not that
> big, so it may be possible to maintain old a new copies of the functions in parallel
> for one release, and solve the ABI issues that way. I'm quite keen to get these
> changes in, since I think being limited to 255 next hops is quite a limitation
> for many cases.
Sounds good.
> A final interesting suggestion I might throw out, is: can we make the lpm library
> configurable in that it can use either 8-bit, 16/24 bit or even pointer based
> next hops (I won't say 64-bit, as for pointers we might be able to get away
> with less than 64-bits being stored)? Would such a thing be useful to people?
I think this could be pretty nice, the tricky part is that, at least in the version Vladimir and Stephen helped me cook up, a lot of bitfield trickery was involved. So we'd need to switch away from bitfields to something a bit more flexible or easy to work with when variable configuration comes into the picture. Also not sure how it'd work at runtime versus compilation, etc. You guys know more than me about this stuff I think.
Matthew.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping
2015-06-29 13:42 4% [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping John McNamara
2015-06-29 13:42 14% ` [dpdk-dev] [PATCH v2 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
@ 2015-07-02 1:24 0% ` Lu, Wenzhuo
2015-07-02 15:16 4% ` [dpdk-dev] [PATCH v3 " John McNamara
2 siblings, 0 replies; 200+ results
From: Lu, Wenzhuo @ 2015-07-02 1:24 UTC (permalink / raw)
To: Mcnamara, John, dev
Hi,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of John McNamara
> Sent: Monday, June 29, 2015 9:42 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588
> timestamping
>
> This patchset adds ethdev API to enable and read IEEE1588/802.1AS PTP
> timestamps from devices that support it. The following functions are added:
>
> rte_eth_timesync_enable()
> rte_eth_timesync_disable()
> rte_eth_timesync_read_rx_timestamp()
> rte_eth_timesync_read_tx_timestamp()
>
> The "ieee1588" forwarding mode in testpmd is also refactored to demonstrate
> the new API and to clean up the code.
>
> Adds support for igb, ixgbe and i40e.
>
>
> V2:
> * Added i40e support.
>
> * Renamed ethdev functions from rte_eth_ieee15888_*() to
> rte_eth_timesync_*()
> since 802.1AS can be supported through the same interfaces.
>
> V1:
> * Initial version for
>
> John McNamara (7):
> ethdev: add support for ieee1588 timestamping
> e1000: add support for ieee1588 timestamping
> ixgbe: add support for ieee1588 timestamping
> i40e: add support for ieee1588 timestamping
> app/testpmd: refactor ieee1588 forwarding
> doc: document ieee1588 forwarding mode
> abi: announce mbuf addition for ieee1588 in DPDK 2.2
>
> app/test-pmd/ieee1588fwd.c | 466 ++--------------------------
> doc/guides/rel_notes/abi.rst | 5 +
> doc/guides/testpmd_app_ug/run_app.rst | 2 +-
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +
> drivers/net/e1000/igb_ethdev.c | 115 +++++++
> drivers/net/i40e/i40e_ethdev.c | 143 +++++++++
> drivers/net/i40e/i40e_rxtx.c | 39 ++-
> drivers/net/ixgbe/ixgbe_ethdev.c | 122 ++++++++
> lib/librte_ether/rte_ethdev.c | 70 ++++-
> lib/librte_ether/rte_ethdev.h | 90 +++++-
> lib/librte_ether/rte_ether_version.map | 4 +
> 11 files changed, 615 insertions(+), 443 deletions(-)
>
> --
> 1.8.1.4
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types
2015-06-30 8:43 0% ` Olivier MATZ
@ 2015-07-02 1:30 0% ` Zhang, Helin
2015-07-02 9:31 0% ` Olivier MATZ
0 siblings, 1 reply; 200+ results
From: Zhang, Helin @ 2015-07-02 1:30 UTC (permalink / raw)
To: Olivier MATZ, dev
Hi Oliver
Thanks for your helps!
> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Tuesday, June 30, 2015 4:44 PM
> To: Zhang, Helin; dev@dpdk.org
> Cc: Cao, Waterman; Liang, Cunming; Liu, Jijiang; Ananyev, Konstantin; Richardson,
> Bruce; yongwang@vmware.com; Wu, Jingjing
> Subject: Re: [PATCH v8 03/18] mbuf: add definitions of unified packet types
>
> Hi Helin,
>
> This is greatly documented, thanks!
> Please find a small comment below.
>
> On 06/23/2015 03:50 AM, Helin Zhang wrote:
> > As there are only 6 bit flags in ol_flags for indicating packet types,
> > which is not enough to describe all the possible packet types hardware
> > can recognize. For example, i40e hardware can recognize more than 150
> > packet types. Unified packet type is composed of L2 type, L3 type, L4
> > type, tunnel type, inner L2 type, inner L3 type and inner L4 type
> > fields, and can be stored in 'struct rte_mbuf' of 32 bits field
> > 'packet_type'.
> > To avoid breaking ABI compatibility, all the changes would be enabled
> > by RTE_NEXT_ABI, which is disabled by default.
> >
> > [...]
> > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> > index 0315561..0ee0c55 100644
> > --- a/lib/librte_mbuf/rte_mbuf.h
> > +++ b/lib/librte_mbuf/rte_mbuf.h
> > @@ -201,6 +201,493 @@ extern "C" {
> > /* 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.
> > + * - Bit 3:0 is for L2 types.
> > + * - Bit 7:4 is for L3 or outer L3 (for tunneling case) types.
> > + * - Bit 11:8 is for L4 or outer L4 (for tunneling case) types.
> > + * - Bit 15:12 is for tunnel types.
> > + * - Bit 19:16 is for inner L2 types.
> > + * - Bit 23:20 is for inner L3 types.
> > + * - Bit 27:24 is for inner L4 types.
> > + * - Bit 31:28 is reserved.
> > + *
> > + * To be compatible with Vector PMD, RTE_PTYPE_L3_IPV4,
> > +RTE_PTYPE_L3_IPV4_EXT,
> > + * RTE_PTYPE_L3_IPV6, RTE_PTYPE_L3_IPV6_EXT, RTE_PTYPE_L4_TCP,
> > +RTE_PTYPE_L4_UDP
> > + * and RTE_PTYPE_L4_SCTP should be kept as below in a contiguous 7 bits.
> > + *
> > + * Note that L3 types values are selected for checking IPV4/IPV6
> > +header from
> > + * performance point of view. Reading annotations of
> > +RTE_ETH_IS_IPV4_HDR and
> > + * RTE_ETH_IS_IPV6_HDR is needed for any future changes of L3 type values.
> > + *
> > + * Note that the packet types of the same packet recognized by
> > +different
> > + * hardware may be different, as different hardware may have
> > +different
> > + * capability of packet type recognition.
> > + *
> > + * examples:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=0x29
> > + * | 'version'=6, 'next header'=0x3A
> > + * | 'ICMPv6 header'>
> > + * will be recognized on i40e hardware as packet type combination of,
> > + * RTE_PTYPE_L2_MAC |
> > + * RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
> > + * RTE_PTYPE_TUNNEL_IP |
> > + * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
> > + * RTE_PTYPE_INNER_L4_ICMP.
> > + *
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=0x2F
> > + * | 'GRE header'
> > + * | 'version'=6, 'next header'=0x11
> > + * | 'UDP header'>
> > + * will be recognized on i40e hardware as packet type combination of,
> > + * RTE_PTYPE_L2_MAC |
> > + * RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
> > + * RTE_PTYPE_TUNNEL_GRENAT |
> > + * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
> > + * RTE_PTYPE_INNER_L4_UDP.
> > + */
> > +#define RTE_PTYPE_UNKNOWN 0x00000000
> > +/**
> > + * MAC (Media Access Control) packet type.
> > + * It is used for outer packet for tunneling cases.
> > + *
> > + * Packet format:
> > + * <'ether type'=[0x0800|0x86DD|others]> */
> > +#define RTE_PTYPE_L2_MAC 0x00000001
>
> I'm wondering if RTE_PTYPE_L2_ETHER is not a better name?
Ethernet includes both Data Link Layer and Physical Layer, while MAC is for Data Link
Layer only. I would prefer to keep 'MAC' in the names, rather than 'ether'.
Any opinions from others?
Regards,
Helin
>
>
> > +/**
> > + * MAC (Media Access Control) packet type for time sync.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x88F7>
> > + */
> > +#define RTE_PTYPE_L2_MAC_TIMESYNC 0x00000002
> > +/**
> > + * ARP (Address Resolution Protocol) packet type.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0806>
> > + */
> > +#define RTE_PTYPE_L2_ARP 0x00000003
> > +/**
> > + * LLDP (Link Layer Discovery Protocol) packet type.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x88CC>
> > + */
> > +#define RTE_PTYPE_L2_LLDP 0x00000004
>
> Maybe ETHER should appear in these names too, what do you think?
Same as above.
>
>
>
>
> > +/**
> > + * Mask of layer 2 packet types.
> > + * It is used for outer packet for tunneling cases.
> > + */
> > +#define RTE_PTYPE_L2_MASK 0x0000000f
> > +/**
> > + * IP (Internet Protocol) version 4 packet type.
> > + * It is used for outer packet for tunneling cases, and does not
> > +contain any
> > + * header option.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'ihl'=5>
> > + */
> > +#define RTE_PTYPE_L3_IPV4 0x00000010
> > +/**
> > + * IP (Internet Protocol) version 4 packet type.
> > + * It is used for outer packet for tunneling cases, and contains
> > +header
> > + * options.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'ihl'=[6-15], 'options'> */
> > +#define RTE_PTYPE_L3_IPV4_EXT 0x00000030
> > +/**
> > + * IP (Internet Protocol) version 6 packet type.
> > + * It is used for outer packet for tunneling cases, and does not
> > +contain any
> > + * extension header.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=0x3B> */
> > +#define RTE_PTYPE_L3_IPV6 0x00000040
> > +/**
> > + * IP (Internet Protocol) version 4 packet type.
> > + * It is used for outer packet for tunneling cases, and may or maynot
> > +contain
> > + * header options.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'ihl'=[5-15], <'options'>> */
> > +#define RTE_PTYPE_L3_IPV4_EXT_UNKNOWN 0x00000090
> > +/**
> > + * IP (Internet Protocol) version 6 packet type.
> > + * It is used for outer packet for tunneling cases, and contains
> > +extension
> > + * headers.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> > + * 'extension headers'>
> > + */
> > +#define RTE_PTYPE_L3_IPV6_EXT 0x000000c0
> > +/**
> > + * IP (Internet Protocol) version 6 packet type.
> > + * It is used for outer packet for tunneling cases, and may or maynot
> > +contain
> > + * extension headers.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> > + * <'extension headers'>>
> > + */
> > +#define RTE_PTYPE_L3_IPV6_EXT_UNKNOWN 0x000000e0
> > +/**
> > + * Mask of layer 3 packet types.
> > + * It is used for outer packet for tunneling cases.
> > + */
> > +#define RTE_PTYPE_L3_MASK 0x000000f0
> > +/**
> > + * TCP (Transmission Control Protocol) packet type.
> > + * It is used for outer packet for tunneling cases.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=6, 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=6>
> > + */
> > +#define RTE_PTYPE_L4_TCP 0x00000100
> > +/**
> > + * UDP (User Datagram Protocol) packet type.
> > + * It is used for outer packet for tunneling cases.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=17, 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=17>
> > + */
> > +#define RTE_PTYPE_L4_UDP 0x00000200
> > +/**
> > + * Fragmented IP (Internet Protocol) packet type.
> > + * It is used for outer packet for tunneling cases.
> > + *
> > + * It refers to those packets of any IP types, which can be
> > +recognized as
> > + * fragmented. A fragmented packet cannot be recognized as any other
> > +L4 types
> > + * (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP, RTE_PTYPE_L4_SCTP,
> > +RTE_PTYPE_L4_ICMP,
> > + * RTE_PTYPE_L4_NONFRAG).
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'MF'=1>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=44>
> > + */
> > +#define RTE_PTYPE_L4_FRAG 0x00000300
> > +/**
> > + * SCTP (Stream Control Transmission Protocol) packet type.
> > + * It is used for outer packet for tunneling cases.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=132, 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=132>
> > + */
> > +#define RTE_PTYPE_L4_SCTP 0x00000400
> > +/**
> > + * ICMP (Internet Control Message Protocol) packet type.
> > + * It is used for outer packet for tunneling cases.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=1, 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=1>
> > + */
> > +#define RTE_PTYPE_L4_ICMP 0x00000500
> > +/**
> > + * Non-fragmented IP (Internet Protocol) packet type.
> > + * It is used for outer packet for tunneling cases.
> > + *
> > + * It refers to those packets of any IP types, while cannot be
> > +recognized as
> > + * any of above L4 types (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP,
> > + * RTE_PTYPE_L4_FRAG, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP).
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'!=[6|17|44|132|1]> */
> > +#define RTE_PTYPE_L4_NONFRAG 0x00000600
> > +/**
> > + * Mask of layer 4 packet types.
> > + * It is used for outer packet for tunneling cases.
> > + */
> > +#define RTE_PTYPE_L4_MASK 0x00000f00
> > +/**
> > + * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=[4|41]>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=[4|41]> */
> > +#define RTE_PTYPE_TUNNEL_IP 0x00001000
> > +/**
> > + * GRE (Generic Routing Encapsulation) tunneling packet type.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=47>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=47>
> > + */
> > +#define RTE_PTYPE_TUNNEL_GRE 0x00002000
> > +/**
> > + * VXLAN (Virtual eXtensible Local Area Network) tunneling packet type.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=17
> > + * | 'destination port'=4798>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=17
> > + * | 'destination port'=4798>
> > + */
> > +#define RTE_PTYPE_TUNNEL_VXLAN 0x00003000
> > +/**
> > + * NVGRE (Network Virtualization using Generic Routing Encapsulation)
> > +tunneling
> > + * packet type.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=47
> > + * | 'protocol type'=0x6558>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=47
> > + * | 'protocol type'=0x6558'>
> > + */
> > +#define RTE_PTYPE_TUNNEL_NVGRE 0x00004000
> > +/**
> > + * GENEVE (Generic Network Virtualization Encapsulation) tunneling packet
> type.
> > + *
> > + * Packet format:
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=17
> > + * | 'destination port'=6081>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=17
> > + * | 'destination port'=6081>
> > + */
> > +#define RTE_PTYPE_TUNNEL_GENEVE 0x00005000
> > +/**
> > + * Tunneling packet type of Teredo, VXLAN (Virtual eXtensible Local
> > +Area
> > + * Network) or GRE (Generic Routing Encapsulation) could be
> > +recognized as this
> > + * packet type, if they can not be recognized independently as of
> > +hardware
> > + * capability.
> > + */
> > +#define RTE_PTYPE_TUNNEL_GRENAT 0x00006000
> > +/**
> > + * Mask of tunneling packet types.
> > + */
> > +#define RTE_PTYPE_TUNNEL_MASK 0x0000f000
> > +/**
> > + * MAC (Media Access Control) packet type.
> > + * It is used for inner packet type only.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=[0x800|0x86DD]>
> > + */
> > +#define RTE_PTYPE_INNER_L2_MAC 0x00010000
> > +/**
> > + * MAC (Media Access Control) packet type with VLAN (Virtual Local
> > +Area
> > + * Network) tag.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=[0x800|0x86DD], vlan=[1-4095]> */
> > +#define RTE_PTYPE_INNER_L2_MAC_VLAN 0x00020000
> > +/**
> > + * Mask of inner layer 2 packet types.
> > + */
> > +#define RTE_PTYPE_INNER_L2_MASK 0x000f0000
> > +/**
> > + * IP (Internet Protocol) version 4 packet type.
> > + * It is used for inner packet only, and does not contain any header option.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'ihl'=5>
> > + */
> > +#define RTE_PTYPE_INNER_L3_IPV4 0x00100000
> > +/**
> > + * IP (Internet Protocol) version 4 packet type.
> > + * It is used for inner packet only, and contains header options.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'ihl'=[6-15], 'options'> */
> > +#define RTE_PTYPE_INNER_L3_IPV4_EXT 0x00200000
> > +/**
> > + * IP (Internet Protocol) version 6 packet type.
> > + * It is used for inner packet only, and does not contain any extension header.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=0x3B> */
> > +#define RTE_PTYPE_INNER_L3_IPV6 0x00300000
> > +/**
> > + * IP (Internet Protocol) version 4 packet type.
> > + * It is used for inner packet only, and may or maynot contain header options.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'ihl'=[5-15], <'options'>> */ #define
> > +RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN 0x00400000
> > +/**
> > + * IP (Internet Protocol) version 6 packet type.
> > + * It is used for inner packet only, and contains extension headers.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> > + * 'extension headers'>
> > + */
> > +#define RTE_PTYPE_INNER_L3_IPV6_EXT 0x00500000
> > +/**
> > + * IP (Internet Protocol) version 6 packet type.
> > + * It is used for inner packet only, and may or maynot contain
> > +extension
> > + * headers.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> > + * <'extension headers'>>
> > + */
> > +#define RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN 0x00600000
> > +/**
> > + * Mask of inner layer 3 packet types.
> > + */
> > +#define RTE_PTYPE_INNER_INNER_L3_MASK 0x00f00000
> > +/**
> > + * TCP (Transmission Control Protocol) packet type.
> > + * It is used for inner packet only.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=6, 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=6>
> > + */
> > +#define RTE_PTYPE_INNER_L4_TCP 0x01000000
> > +/**
> > + * UDP (User Datagram Protocol) packet type.
> > + * It is used for inner packet only.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=17, 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=17>
> > + */
> > +#define RTE_PTYPE_INNER_L4_UDP 0x02000000
> > +/**
> > + * Fragmented IP (Internet Protocol) packet type.
> > + * It is used for inner packet only, and may or maynot have layer 4 packet.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'MF'=1>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=44>
> > + */
> > +#define RTE_PTYPE_INNER_L4_FRAG 0x03000000
> > +/**
> > + * SCTP (Stream Control Transmission Protocol) packet type.
> > + * It is used for inner packet only.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=132, 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=132>
> > + */
> > +#define RTE_PTYPE_INNER_L4_SCTP 0x04000000
> > +/**
> > + * ICMP (Internet Control Message Protocol) packet type.
> > + * It is used for inner packet only.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'=1, 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'=1>
> > + */
> > +#define RTE_PTYPE_INNER_L4_ICMP 0x05000000
> > +/**
> > + * Non-fragmented IP (Internet Protocol) packet type.
> > + * It is used for inner packet only, and may or maynot have other
> > +unknown layer
> > + * 4 packet types.
> > + *
> > + * Packet format (inner only):
> > + * <'ether type'=0x0800
> > + * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
> > + * or,
> > + * <'ether type'=0x86DD
> > + * | 'version'=6, 'next header'!=[6|17|44|132|1]> */
> > +#define RTE_PTYPE_INNER_L4_NONFRAG 0x06000000
> > +/**
> > + * Mask of inner layer 4 packet types.
> > + */
> > +#define RTE_PTYPE_INNER_L4_MASK 0x0f000000
> > +
> > +/**
> > + * 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.
> > + */
> > +#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.
> > + */
> > +#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 */
> > +
> > /**
> > * Get the name of a RX offload flag
> > *
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8 00/18] unified packet type
2015-06-23 16:13 0% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Ananyev, Konstantin
@ 2015-07-02 8:45 0% ` Liu, Yong
0 siblings, 0 replies; 200+ results
From: Liu, Yong @ 2015-07-02 8:45 UTC (permalink / raw)
To: Ananyev, Konstantin, Zhang, Helin, dev
Tested-by: Yong Liu <yong.liu@intel.com>
- Tested Commit: 7e1fa1de8a536c68f6af76cf8d222a9e948c93ba
- OS: Fedora20 3.15.5
- GCC: gcc version 4.8.3 20140911
- CPU: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz
- NIC: Intel Corporation XL710 10-Gigabit SFI/SFP+ [8086:1572]
- NIC: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ [8086:10fb]
- NIC: Intel Corporation I350 Gigabit Network Connection [8086:1521]
- Default x86_64-native-linuxapp-gcc configuration
- Prerequisites: Enable CONFIG_RTE_NEXT_ABI in dpdk configuration
Disable CONFIG_RTE_IXGBE_INC_VECTOR in dpdk configuration
- Total 10 cases, 10 passed, 0 failed
- Case: L2 packet type detect
Description: check L2 only packet can be normally detected by Fortville
Command / instruction:
Start testpmd and enable rxonly verbose mode
./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 4 -- -i --txqflags=0x0
set fwd rxonly
set verbose 1
start
Send time sync packet and verify Timesync packet detected
Send ARP packet and verify ARP packet detected
Send LLDP packet and verify LLDP packet detected
- Case: IPv4&L4 packet type detect
Description: check L3 and L4 packet can be normally detected
Fortville did not detect whether packet contian ipv4 header options, so L3
type will be shown as IPV4_EXT_UNKNOWN
Command / instruction:
Start testpmd and enable rxonly verbose mode
Send IP only packet and verify L3 packet detected
Send IP+UDP packet and verify L3&L4 packet detected
Send IP+TCP packet and verify L3&L4 packet detected
Send IP+SCTP packet and verify L3&L4 packet detected
Send IP+ICMP packet and verify L3&L4 packet detected
Send IP fragment+TCP packet and verify L3&L4 packet detected
- Case: IPv6&L4 packet type detect
Description: check IPv6 and L4 packet can be normally detected
Fortville did not detect whether packet contian ipv6 extension options, so
L3 type will be shown as IPV6_EXT_UNKNOWN
Command / instruction:
Start testpmd and enable rxonly verbose mode
Send IPv6 only packet and verify L3 packet detected
Send IPv6+UDP packet and verify L3&L4 packet detected
Send IPv6+TCP packet and verify L3&L4 packet detected
Send IPv6 fragment+TCP packet and verify L3&L4 packet detected
- Case: IP in IPv4 tunnel packet type detect
Description: check tunnel packet can be normally detected by Fortville
Command / instruction:
Send IPv4+IPv4 fragment packet and verify tunnel packet detected
Send IPv4+IPv4 packet and verify tunnel packet detected
Send IPv4+IPv4+UDP packet and verify tunnel packet detected
Send IPv4+IPv4+TCP packet and verify tunnel packet detected
Send IPv4+IPv4+SCTP packet and verify tunnel packet detected
Send IPv4+IPv4+ICMP packet and verify tunnel packet detected
Send IPv4+IPv6 fragment packet and verify tunnel packet detected
Send IPv4+IPv6 packet and verify tunnel packet detected
Send IPv4+IPv6+UDP packet and verify tunnel packet detected
Send IPv4+IPv6+TCP packet and verify tunnel packet detected
Send IPv4+IPv6+SCTP packet and verify tunnel packet detected
Send IPv4+IPv6+ICMP packet and verify tunnel packet detected
- Case: IPv6 in IPv4 tunnel packet type detect by niantic
Description: check tunnel packet can be normally detected by Niantic
Niantic only can detect few types of ip in ip tunnel packets, this case
designed to test them.
Command / instruction:
Send IPv4+IPv6 packet and verify tunnel packet detected
Send IPv4+IPv6_EXT packet and verify tunnel packet detected
Send IPv4+IPv6+UDP packet and verify tunnel packet detected
Send IPv4+IPv6+TCP packet and verify tunnel packet detected
Send IPv4+IPv6_EXT+UDP packet and verify tunnel packet detected
Send IPv4+IPv6_EXT+TCP packet and verify tunnel packet detected
- Case: IP in IPv6 tunnel packet type detect
Description: check tunnel packet can be normally detected by Fortville
Command / instruction:
Send IPv6+IPv4 fragment packet and verify tunnel packet detected
Send IPv6+IPv4 packet and verify tunnel packet detected
Send IPv6+IPv4+UDP packet and verify tunnel packet detected
Send IPv6+IPv4+TCP packet and verify tunnel packet detected
Send IPv6+IPv4+SCTP packet and verify tunnel packet detected
Send IPv6+IPv4+ICMP packet and verify tunnel packet detected
Send IPv6+IPv6 fragment packet and verify tunnel packet detected
Send IPv6+IPv6 packet and verify tunnel packet detected
Send IPv6+IPv6+UDP packet and verify tunnel packet detected
Send IPv6+IPv6+TCP packet and verify tunnel packet detected
Send IPv6+IPv6+SCTP packet and verify tunnel packet detected
Send IPv6+IPv6+ICMP packet and verify tunnel packet detected
- Case: NVGRE tunnel packet type detect
Description: check tunnel packet can be normally detected by Fortville
Fortville did not distinguish GRE/Teredo/Vxlan packets, all those types
will be displayed as GRENAT
Command / instruction:
Send IPv4+NVGRE fragment packet and verify tunnel packet detected
Send IPV4+NVGRE+MAC packet and verify tunnel packet detected
Send IPv4+NVGRE+MAC_VLAN packet and verify tunnel packet detected
Send IPv4+NVGRE+MAC_VLAN+IPv4 fragment packet and verify tunnel packet
detected
Send IPv4+NVGRE+MAC_VLAN+IPv4 packet and verify tunnel packet detected
Send IPv4+NVGRE+MAC_VLAN+IPv4+UDP packet and verify tunnel packet detected
Send IPv4+NVGRE+MAC_VLAN+IPv4+TCP packet and verify tunnel packet detected
Send IPv4+NVGRE+MAC_VLAN+IPv4+SCTP packet and verify tunnel packet
detected
Send IPv4+NVGRE+MAC_VLAN+IPv4+ICMP packet and verify tunnel packet
detected
Send IPv4+NVGRE+MAC_VLAN+IPv6+IPv6 fragment acket and verify tunnel packet
detected
Send IPv4+NVGRE+MAC_VLAN+IPv6 packet and verify tunnel packet detected
Send IPv4+NVGRE+MAC_VLAN+IPv6+UDP packet and verify tunnel packet detected
Send IPv4+NVGRE+MAC_VLAN+IPv6+TCP packet and verify tunnel packet detected
Send IPv4+NVGRE+MAC_VLAN+IPv6+SCTP packet and verify tunnel packet
detected
Send IPv4+NVGRE+MAC_VLAN+IPv6+ICMP packet and verify tunnel packet
detected
- Case: NVGRE in IPv6 tunnel packet type detect
Description: check tunnel packet can be normally detected by Fortville
Fortville did not distinguish GRE/Teredo/Vxlan packets, all those types
will be displayed as GRENAT
Command / instruction:
Send IPV6+NVGRE+MAC packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv4 fragment packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv4 packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv4+UDP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv4+TCP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv4+SCTP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv4+ICMP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv6 fragment packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv6 packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv6+UDP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv6+TCP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv6+SCTP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC+IPv6+ICMP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC_VLAN+IPv4 fragment packet and verify tunnel packet
detected
Send IPV6+NVGRE+MAC_VLAN+IPv4 packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC_VLAN+IPv4+UDP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC_VLAN+IPv4+TCP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC_VLAN+IPv4+SCTP packet and verify tunnel packet
detected
Send IPV6+NVGRE+MAC_VLAN+IPv4+ICMP packet and verify tunnel packet
detected
Send IPV6+NVGRE+MAC_VLAN+IPv6 fragment packet and verify tunnel packet
detected
Send IPV6+NVGRE+MAC_VLAN+IPv6 packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC_VLAN+IPv6+UDP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC_VLAN+IPv6+TCP packet and verify tunnel packet detected
Send IPV6+NVGRE+MAC_VLAN+IPv6+SCTP packet and verify tunnel packet
detected
Send IPV6+NVGRE+MAC_VLAN+IPv6+ICMP packet and verify tunnel packet
detected
Send IPV6+NVGRE+MAC_VLAN+IPv6 fragment packet and verify tunnel packet
detected
- Case: GRE tunnel packet type detect
Description: check tunnel packet can be normally detected by Fortville
Fortville did not distinguish GRE/Teredo/Vxlan packets, all those types
will be displayed as GRENAT
Command / instruction:
Send IPv4+GRE+IPv4 fragment packet and verify tunnel packet detected
Send IPv4+GRE+IPv4 packet and verify tunnel packet detected
Send IPv4+GRE+IPv4+UDP packet and verify tunnel packet detected
Send IPv4+GRE+IPv4+TCP packet and verify tunnel packet detected
Send IPv4+GRE+IPv4+SCTP packet and verify tunnel packet detected
Send IPv4+GRE+IPv4+ICMP packet and verify tunnel packet detected
Send IPv4+GRE packet and verify tunnel packet detected
- Case: Vxlan tunnel packet type detect
Description: check tunnel packet can be normally detected by Fortville
Fortville did not distinguish GRE/Teredo/Vxlan packets, all those types
will be displayed as GRENAT
Command / instruction:
Add vxlan tunnle port filter on receive port
rx_vxlan_port add 4789 0
Send IPv4+Vxlan+MAC+IPv4 fragment packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv4 packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv4+UDP packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv4+TCP packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv4+SCTP packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv4+ICMP packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv6 fragment packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv6 packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv6+UDP packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv6+TCP packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv6+SCTP packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC+IPv6+ICMP packet and verify tunnel packet detected
Send IPv4+Vxlan+MAC packet and verify tunnel packet detected
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ananyev, Konstantin
> Sent: Wednesday, June 24, 2015 12:14 AM
> To: Zhang, Helin; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v8 00/18] unified packet type
>
>
>
> > -----Original Message-----
> > From: Zhang, Helin
> > Sent: Tuesday, June 23, 2015 2:50 AM
> > To: dev@dpdk.org
> > Cc: Cao, Waterman; Liang, Cunming; Liu, Jijiang; Ananyev, Konstantin;
> Richardson, Bruce; yongwang@vmware.com;
> > olivier.matz@6wind.com; Wu, Jingjing; Zhang, Helin
> > Subject: [PATCH v8 00/18] unified packet type
> >
> > Currently only 6 bits which are stored in ol_flags are used to indicate
> the
> > packet types. This is not enough, as some NIC hardware can recognize
> quite
> > a lot of packet types, e.g i40e hardware can recognize more than 150
> packet
> > types. Hiding those packet types hides hardware offload capabilities
> which
> > could be quite useful for improving performance and for end users.
> > So an unified packet types are needed to support all possible PMDs. A 16
> > bits packet_type in mbuf structure can be changed to 32 bits and used
> for
> > this purpose. In addition, all packet types stored in ol_flag field
> should
> > be deleted at all, and 6 bits of ol_flags can be save as the benifit.
> >
> > Initially, 32 bits of packet_type can be divided into several sub fields
> to
> > indicate different packet type information of a packet. The initial
> design
> > is to divide those bits into fields for L2 types, L3 types, L4 types,
> tunnel
> > types, inner L2 types, inner L3 types and inner L4 types. All PMDs
> should
> > translate the offloaded packet types into these 7 fields of information,
> for
> > user applications.
> >
> > To avoid breaking ABI compatibility, currently all the code changes for
> > unified packet type are disabled at compile time by default. Users can
> enable
> > it manually by defining the macro of RTE_NEXT_ABI. The code changes will
> be
> > valid by default in a future release, and the old version will be
> deleted
> > accordingly, after the ABI change process is done.
> >
> > Note that this patch set should be integrated after another patch set
> for
> > '[PATCH v3 0/7] support i40e QinQ stripping and insertion', to clearly
> solve
> > the conflict during integration. As both patch sets modified 'struct
> rte_mbuf',
> > and the final layout of the 'struct rte_mbuf' is key to vectorized ixgbe
> PMD.
> >
> > v2 changes:
> > * Enlarged the packet_type field from 16 bits to 32 bits.
> > * Redefined the packet type sub-fields.
> > * Updated the 'struct rte_kni_mbuf' for KNI according to the mbuf
> changes.
> > * Used redefined packet types and enlarged packet_type field for all
> PMDs
> > and corresponding applications.
> > * Removed changes in bond and its relevant application, as there is no
> need
> > at all according to the recent bond changes.
> >
> > v3 changes:
> > * Put the mbuf layout changes into a single patch.
> > * Put vector ixgbe changes right after mbuf changes.
> > * Disabled vector ixgbe PMD by default, as mbuf layout changed, and then
> > re-enabled it after vector ixgbe PMD updated.
> > * Put the definitions of unified packet type into a single patch.
> > * Minor bug fixes and enhancements in l3fwd example.
> >
> > v4 changes:
> > * Added detailed description of each packet types.
> > * Supported unified packet type of fm10k.
> > * Added printing logs of packet types of each received packet for rxonly
> > mode in testpmd.
> > * Removed several useless code lines which block packet type unification
> from
> > app/test/packet_burst_generator.c.
> >
> > v5 changes:
> > * Added more detailed description for each packet types, together with
> examples.
> > * Rolled back the macro definitions of RX packet flags, for ABI
> compitability.
> >
> > v6 changes:
> > * Disabled the code changes for unified packet type by default, to
> > avoid breaking ABI compatibility.
> >
> > v7 changes:
> > * Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
> > * Integrated with patch set for '[PATCH v3 0/7] support i40e QinQ
> stripping
> > and insertion', to clearly solve the conflicts during merging.
> >
> > v8 changes:
> > * Moved the field of 'vlan_tci_outer' in 'struct rte_mbuf' to the end of
> the 1st
> > cache line, to avoid breaking any vectorized PMD storing, as fields of
> > 'packet_type, pkt_len, data_len, vlan_tci, rss' should be in an
> contiguous 128
> > bits.
> >
> > Helin Zhang (18):
> > mbuf: redefine packet_type in rte_mbuf
> > ixgbe: support unified packet type in vectorized PMD
> > mbuf: add definitions of unified packet types
> > e1000: replace bit mask based packet type with unified packet type
> > ixgbe: replace bit mask based packet type with unified packet type
> > i40e: replace bit mask based packet type with unified packet type
> > enic: replace bit mask based packet type with unified packet type
> > vmxnet3: replace bit mask based packet type with unified packet type
> > fm10k: replace bit mask based packet type with unified packet type
> > app/test-pipeline: replace bit mask based packet type with unified
> > packet type
> > app/testpmd: replace bit mask based packet type with unified packet
> > type
> > app/test: Remove useless code
> > examples/ip_fragmentation: replace bit mask based packet type with
> > unified packet type
> > examples/ip_reassembly: replace bit mask based packet type with
> > unified packet type
> > examples/l3fwd-acl: replace bit mask based packet type with unified
> > packet type
> > examples/l3fwd-power: replace bit mask based packet type with unified
> > packet type
> > examples/l3fwd: replace bit mask based packet type with unified packet
> > type
> > mbuf: remove old packet type bit masks
> >
> > app/test-pipeline/pipeline_hash.c | 13 +
> > app/test-pmd/csumonly.c | 14 +
> > app/test-pmd/rxonly.c | 183 +++++++
> > app/test/packet_burst_generator.c | 6 +-
> > drivers/net/e1000/igb_rxtx.c | 102 ++++
> > drivers/net/enic/enic_main.c | 26 +
> > drivers/net/fm10k/fm10k_rxtx.c | 27 ++
> > drivers/net/i40e/i40e_rxtx.c | 528
> +++++++++++++++++++++
> > drivers/net/ixgbe/ixgbe_rxtx.c | 163 +++++++
> > drivers/net/ixgbe/ixgbe_rxtx_vec.c | 75 ++-
> > drivers/net/vmxnet3/vmxnet3_rxtx.c | 8 +
> > examples/ip_fragmentation/main.c | 9 +
> > examples/ip_reassembly/main.c | 9 +
> > examples/l3fwd-acl/main.c | 29 +-
> > examples/l3fwd-power/main.c | 8 +
> > examples/l3fwd/main.c | 123 ++++-
> > .../linuxapp/eal/include/exec-env/rte_kni_common.h | 6 +
> > lib/librte_mbuf/rte_mbuf.c | 4 +
> > lib/librte_mbuf/rte_mbuf.h | 517
> ++++++++++++++++++++
> > 19 files changed, 1837 insertions(+), 13 deletions(-)
> >
> > --
>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
>
> > 1.9.3
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types
2015-07-02 1:30 0% ` Zhang, Helin
@ 2015-07-02 9:31 0% ` Olivier MATZ
2015-07-03 1:30 0% ` Zhang, Helin
0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2015-07-02 9:31 UTC (permalink / raw)
To: Zhang, Helin, dev
Hi Helin,
On 07/02/2015 03:30 AM, Zhang, Helin wrote:
> Hi Oliver
>
> Thanks for your helps!
>
>> -----Original Message-----
>> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
>> Sent: Tuesday, June 30, 2015 4:44 PM
>> To: Zhang, Helin; dev@dpdk.org
>> Cc: Cao, Waterman; Liang, Cunming; Liu, Jijiang; Ananyev, Konstantin; Richardson,
>> Bruce; yongwang@vmware.com; Wu, Jingjing
>> Subject: Re: [PATCH v8 03/18] mbuf: add definitions of unified packet types
>>
>> Hi Helin,
>>
>> This is greatly documented, thanks!
>> Please find a small comment below.
>>
>> On 06/23/2015 03:50 AM, Helin Zhang wrote:
>>> As there are only 6 bit flags in ol_flags for indicating packet types,
>>> which is not enough to describe all the possible packet types hardware
>>> can recognize. For example, i40e hardware can recognize more than 150
>>> packet types. Unified packet type is composed of L2 type, L3 type, L4
>>> type, tunnel type, inner L2 type, inner L3 type and inner L4 type
>>> fields, and can be stored in 'struct rte_mbuf' of 32 bits field
>>> 'packet_type'.
>>> To avoid breaking ABI compatibility, all the changes would be enabled
>>> by RTE_NEXT_ABI, which is disabled by default.
>>>
>>> [...]
>>> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
>>> index 0315561..0ee0c55 100644
>>> --- a/lib/librte_mbuf/rte_mbuf.h
>>> +++ b/lib/librte_mbuf/rte_mbuf.h
>>> @@ -201,6 +201,493 @@ extern "C" {
>>> /* 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.
>>> + * - Bit 3:0 is for L2 types.
>>> + * - Bit 7:4 is for L3 or outer L3 (for tunneling case) types.
>>> + * - Bit 11:8 is for L4 or outer L4 (for tunneling case) types.
>>> + * - Bit 15:12 is for tunnel types.
>>> + * - Bit 19:16 is for inner L2 types.
>>> + * - Bit 23:20 is for inner L3 types.
>>> + * - Bit 27:24 is for inner L4 types.
>>> + * - Bit 31:28 is reserved.
>>> + *
>>> + * To be compatible with Vector PMD, RTE_PTYPE_L3_IPV4,
>>> +RTE_PTYPE_L3_IPV4_EXT,
>>> + * RTE_PTYPE_L3_IPV6, RTE_PTYPE_L3_IPV6_EXT, RTE_PTYPE_L4_TCP,
>>> +RTE_PTYPE_L4_UDP
>>> + * and RTE_PTYPE_L4_SCTP should be kept as below in a contiguous 7 bits.
>>> + *
>>> + * Note that L3 types values are selected for checking IPV4/IPV6
>>> +header from
>>> + * performance point of view. Reading annotations of
>>> +RTE_ETH_IS_IPV4_HDR and
>>> + * RTE_ETH_IS_IPV6_HDR is needed for any future changes of L3 type values.
>>> + *
>>> + * Note that the packet types of the same packet recognized by
>>> +different
>>> + * hardware may be different, as different hardware may have
>>> +different
>>> + * capability of packet type recognition.
>>> + *
>>> + * examples:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=0x29
>>> + * | 'version'=6, 'next header'=0x3A
>>> + * | 'ICMPv6 header'>
>>> + * will be recognized on i40e hardware as packet type combination of,
>>> + * RTE_PTYPE_L2_MAC |
>>> + * RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
>>> + * RTE_PTYPE_TUNNEL_IP |
>>> + * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
>>> + * RTE_PTYPE_INNER_L4_ICMP.
>>> + *
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=0x2F
>>> + * | 'GRE header'
>>> + * | 'version'=6, 'next header'=0x11
>>> + * | 'UDP header'>
>>> + * will be recognized on i40e hardware as packet type combination of,
>>> + * RTE_PTYPE_L2_MAC |
>>> + * RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
>>> + * RTE_PTYPE_TUNNEL_GRENAT |
>>> + * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
>>> + * RTE_PTYPE_INNER_L4_UDP.
>>> + */
>>> +#define RTE_PTYPE_UNKNOWN 0x00000000
>>> +/**
>>> + * MAC (Media Access Control) packet type.
>>> + * It is used for outer packet for tunneling cases.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=[0x0800|0x86DD|others]> */
>>> +#define RTE_PTYPE_L2_MAC 0x00000001
>>
>> I'm wondering if RTE_PTYPE_L2_ETHER is not a better name?
> Ethernet includes both Data Link Layer and Physical Layer, while MAC is for Data Link
> Layer only. I would prefer to keep 'MAC' in the names, rather than 'ether'.
> Any opinions from others?
Just to precise what I'm saying: MAC is the interface between
the logical link and the physical layer. It is different
depending on the physical media (Ethernet, Token Ring, WLAN, ...).
Every packet has a MAC layer and I think "MAC" does not bring
any information.
Having "ETHER" in the name would inform the software that
it can expect an ethernet header. In the future, I would expect
to have more L2 types like PPP.
I also have another question about RTE_PTYPE_L2_MAC. You
describe it as "<'ether type'=[0x0800|0x86DD|others]>".
What is the meaning of "others"? Does it mean that it is
valid to set RTE_PTYPE_L2_MAC for any received packet?
For instance, an ARP packet. The driver has the choice
to set:
A- RTE_PTYPE_UNKNOWN: the driver does not know the L2 packet
type
B- RTE_PTYPE_L2_MAC: the driver knows it's an ethernet packet
(it should be the case for all received packets today as
dpdk only supports ethernet ports)
C- RTE_PTYPE_L2_ARP: the driver knows that the packet carries
an ARP header after the ethernet header.
Is it correct for a driver to always set B- for all received
packets?
Another thing that bothers me a bit is that L2_ARP, L2_LLDP,
L2_MAC_TIMESYNC, (...) are not really L2 types. The L2 type is
Ethernet. On the other hand, they are not L3 type either.
So, I have no other solution. The OSI model is probably a
bit too theorical, and we have to choose the solution that
is the most useful for the applications, even if it does not
absolutely matches the theory ;)
Regards,
Olivier
>
> Regards,
> Helin
>
>>
>>
>>> +/**
>>> + * MAC (Media Access Control) packet type for time sync.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x88F7>
>>> + */
>>> +#define RTE_PTYPE_L2_MAC_TIMESYNC 0x00000002
>>> +/**
>>> + * ARP (Address Resolution Protocol) packet type.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0806>
>>> + */
>>> +#define RTE_PTYPE_L2_ARP 0x00000003
>>> +/**
>>> + * LLDP (Link Layer Discovery Protocol) packet type.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x88CC>
>>> + */
>>> +#define RTE_PTYPE_L2_LLDP 0x00000004
>>
>> Maybe ETHER should appear in these names too, what do you think?
> Same as above.
>
>>
>>
>>
>>
>>> +/**
>>> + * Mask of layer 2 packet types.
>>> + * It is used for outer packet for tunneling cases.
>>> + */
>>> +#define RTE_PTYPE_L2_MASK 0x0000000f
>>> +/**
>>> + * IP (Internet Protocol) version 4 packet type.
>>> + * It is used for outer packet for tunneling cases, and does not
>>> +contain any
>>> + * header option.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'ihl'=5>
>>> + */
>>> +#define RTE_PTYPE_L3_IPV4 0x00000010
>>> +/**
>>> + * IP (Internet Protocol) version 4 packet type.
>>> + * It is used for outer packet for tunneling cases, and contains
>>> +header
>>> + * options.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'ihl'=[6-15], 'options'> */
>>> +#define RTE_PTYPE_L3_IPV4_EXT 0x00000030
>>> +/**
>>> + * IP (Internet Protocol) version 6 packet type.
>>> + * It is used for outer packet for tunneling cases, and does not
>>> +contain any
>>> + * extension header.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=0x3B> */
>>> +#define RTE_PTYPE_L3_IPV6 0x00000040
>>> +/**
>>> + * IP (Internet Protocol) version 4 packet type.
>>> + * It is used for outer packet for tunneling cases, and may or maynot
>>> +contain
>>> + * header options.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'ihl'=[5-15], <'options'>> */
>>> +#define RTE_PTYPE_L3_IPV4_EXT_UNKNOWN 0x00000090
>>> +/**
>>> + * IP (Internet Protocol) version 6 packet type.
>>> + * It is used for outer packet for tunneling cases, and contains
>>> +extension
>>> + * headers.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
>>> + * 'extension headers'>
>>> + */
>>> +#define RTE_PTYPE_L3_IPV6_EXT 0x000000c0
>>> +/**
>>> + * IP (Internet Protocol) version 6 packet type.
>>> + * It is used for outer packet for tunneling cases, and may or maynot
>>> +contain
>>> + * extension headers.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
>>> + * <'extension headers'>>
>>> + */
>>> +#define RTE_PTYPE_L3_IPV6_EXT_UNKNOWN 0x000000e0
>>> +/**
>>> + * Mask of layer 3 packet types.
>>> + * It is used for outer packet for tunneling cases.
>>> + */
>>> +#define RTE_PTYPE_L3_MASK 0x000000f0
>>> +/**
>>> + * TCP (Transmission Control Protocol) packet type.
>>> + * It is used for outer packet for tunneling cases.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=6, 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=6>
>>> + */
>>> +#define RTE_PTYPE_L4_TCP 0x00000100
>>> +/**
>>> + * UDP (User Datagram Protocol) packet type.
>>> + * It is used for outer packet for tunneling cases.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=17, 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=17>
>>> + */
>>> +#define RTE_PTYPE_L4_UDP 0x00000200
>>> +/**
>>> + * Fragmented IP (Internet Protocol) packet type.
>>> + * It is used for outer packet for tunneling cases.
>>> + *
>>> + * It refers to those packets of any IP types, which can be
>>> +recognized as
>>> + * fragmented. A fragmented packet cannot be recognized as any other
>>> +L4 types
>>> + * (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP, RTE_PTYPE_L4_SCTP,
>>> +RTE_PTYPE_L4_ICMP,
>>> + * RTE_PTYPE_L4_NONFRAG).
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'MF'=1>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=44>
>>> + */
>>> +#define RTE_PTYPE_L4_FRAG 0x00000300
>>> +/**
>>> + * SCTP (Stream Control Transmission Protocol) packet type.
>>> + * It is used for outer packet for tunneling cases.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=132, 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=132>
>>> + */
>>> +#define RTE_PTYPE_L4_SCTP 0x00000400
>>> +/**
>>> + * ICMP (Internet Control Message Protocol) packet type.
>>> + * It is used for outer packet for tunneling cases.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=1, 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=1>
>>> + */
>>> +#define RTE_PTYPE_L4_ICMP 0x00000500
>>> +/**
>>> + * Non-fragmented IP (Internet Protocol) packet type.
>>> + * It is used for outer packet for tunneling cases.
>>> + *
>>> + * It refers to those packets of any IP types, while cannot be
>>> +recognized as
>>> + * any of above L4 types (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP,
>>> + * RTE_PTYPE_L4_FRAG, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP).
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'!=[6|17|44|132|1]> */
>>> +#define RTE_PTYPE_L4_NONFRAG 0x00000600
>>> +/**
>>> + * Mask of layer 4 packet types.
>>> + * It is used for outer packet for tunneling cases.
>>> + */
>>> +#define RTE_PTYPE_L4_MASK 0x00000f00
>>> +/**
>>> + * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=[4|41]>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=[4|41]> */
>>> +#define RTE_PTYPE_TUNNEL_IP 0x00001000
>>> +/**
>>> + * GRE (Generic Routing Encapsulation) tunneling packet type.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=47>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=47>
>>> + */
>>> +#define RTE_PTYPE_TUNNEL_GRE 0x00002000
>>> +/**
>>> + * VXLAN (Virtual eXtensible Local Area Network) tunneling packet type.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=17
>>> + * | 'destination port'=4798>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=17
>>> + * | 'destination port'=4798>
>>> + */
>>> +#define RTE_PTYPE_TUNNEL_VXLAN 0x00003000
>>> +/**
>>> + * NVGRE (Network Virtualization using Generic Routing Encapsulation)
>>> +tunneling
>>> + * packet type.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=47
>>> + * | 'protocol type'=0x6558>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=47
>>> + * | 'protocol type'=0x6558'>
>>> + */
>>> +#define RTE_PTYPE_TUNNEL_NVGRE 0x00004000
>>> +/**
>>> + * GENEVE (Generic Network Virtualization Encapsulation) tunneling packet
>> type.
>>> + *
>>> + * Packet format:
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=17
>>> + * | 'destination port'=6081>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=17
>>> + * | 'destination port'=6081>
>>> + */
>>> +#define RTE_PTYPE_TUNNEL_GENEVE 0x00005000
>>> +/**
>>> + * Tunneling packet type of Teredo, VXLAN (Virtual eXtensible Local
>>> +Area
>>> + * Network) or GRE (Generic Routing Encapsulation) could be
>>> +recognized as this
>>> + * packet type, if they can not be recognized independently as of
>>> +hardware
>>> + * capability.
>>> + */
>>> +#define RTE_PTYPE_TUNNEL_GRENAT 0x00006000
>>> +/**
>>> + * Mask of tunneling packet types.
>>> + */
>>> +#define RTE_PTYPE_TUNNEL_MASK 0x0000f000
>>> +/**
>>> + * MAC (Media Access Control) packet type.
>>> + * It is used for inner packet type only.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=[0x800|0x86DD]>
>>> + */
>>> +#define RTE_PTYPE_INNER_L2_MAC 0x00010000
>>> +/**
>>> + * MAC (Media Access Control) packet type with VLAN (Virtual Local
>>> +Area
>>> + * Network) tag.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=[0x800|0x86DD], vlan=[1-4095]> */
>>> +#define RTE_PTYPE_INNER_L2_MAC_VLAN 0x00020000
>>> +/**
>>> + * Mask of inner layer 2 packet types.
>>> + */
>>> +#define RTE_PTYPE_INNER_L2_MASK 0x000f0000
>>> +/**
>>> + * IP (Internet Protocol) version 4 packet type.
>>> + * It is used for inner packet only, and does not contain any header option.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'ihl'=5>
>>> + */
>>> +#define RTE_PTYPE_INNER_L3_IPV4 0x00100000
>>> +/**
>>> + * IP (Internet Protocol) version 4 packet type.
>>> + * It is used for inner packet only, and contains header options.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'ihl'=[6-15], 'options'> */
>>> +#define RTE_PTYPE_INNER_L3_IPV4_EXT 0x00200000
>>> +/**
>>> + * IP (Internet Protocol) version 6 packet type.
>>> + * It is used for inner packet only, and does not contain any extension header.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=0x3B> */
>>> +#define RTE_PTYPE_INNER_L3_IPV6 0x00300000
>>> +/**
>>> + * IP (Internet Protocol) version 4 packet type.
>>> + * It is used for inner packet only, and may or maynot contain header options.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'ihl'=[5-15], <'options'>> */ #define
>>> +RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN 0x00400000
>>> +/**
>>> + * IP (Internet Protocol) version 6 packet type.
>>> + * It is used for inner packet only, and contains extension headers.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
>>> + * 'extension headers'>
>>> + */
>>> +#define RTE_PTYPE_INNER_L3_IPV6_EXT 0x00500000
>>> +/**
>>> + * IP (Internet Protocol) version 6 packet type.
>>> + * It is used for inner packet only, and may or maynot contain
>>> +extension
>>> + * headers.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
>>> + * <'extension headers'>>
>>> + */
>>> +#define RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN 0x00600000
>>> +/**
>>> + * Mask of inner layer 3 packet types.
>>> + */
>>> +#define RTE_PTYPE_INNER_INNER_L3_MASK 0x00f00000
>>> +/**
>>> + * TCP (Transmission Control Protocol) packet type.
>>> + * It is used for inner packet only.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=6, 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=6>
>>> + */
>>> +#define RTE_PTYPE_INNER_L4_TCP 0x01000000
>>> +/**
>>> + * UDP (User Datagram Protocol) packet type.
>>> + * It is used for inner packet only.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=17, 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=17>
>>> + */
>>> +#define RTE_PTYPE_INNER_L4_UDP 0x02000000
>>> +/**
>>> + * Fragmented IP (Internet Protocol) packet type.
>>> + * It is used for inner packet only, and may or maynot have layer 4 packet.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'MF'=1>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=44>
>>> + */
>>> +#define RTE_PTYPE_INNER_L4_FRAG 0x03000000
>>> +/**
>>> + * SCTP (Stream Control Transmission Protocol) packet type.
>>> + * It is used for inner packet only.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=132, 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=132>
>>> + */
>>> +#define RTE_PTYPE_INNER_L4_SCTP 0x04000000
>>> +/**
>>> + * ICMP (Internet Control Message Protocol) packet type.
>>> + * It is used for inner packet only.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'=1, 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'=1>
>>> + */
>>> +#define RTE_PTYPE_INNER_L4_ICMP 0x05000000
>>> +/**
>>> + * Non-fragmented IP (Internet Protocol) packet type.
>>> + * It is used for inner packet only, and may or maynot have other
>>> +unknown layer
>>> + * 4 packet types.
>>> + *
>>> + * Packet format (inner only):
>>> + * <'ether type'=0x0800
>>> + * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
>>> + * or,
>>> + * <'ether type'=0x86DD
>>> + * | 'version'=6, 'next header'!=[6|17|44|132|1]> */
>>> +#define RTE_PTYPE_INNER_L4_NONFRAG 0x06000000
>>> +/**
>>> + * Mask of inner layer 4 packet types.
>>> + */
>>> +#define RTE_PTYPE_INNER_L4_MASK 0x0f000000
>>> +
>>> +/**
>>> + * 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.
>>> + */
>>> +#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.
>>> + */
>>> +#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 */
>>> +
>>> /**
>>> * Get the name of a RX offload flag
>>> *
>>>
>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] doc: fix minor sphinx build warning
@ 2015-07-02 11:52 9% John McNamara
2015-07-02 12:18 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: John McNamara @ 2015-07-02 11:52 UTC (permalink / raw)
To: dev
Fix for a minor Sphinx build warning in the ABI guidelines docs:
versioning.rst:126: WARNING: Bullet list ends without a
blank line; unexpected unindent.
Also added a RST label to the start of the doc to allow it
to be linked to from other docs.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/guidelines/versioning.rst | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
index a1c9368..57db6fd 100644
--- a/doc/guides/guidelines/versioning.rst
+++ b/doc/guides/guidelines/versioning.rst
@@ -1,3 +1,5 @@
+.. abi_guidelines:
+
Managing ABI updates
====================
@@ -122,9 +124,9 @@ The macros exported are:
the linker to bind references to symbol ``b`` to the internal symbol
``b_e``.
-* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the fully
-qualified function ``p``, so that if a symbol becomes versioned, it can still be
-mapped back to the public symbol name.
+* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
+ fully qualified function ``p``, so that if a symbol becomes versioned, it
+ can still be mapped back to the public symbol name.
Examples of ABI Macro use
-------------------------
--
1.8.1.4
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH] doc: fix minor sphinx build warning
2015-07-02 11:52 9% [dpdk-dev] [PATCH] doc: fix minor sphinx build warning John McNamara
@ 2015-07-02 12:18 3% ` Thomas Monjalon
2015-07-02 13:28 0% ` Mcnamara, John
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-07-02 12:18 UTC (permalink / raw)
To: John McNamara; +Cc: dev
2015-07-02 12:52, John McNamara:
> Also added a RST label to the start of the doc to allow it
> to be linked to from other docs.
We don't really need to have a label at the top of the doc.
It can be linked with :doc: role:
dpdk.org/browse/dpdk/commit/?id=7cc2bdedd3812998078
But it could be useful in case new versioning chapters are added before
ABI guidelines.
In this case, the link referenced in the commit above should be updated.
> --- a/doc/guides/guidelines/versioning.rst
> +++ b/doc/guides/guidelines/versioning.rst
> @@ -1,3 +1,5 @@
> +.. abi_guidelines:
> +
> Managing ABI updates
> ====================
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v4 3/4] bond mode 4: allow external state machine
@ 2015-07-02 13:30 4% ` Declan Doherty
0 siblings, 0 replies; 200+ results
From: Declan Doherty @ 2015-07-02 13:30 UTC (permalink / raw)
To: Eric Kinzie, dev; +Cc: Eric Kinzie
On 26/05/15 16:41, Eric Kinzie wrote:
> From: Eric Kinzie <ekinzie@brocade.com>
>
> Provide functions to allow an external 802.3ad state machine to transmit
> and recieve LACPDUs and to set the collection/distribution flags on
> slave interfaces.
>
> Size of struct rte_eth_bond_8023ad_conf changed. Increment LIBABIVER
> and version bond_mode_8023ad_setup and bond_mode_8023ad_conf_get
> functions.
>
> Signed-off-by: Eric Kinzie <ehkinzie@gmail.com>
> ---
....
>
Hey Eric, sorry for talking so long to get back with these comments.
I had some issues with the ABI versioning and the static linking with
the test app, also the ABI versioning wasn't implemented as specified in
the latest guidelines document, I had to make the following changes to
get things to link correctly for me. Also in
rte_eth_bond_8023ad_ext_slowtx it's probably worth while checking the
ethertype in the eth header.
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c
b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 06534ae..a9e6a50 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -1001,7 +1001,7 @@ bond_mode_8023ad_mac_address_update(struct
rte_eth_dev *bond_dev)
bond_mode_8023ad_start(bond_dev);
}
-void __vsym
+void
bond_mode_8023ad_conf_get_v20(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf)
{
@@ -1020,9 +1020,8 @@ bond_mode_8023ad_conf_get_v20(struct rte_eth_dev *dev,
conf->slowrx_cb = mode4->slowrx_cb;
}
-VERSION_SYMBOL(bond_mode_8023ad_conf_get, _v20, 2.0);
-void __vsym
+void
bond_mode_8023ad_conf_get_v21(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf)
{
@@ -1041,9 +1040,10 @@ bond_mode_8023ad_conf_get_v21(struct rte_eth_dev
*dev,
conf->slowrx_cb = mode4->slowrx_cb;
}
-BIND_DEFAULT_SYMBOL(bond_mode_8023ad_conf_get, _v21, 2.1);
+MAP_STATIC_SYMBOL(void bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_bond_8023ad_conf *conf), bond_mode_8023ad_conf_get_v21);
-void __vsym
+void
bond_mode_8023ad_setup_v20(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf)
{
@@ -1074,9 +1074,8 @@ bond_mode_8023ad_setup_v20(struct rte_eth_dev *dev,
mode4->update_timeout_us = conf->update_timeout_ms * 1000;
}
-VERSION_SYMBOL(bond_mode_8023ad_setup, _v20, 2.0);
-void __vsym
+void
bond_mode_8023ad_setup_v21(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf)
{
@@ -1114,8 +1113,9 @@ bond_mode_8023ad_setup_v21(struct rte_eth_dev *dev,
bond_mode_8023ad_start(dev);
}
-BIND_DEFAULT_SYMBOL(bond_mode_8023ad_setup, _v21, 2.1);
-
+MAP_STATIC_SYMBOL(void bond_mode_8023ad_setup(struct rte_eth_dev *dev,
+ struct rte_eth_bond_8023ad_conf *conf),
+ bond_mode_8023ad_setup_v21);
int
bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
{
@@ -1407,7 +1407,8 @@ rte_eth_bond_8023ad_ext_slowtx(uint8_t port_id,
uint8_t slave_id,
/* only enqueue LACPDUs */
lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
- if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
+ if (lacp-> eth_hdr. ether_type != rte_cpu_to_be(ETHER_TYPE_SLOW) ||
+ lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
return -EINVAL;
MODE4_DEBUG("sending LACP frame\n");
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad_private.h
b/drivers/net/bonding/rte_eth_bond_8023ad_private.h
index cb39004..d1a1af0 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad_private.h
+++ b/drivers/net/bonding/rte_eth_bond_8023ad_private.h
@@ -191,7 +191,7 @@ struct bond_dev_private;
/**
* @internal
*
- * Get configuration of bonded interface.
+ * Retreive mode 4 configuration of bonded interface.
*
*
* @param dev Bonded interface
@@ -201,6 +201,18 @@ void
bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf);
+void
+bond_mode_8023ad_conf_get_v20(struct rte_eth_dev *dev,
+ struct rte_eth_bond_8023ad_conf *conf);
+
+VERSION_SYMBOL(bond_mode_8023ad_conf_get, _v20, 2.0);
+
+void
+bond_mode_8023ad_conf_get_v21(struct rte_eth_dev *dev,
+ struct rte_eth_bond_8023ad_conf *conf);
+
+BIND_DEFAULT_SYMBOL(bond_mode_8023ad_conf_get, _v21, 2.1);
+
/**
* @internal
*
@@ -214,31 +226,19 @@ bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
void
bond_mode_8023ad_setup(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf);
-void __vsym
+void
bond_mode_8023ad_setup_v20(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf);
-void __vsym
-bond_mode_8023ad_setup_v21(struct rte_eth_dev *dev,
- struct rte_eth_bond_8023ad_conf *conf);
-/**
- * @internal
- *
- * Retreive mode 4 configuration of bonded interface.
- *
- * @param dev Bonded interface
- * @param conf Bonded interface configuration
- */
+VERSION_SYMBOL(bond_mode_8023ad_setup, _v20, 2.0);
+
void
-bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
- struct rte_eth_bond_8023ad_conf *conf);
-void __vsym
-bond_mode_8023ad_conf_get_v20(struct rte_eth_dev *dev,
- struct rte_eth_bond_8023ad_conf *conf);
-void __vsym
-bond_mode_8023ad_conf_get_v21(struct rte_eth_dev *dev,
+bond_mode_8023ad_setup_v21(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf);
+BIND_DEFAULT_SYMBOL(bond_mode_8023ad_setup, _v21, 2.1);
+
+
/**
* @internal
diff --git a/drivers/net/bonding/rte_eth_bond_version.map
b/drivers/net/bonding/rte_eth_bond_version.map
index 328a423..0e144e3 100644
--- a/drivers/net/bonding/rte_eth_bond_version.map
+++ b/drivers/net/bonding/rte_eth_bond_version.map
@@ -2,6 +2,9 @@ DPDK_2.0 {
global:
rte_eth_bond_8023ad_conf_get;
+ rte_eth_bond_8023ad_ext_collect;
+ rte_eth_bond_8023ad_ext_distrib;
+ rte_eth_bond_8023ad_ext_slowtx;
rte_eth_bond_8023ad_setup;
rte_eth_bond_active_slaves_get;
rte_eth_bond_create;
@@ -17,9 +20,6 @@ DPDK_2.0 {
rte_eth_bond_slaves_get;
rte_eth_bond_xmit_policy_get;
rte_eth_bond_xmit_policy_set;
- rte_eth_bond_8023ad_ext_collect;
- rte_eth_bond_8023ad_ext_distrib;
- rte_eth_bond_8023ad_ext_slowtx;
local: *;
};
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] doc: fix minor sphinx build warning
2015-07-02 12:18 3% ` Thomas Monjalon
@ 2015-07-02 13:28 0% ` Mcnamara, John
0 siblings, 0 replies; 200+ results
From: Mcnamara, John @ 2015-07-02 13:28 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Thursday, July 2, 2015 1:18 PM
> To: Mcnamara, John
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] doc: fix minor sphinx build warning
>
> But it could be useful in case new versioning chapters are added before
> ABI guidelines.
> In this case, the link referenced in the commit above should be updated.
Hi Thomas,
I'll just resubmit without the label part of the patch and submit a patch for the label at a later stage, if required.
John
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH 2/3] doc: added guidelines on dpdk documentation
@ 2015-07-02 13:50 3% ` John McNamara
2015-07-02 16:20 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: John McNamara @ 2015-07-02 13:50 UTC (permalink / raw)
To: dev
Added guidelines on the purpose and structure of the DPDK
documentation, how to build it and guidelines for creating it.
Also added guidelines on how to format and submit a documentation patch.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/guidelines/documentation.rst | 1005 +++++++++++++++++++++++++++++++
doc/guides/guidelines/index.rst | 2 +
2 files changed, 1007 insertions(+)
create mode 100644 doc/guides/guidelines/documentation.rst
diff --git a/doc/guides/guidelines/documentation.rst b/doc/guides/guidelines/documentation.rst
new file mode 100644
index 0000000..d3e5905
--- /dev/null
+++ b/doc/guides/guidelines/documentation.rst
@@ -0,0 +1,1005 @@
+g.. doc_guidelines:
+
+DPDK Documentation Guidelines
+=============================
+
+This document outlines the guidelines for writing the DPDK Guides and API
+documentation in RST and Doxygen format.
+
+It also explains the structure of the DPDK documentation and shows how to
+build the Html and PDF versions of the documents.
+
+It also explains how to submit a patch to the documentation.
+
+
+Structure of the Documentation
+------------------------------
+
+The DPDK source code repository contains input files to build the API
+documentation and User Guides.
+
+The main directories that contain files related to documentation are shown
+below::
+
+ lib
+ |-- librte_acl
+ |-- librte_cfgfile
+ |-- librte_cmdline
+ |-- librte_compat
+ |-- librte_eal
+ | |-- ...
+ ...
+ doc
+ |-- api
+ +-- guides
+ |-- freebsd_gsg
+ |-- linux_gsg
+ |-- prog_guide
+ |-- sample_app_ug
+ |-- guidelines
+ |-- testpmd_app_ug
+ |-- rel_notes
+ |-- nics
+ |-- xen
+ |-- ...
+
+
+The API documentation is built from `Doxygen
+<http://www.stack.nl/~dimitri/doxygen/>`_ comments in the header files. These
+files are mainly in the ``lib/lib_rte_*`` directories although some of the
+Poll Mode Drivers in ``drivers/net`` are also documented with Doxygen.
+
+The configuration files that are used to control the Doxygen output are in the
+``doc/api`` directory.
+
+The user guides such as *The Programmers Guide* and the *FreeBSD* and *Linux
+Getting Started* Guides are generated from RST markup text files using the
+`Sphinx <http://sphinx-doc.org/index.html>`_ Documentation Generator.
+
+These files are included in the ``doc/guides/`` directory. The output is
+controlled by the ``doc/guides/conf.py`` file.
+
+
+Role of the Documentation
+-------------------------
+
+The following items outline the roles of the different parts of the
+documentation and when they need to be updated or added to by the developer.
+
+* **Release Notes**
+
+ The Release Notes document which features have been added in the current and
+ previous releases of DPDK and highlight any known issues. The Releases Notes
+ also contain notifications of features that will change ABI compatibility in
+ the next major release.
+
+ In general developers do not have to update the Release Notes apart from
+ adding ABI announcements.
+
+* **API documentation**
+
+ The API documentation explains how to use the public DPDK functions. The
+ `API index page <http://dpdk.org/doc/api/>`_ shows the generated API
+ documentation as related groups of functions.
+
+ The API documentation should be updated via Doxygen comments when new
+ functions are added.
+
+* **Getting Started Guides**
+
+ The Getting Started Guides show how to install and configure DPDK and
+ how to run DPDK based applications on different OSes.
+
+ A Getting Started Guide should be added when DPDK is ported to a new OS. The
+ guide for the Skeleton Forwarding app is a good starting reference.
+
+* **The Programmers Guide**
+
+ The Programmers Guide explains how the API components of DPDK such as
+ the EAL, Memzone, Rings and the Hash Library work. It also explains how some
+ higher level functionality such as Packet Distributor, Packet Framework and
+ KNI work. It also shows the build system and explains how to add
+ applications.
+
+ The Programmers Guide should be expanded when new functionality is added to
+ DPDK.
+
+* **App Guides**
+
+ The app guides document the DPDK applications in the ``app`` directory such
+ as ``testpmd``.
+
+ The app guides should be updated if functionality is changed or added.
+
+* **Sample App Guides**
+
+ The sample app guides document the DPDK example applications in the examples
+ directory. Generally they demonstrate a major feature such as L2 or L3
+ Forwarding, Multi Process or Power Management. They explain the purpose of
+ the sample application, how to run it and step through some of the code to
+ explain the major functionality.
+
+ A new sample application should be accompanied by new sample app guide.
+
+* **Network Interface Controller Drivers**
+
+ The NIC Drivers document explains the features of the individual Poll Mode
+ Drivers, such as software requirements, configuration and initialization.
+
+ New documentation should be added for new Poll Mode Drivers.
+
+* **Guidelines**
+
+ The guideline documents record the DPDK guidelines on coding, design, ABI
+ usage and documentation.
+
+ These should be changed to clarify or improve guidelines.
+
+
+Building the Documentation
+--------------------------
+
+Dependencies
+~~~~~~~~~~~~
+
+
+The following dependencies must be installed to build the documentation:
+
+* Doxygen.
+
+* Sphinx.
+
+* TexLive.
+
+* Inkscape.
+
+`Doxygen`_ generates documentation from commented source code. It can be
+installed as follows:
+
+.. code-block:: console
+
+ # Ubuntu/Debian.
+ sudo apt-get -y install doxygen
+
+ # Red Hat/Fedora.
+ sudo yum -y install doxygen
+
+`Sphinx`_ is a Python documentation tool for converting RST files to Html or
+to PDF (via LaTeX). It can be installed as follows:
+
+.. code-block:: console
+
+ # Ubuntu/Debian.
+ sudo apt-get -y install python-sphinx
+
+ # Red Hat/Fedora.
+ sudo yum -y install python-sphinx
+
+ # Or, on any system with Python installed.
+ sudo easy_install -U sphinx
+
+For further information on getting started with Sphinx see the `Sphinx
+Tutorial <http://sphinx-doc.org/tutorial.html>`_.
+
+.. Note::
+
+ To get full support for Figure and Table numbering it is best to install
+ Sphinx 1.3.1 or later.
+
+
+`Inkscape`_ is a vector based graphics program which is used to create SVG
+images and also to convert SVG images to PDF images. It can be installed as
+follows:
+
+.. code-block:: console
+
+ # Ubuntu/Debian.
+ sudo apt-get -y install inkscape
+
+ # Red Hat/Fedora.
+ sudo yum -y install inkscape
+
+`TexLive <http://www.tug.org/texlive/>`_ is an installation package for
+Tex/LaTeX. It is used to generate the PDF versions of the
+documentation. Installation of all of the TeX components required by Sphinx
+can be tricky. If possible it is best to install TexLive Full to ensure that
+you have all the requirements. It can be installed as follows:
+
+.. code-block:: console
+
+ # Ubuntu/Debian.
+
+ sudo apt-get -y install texlive-full
+
+ # Red Hat/Fedora, selective install.
+ sudo yum -y install texlive
+ sudo yum -y install texlive-latex
+ sudo yum -y install texlive-collection-latex
+ sudo yum -y install texlive-collection-latexrecommended
+ sudo yum -y install texlive-collection-latexextra
+ sudo yum -y install texlive-dejavu
+
+
+Build commands
+~~~~~~~~~~~~~~
+
+The documentation is built using the standard DPDK build system. Some examples
+are shown below:
+
+* Generate all the documentation targets::
+
+ make doc
+
+* Generate the Doxygen API documentation in Html::
+
+ make doc-api-html
+
+* Generate the guides documentation in Html::
+
+ make doc-guides-html
+
+* Generate the guides documentation in Pdf::
+
+ make doc-guides-pdf
+
+The output of these commands is generated in the ``build`` directory::
+
+ build/doc
+ |-- html
+ | |-- api
+ | +-- guides
+ |
+ +-- pdf
+ +-- guides
+
+
+.. Note::
+
+ Make sure to fix any Sphinx or Doxygen warnings when adding or updating
+ documentation.
+
+The documentation output files can be removed as follows::
+
+ make doc-clean
+
+
+Document Guidelines
+-------------------
+
+Here are some guidelines in relation to the style of the documentation:
+
+* Document the obvious as well as the obscure since it won't always be obvious
+ to the reader. For example an instruction like "Set up 64 2MB Hugepages" is
+ better when followed by a sample commandline or a link to the appropriate
+ section of the documentation.
+
+* Use American English spellings throughout. This can be checked using the
+ ``aspell`` utility::
+
+ aspell --lang=en_US --check doc/guides/sample_app_ug/mydoc.rst
+
+
+RST Guidelines
+--------------
+
+The RST (reStructuredText) format is a plain text markup format that can be
+converted to Html, PDF or other formats. It is most closely associated with
+Python but it can be used to document any language. It is used in DPDK to
+document everything apart from the API.
+
+The Sphinx documentation contains a very useful `RST Primer
+<http://sphinx-doc.org/rest.html#rst-primer>`_ which is a good place to learn
+the minimal set of syntax required to format a document.
+
+The official `reStructuredText <http://docutils.sourceforge.net/rst.html>`_
+website contains the specification for the RST format and also examples of how
+to use it. However, for most developers the RST Primer above is a better
+resource.
+
+The most common guidelines for writing RST text are detailed in the
+`Documenting Python <https://docs.python.org/devguide/documenting.html>`_
+guidelines. The additional guidelines below reiterate or expand upon those
+guidelines.
+
+
+Readability
+~~~~~~~~~~~
+
+The main RST guideline is that the RST text should be readable in text format.
+
+Even though RST is a markup format and the text will most often be read when
+rendered to Html or PDF it is important to maintain readability of the raw
+text. This makes is easier for developers to read in an editor or in a
+terminal.
+
+
+Line Length
+~~~~~~~~~~~
+
+The existing documentation contains different styles for long lines and
+paragraphs. The following are recommendations for new text in order of
+preference:
+
+* Wrap lines at 80 characters. This is the Python RST recommendation and adds
+ to readability of the raw text.
+
+* Use one sentence per line in a paragraph, i.e., put a newline character
+ after each period/full stop.
+
+* Use one line per paragraph.
+
+
+Whitespace
+~~~~~~~~~~
+
+* Standard RST indentation is 3 spaces. Code can be indented 4 spaces,
+ especially if it is copied from source files.
+
+* No tabs. Convert tabs in embedded code to 4 or 8 spaces.
+
+* No trailing whitespace.
+
+* The most common existing style in the documentation is to have only 1 space
+ after a period/full stop.
+
+* Add 2 blank lines before each section header.
+
+* Add 1 blank line after each section header.
+
+* Add 1 blank line between each line of a list.
+
+
+Section Headers
+~~~~~~~~~~~~~~~
+
+* Section headers should use the use the following underline formats::
+
+ Level 1 Heading
+ ===============
+
+
+ Level 2 Heading
+ ---------------
+
+
+ Level 3 Heading
+ ~~~~~~~~~~~~~~~
+
+
+ Level 4 Heading
+ ^^^^^^^^^^^^^^^
+
+
+* Level 4 headings should be used sparingly.
+
+* The underlines should match the length of the text.
+
+* In general, the heading should be less than 80 characters.
+
+* As noted above:
+
+ * Add 2 blank lines before each section header.
+
+ * Add 1 blank line after each section header.
+
+
+Lists
+~~~~~
+
+* Bullet lists should be formatted with a leading ``*`` as follows::
+
+ * Item one.
+
+ * Item two is a longer line that is wrapped at 80 characters and then
+ indented to match the start of the first line.
+
+ * One space character between the bullet and the text is preferred.
+
+* Numbered lists can be formatted with a leading number but the preference is
+ to use ``#.`` which will give automatic numbering. This is more convenient
+ when adding or removing items::
+
+ #. Item one.
+
+ #. Item two is a longer line that is wrapped at 80 characters and then
+ indented to match the start of the e first line.
+
+* Definition lists can be written with or without a bullet::
+
+ * Item one.
+
+ Some text about item one.
+
+ * Item two.
+
+ Some text about item two.
+
+* All lists, and sub-lists, must be separated from the preceding text by a
+ blank line. This is a syntax requirement.
+
+* All list items should be separated by a blank line for readability.
+
+
+Code and Literal block sections
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* Inline text that is required to be rendered with a fixed width font should
+ be enclosed in backquotes like this: \`\`text\`\`, so that it appears like
+ this: ``text``.
+
+* Fixed width, literal blocks of texts should be indented at least 3 spaces
+ and prefixed with ``::`` like this::
+
+ Here is some fixed width text::
+
+ 0x0001 0x0001 0x00FF 0x00FF
+
+* It is also possible to specify an encoding for a literal block using the
+ ``.. code-block::`` directive so that syntax highlighting can be
+ applied. Examples of supported highlighting are::
+
+ .. code-block:: console
+ .. code-block:: c
+ .. code-block:: python
+ .. code-block:: diff
+ .. code-block:: none
+
+ That can be applied as follows::
+
+ .. code-block:: c
+
+ #include<stdio.h>
+
+ int main() {
+
+ printf("Hello World\n");
+
+ return 0;
+ }
+
+ Which would be rendered as:
+
+ .. code-block:: c
+
+ #include<stdio.h>
+
+ int main() {
+
+ printf("Hello World\n");
+
+ return 0;
+ }
+
+
+* The default encoding for a literal block using the simplified ``::``
+ directive is ``none``.
+
+* Avoid lines longer than 80 character in literal blocks since they can exceed
+ the page width when converted to PDF documentation. If possible try to wrap
+ the text at sensible locations. For example a long command line could be
+ documented like this and still work if copied directly from the docs::
+
+ build/app/testpmd -c7 -n3 --vdev=eth_pcap0,iface=eth0 \
+ --vdev=eth_pcap1,iface=eth1 \
+ -- -i --nb-cores=2 --nb-ports=2 \
+ --total-num-mbufs=2048
+
+
+Images
+~~~~~~
+
+* All images should be in SVG scalar graphics format. They should be true SVG
+ XML files and should not include binary formats embedded in a SVG wrapper.
+
+* The DPDK documentation contains some legacy images in PNG format. These will
+ be converted to SVG in time.
+
+* `Inkscape <inkscape.org>`_ is the recommended graphics editor for creating
+ the images. Use some of the older images in ``doc/guides/prog_guide/img/``
+ as a template, for example ``mbuf1.svg`` or ``ring-enqueue.svg``.
+
+* The SVG images should include a copyright notice, as an XML comment.
+
+* Images in the documentation should be formatted as follows:
+
+ * The image should be preceded by a label in the format
+ ``.. _figure_XXXX:`` with a leading underscore and where ``XXXX`` is a
+ unique descriptive name.
+
+ * Images should be included using the ``.. figure::`` directive and the
+ file type should be set to ``*`` (not ``.svg``). This allows the format
+ of the image to be changed if required.
+
+ * Images must have a caption as part of the ``.. figure::`` directive.
+
+* Here is an example of the previous three guidelines::
+
+ .. _figure_mempool:
+
+ .. figure:: img/mempool.*
+
+ A mempool in memory with its associated ring.
+
+.. _mock_label:
+
+* Images can then be linked to using the ``:numref:`` directive::
+
+ The mempool layout is shown in :numref:`figure_mempool`.
+
+ This would be rendered as: *The mempool layout is shown in* :ref:`Fig 6.3
+ <mock_label>`.
+
+ **Note**: The ``:numref:`` directive requires Sphinx 1.3.1 or later. With
+ earlier versions it will still be rendered as a link but won't have an
+ automatically generated number.
+
+* The caption of the image can be generated, with a link, using the ``:ref:``
+ directive::
+
+ :ref:`figure_mempool`
+
+ This would be rendered as: *A mempool in memory with its associated ring.*
+
+Tables
+~~~~~~
+
+* RST tables should be used sparingly. They are hard to format and to edit,
+ they are often rendered incorrectly in PDF format, and the same information
+ can usually be shown just as clearly with a list.
+
+* Tables in the documentation should be formatted as follows:
+
+ * The table should be preceded by a label in the format
+ ``.. _table_XXXX:`` with a leading underscore and where ``XXXX`` is a
+ unique descriptive name.
+
+ * Tables should be included using the ``.. table::`` directive and must
+ have a caption.
+
+* Here is an example of the previous two guidelines::
+
+ .. _table_qos_pipes:
+
+ .. table:: Sample configuration for QOS pipes.
+
+ +----------+----------+----------+
+ | Header 1 | Header 2 | Header 3 |
+ | | | |
+ +==========+==========+==========+
+ | Text | Text | Text |
+ +----------+----------+----------+
+ | ... | ... | ... |
+ +----------+----------+----------+
+
+* Tables can be linked to using the ``:numref:`` and ``:ref:`` directives, as
+ shown in the previous section for images. For example::
+
+ The QOS configuration is shown in :numref:`table_qos_pipes`.
+
+* Tables should not include merged cells since they are not supported by the
+ PDF renderer.
+
+
+.. _links:
+
+Hyperlinks
+~~~~~~~~~~
+
+* Links to external websites can be plain URLs. The following is rendered as
+ http://dpdk.org::
+
+ http://dpdk.org
+
+* They can contain alternative text. The following is rendered as
+ `Check out DPDK <http://dpdk.org>`_::
+
+ `Check out DPDK <http://dpdk.org>`_
+
+* An internal link can be generated by placing labels in the document with the
+ format ``.. _label_name``.
+
+* The following links to the top of this section: :ref:`links`::
+
+ .. _links:
+
+ Hyperlinks
+ ~~~~~~~~~~
+
+ * The following links to the top of this section: :ref:`links`:
+
+.. Note::
+
+ The label must have a leading underscore but the reference to it must omit
+ it. This is a frequent cause of errors and warnings.
+
+* The use of a label is preferred since it works across files and will still
+ work if the header text changes.
+
+
+.. _doxygen_guidelines:
+
+Doxygen Guidelines
+------------------
+
+The DPDK API is documented using Doxygen comment annotations in the header
+files. Doxygen is a very powerful tool, it is extremely configurable and with
+a little effort can be used to create expressive documents. See the `Doxygen
+website <http://www.stack.nl/~dimitri/doxygen/>`_ for full details on how to
+use it.
+
+The following are some guidelines for use of Doxygen in the DPDK API
+documentation:
+
+* New libraries that are documented with Doxygen should be added to the
+ Doxygen configuration file: ``doc/api/doxy-api.conf``. It is only required
+ to add the directory that contains the files. It isn't necessary to
+ explicitly name each file since the configuration matches all ``rte_*.h``
+ files in the directory.
+
+* Use proper capitalization and punctuation in the Doxygen comments since they
+ will become sentences in the documentation. This in particular applies to
+ single line comments, which is the case the is most often forgotten.
+
+* Use ``@`` style Doxygen commands instead of ``\`` style commands.
+
+* Add a general description of each library at the head of the main header
+ files:
+
+ .. code-block:: c
+
+ /**
+ * @file
+ * RTE Mempool.
+ *
+ * A memory pool is an allocator of fixed-size object. It is
+ * identified by its name, and uses a ring to store free objects.
+ * ...
+ */
+
+* Document the purpose of a function, the parameters used and the return
+ value:
+
+ .. code-block:: c
+
+ /**
+ * Attach a new Ethernet device specified by arguments.
+ *
+ * @param devargs
+ * A pointer to a strings array describing the new device
+ * to be attached. The strings should be a pci address like
+ * `0000:01:00.0` or **virtual** device name like `eth_pcap0`.
+ * @param port_id
+ * A pointer to a port identifier actually attached.
+ *
+ * @return
+ * 0 on success and port_id is filled, negative on error.
+ */
+ int rte_eth_dev_attach(const char *devargs, uint8_t *port_id);
+
+* Doxygen supports Markdown style syntax such as bold, italics, fixed width
+ text and lists. For example the second line in the ``devargs`` parameter in
+ the previous example will be rendered as:
+
+ The strings should be a pci address like ``0000:01:00.0`` or **virtual**
+ device name like ``eth_pcap0``.
+
+* Use ``-`` instead of ``*`` for lists within the Doxygen comment since the
+ latter can get confused with the comment delimiter.
+
+* Add an empty line between the function description, the ``@params`` and
+ ``@return`` for readability.
+
+* Place the ``@params`` description on separate line and indent it by 2
+ spaces. (It would be better to use no indentation since this is more common
+ and also because checkpatch complains about leading whitespace in
+ comments. However this is the convention used in the existing DPDK code.)
+
+* Documented functions can be linked to simply by adding ``()`` to the
+ function name:
+
+ .. code-block:: c
+
+ /**
+ * The functions exported by the application Ethernet API to setup
+ * a device designated by its port identifier must be invoked in
+ * the following order:
+ * - rte_eth_dev_configure()
+ * - rte_eth_tx_queue_setup()
+ * - rte_eth_rx_queue_setup()
+ * - rte_eth_dev_start()
+ */
+
+ In the API documentation the functions will be rendered as links, see the
+ `online section of the rte_ethdev.h docs
+ <http://dpdk.org/doc/api/rte__ethdev_8h.html>`_ that contains the above
+ text.
+
+* The ``@see`` keyword can be used to create a *see also* link to another file
+ or library. This directive should be placed on one line at the bottom of the
+ documentation section.
+
+ .. code-block:: c
+
+ /**
+ * ...
+ *
+ * Some text that references mempools.
+ *
+ * @see eal_memzone.c
+ */
+
+* Doxygen supports two types of comments for documenting variables, constants
+ and members: prefix and postfix:
+
+ .. code-block:: c
+
+ /** This is a prefix comment. */
+ #define RTE_FOO_ERROR 0x023.
+
+ #define RTE_BAR_ERROR 0x024. /**< This is a postfix comment. */
+
+* Postfix comments are preferred for struct members and constants if they can
+ be documented in the same way:
+
+ .. code-block:: c
+
+ struct rte_eth_stats {
+ uint64_t ipackets; /**< Total number of received packets. */
+ uint64_t opackets; /**< Total number of transmitted packets.*/
+ uint64_t ibytes; /**< Total number of received bytes. */
+ uint64_t obytes; /**< Total number of transmitted bytes. */
+ uint64_t imissed; /**< Total of RX missed packets. */
+ uint64_t ibadcrc; /**< Total of RX packets with CRC error. */
+ uint64_t ibadlen; /**< Total of RX packets with bad length. */
+ }
+
+ Note: postfix comments should be aligned with spaces not tabs in accordance
+ with the :ref:`coding_style`.
+
+* If a single comment type can't be used, due to line length limitations then
+ prefix comments should be preferred. For example this section of the code
+ contains prefix comments, postfix comments on the same line and postfix
+ comments on a separate line:
+
+ .. code-block:: c
+
+ /** Number of elements in the elt_pa array. */
+ uint32_t pg_num __rte_cache_aligned;
+ uint32_t pg_shift; /**< LOG2 of the physical pages. */
+ uintptr_t pg_mask; /**< Physical page mask value. */
+ uintptr_t elt_va_start;
+ /**< Virtual address of the first mempool object. */
+ uintptr_t elt_va_end;
+ /**< Virtual address of the <size + 1> mempool object. */
+ phys_addr_t elt_pa[MEMPOOL_PG_NUM_DEFAULT];
+ /**< Array of physical page addresses for the mempool buffer. */
+
+ This doesn't have an effect on the rendered documentation but it is
+ confusing for the developer reading the code. It this case it would be
+ clearer to use prefix comments throughout:
+
+ .. code-block:: c
+
+ /** Number of elements in the elt_pa array. */
+ uint32_t pg_num __rte_cache_aligned;
+ /** LOG2 of the physical pages. */
+ uint32_t pg_shift;
+ /** Physical page mask value. */
+ uintptr_t pg_mask;
+ /** Virtual address of the first mempool object. */
+ uintptr_t elt_va_start;
+ /** Virtual address of the <size + 1> mempool object. */
+ uintptr_t elt_va_end;
+ /** Array of physical page addresses for the mempool buffer. */
+ phys_addr_t elt_pa[MEMPOOL_PG_NUM_DEFAULT];
+
+* Check for Doxygen warnings in new code by checking the API documentation
+ build::
+
+ make doc-api-html | grep "warning:"
+
+* Read the rendered section of the documentation that you have added for
+ correctness, clarity and consistency with the surrounding text.
+
+
+Patching the Documentation
+--------------------------
+
+One of the easiest ways to contribute to DPDK is to submit a patch to the
+documentation.
+
+Over time the documentation may contain information that is slightly out of
+date or that could be improved upon. Newcomers to the DPDK project often
+notice these issues as they work through the examples and how-to guides.
+
+Rather than emailing the development list, or even ignoring the issue, it is
+just as easy to submit a patch to fix it. The following instructions explain
+how to do that and since they are meant to encourage contributions they assume
+no development experience or prior exposure to the DPDK workflow.
+
+#. Install the documentation dependencies as shown above. As a minimum you
+ should install Sphinx::
+
+ # Ubuntu/Debian.
+ sudo apt-get -y install python-sphinx
+
+ # Red Hat/Fedora.
+ sudo yum -y install python-sphinx
+
+ If you are going to patch the API docs you will need Doxygen. You can omit
+ TexLive and Inkscape for now.
+
+#. Install ``git`` as follows::
+
+ # Ubuntu/Debian.
+ sudo apt-get -y install git
+
+ # Red Hat/Fedora.
+ sudo yum -y install git
+
+ If you have any problems, refer to the official `Git installation guide
+ <https://git-scm.com/book/en/v2/Getting-Started-Installing-Git>`_.
+
+#. Configure your ``.gitconfig`` file with your name and email address::
+
+ git config --global user.name "J. Smith"
+ git config --global user.email jsmith@example.com
+
+ If you wish you can also configure the default editor that is used to write
+ commit messages::
+
+ git config --global core.editor vi
+
+ See the `Git getting started guide
+ <https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup>`_ if
+ you have any issues.
+
+#. Clone the DPDK repository (this can take a minute or two)::
+
+ git clone http://dpdk.org/git/dpdk
+
+#. Change into the new ``dpdk`` directory and test if you have the required
+ dependencies to build the docs::
+
+ cd dpdk
+ make doc-guides-html
+
+ If you get warnings about missing utilities go back and work through
+ installing the dependencies again.
+
+ If you installed some of the other dependencies you can try the following,
+ but they aren't required::
+
+ # If you installed Doxygen:
+ make doc-api-html
+
+ # If you installed Inkscape and TexLive as well:
+ make doc
+
+ .. Note::
+
+ You can ignore a warning about upgrading Sphinx, that is optional. If
+ you are building the documentation on Mac OS you can ignore a warning
+ from ``sed``.
+
+#. Using your preferred editor make the changes to the file you want to fix or
+ improve. For example::
+
+ vi doc/guides/linux_gsg/quick_start.rst
+
+#. Once you have make the modifications you should see a change in the ``git
+ status``::
+
+ git status
+
+ On branch master
+ Your branch is up-to-date with 'origin/master'.
+ Changes not staged for commit:
+ (use "git add <file>..." to update what will be committed)
+ (use "git checkout -- <file>..." to discard changes)
+
+ modified: doc/guides/linux_gsg/quick_start.rst
+
+
+#. You will be able to review your changes using ``git diff``:
+
+ .. code-block:: diff
+
+ git diff
+
+ diff --git a/quick_start.rst b/quick_start.rst
+ index b07fc87..7b49e1c 100644
+ --- a/doc/guides/linux_gsg/quick_start.rst
+ +++ b/doc/guides/linux_gsg/quick_start.rst
+ @@ -256,7 +256,7 @@ The following selection demonstrates the launch
+
+ Enter hex bitmask of cores to execute test app on
+ Example: to execute app on cores 0 to 7, enter 0xff
+ - bitmaks: 0x01
+ + bitmask: 0x01
+ Launching app
+ EAL: coremask set to 1
+ EAL: Detected lcore 0 on socket 0
+
+ Two other diff options that are useful when dealing with changes to
+ documentation are word and character diffs::
+
+ # View differences by word instead of lines:
+ git diff --color-words
+
+ # View differences by character:
+ git diff --color-words=.
+
+
+#. Rebuild the docs and fix any new warnings::
+
+ make doc-guides-html
+
+#. Open the output Html document and review your changes in the context of the
+ surrounding text. Use a Web browser like the following::
+
+ firefox build/doc/html/guides/linux_gsg/quick_start.html &
+
+#. If everything is okay you can commit your changes to your local repository
+ and generate a patch. The first step is to add the file(s) that you
+ modified::
+
+ git add doc/guides/linux_gsg/quick_start.rst
+
+#. Now commit the changes to the local repository. You must "sign" the commit
+ by using ``-s``. This will insert the name and email address that you
+ configured in your ``.gitconfig`` above::
+
+ git commit -s
+
+ This will drop you into the default, or configured, editor and you can
+ insert a message like the following::
+
+ doc: fix minor typo in linux getting started guide
+
+ Fixed a minor typo in the Linux Getting Started Guide.
+
+ Signed-off-by: J. Smith <jsmith@example.com>
+
+ The first line will be used as a subject line for an email so it should:
+
+ * start with ``doc:``
+ * be less than 50 characters
+ * be lowercase only
+ * and not end with a period/full stop
+
+ The body of the text should:
+
+ * describe the change
+ * be wrapped at 72 characters
+ * have proper punctuation and capitalization
+
+ The body of the message should generally be longer than the example above
+ and should explain the purpose of the change.
+
+#. You can now create and email a patch. This can be done in one step from git
+ but for beginners it is best done in two steps so that you can review the
+ patch. First generate the patch::
+
+ git format-patch -1
+
+ This will generate a patch like the following::
+
+ 0001-doc-fix-minor-typo-in-linux-getting-started-guide.patch
+
+ If you have a large patch or set of patches you can also generate a cover
+ letter to explain the changes by adding the ``--cover-letter`` option.
+
+
+#. If you are happy that everything looks good you can sent the patch to the
+ DPDK ``dev`` mailing list::
+
+ git send-mail --to dev@dpdk.org 0001-doc-fix-minor-typo-etc.patch
+
+ If you have issues see the `git send-mail
+ <http://git-scm.com/docs/git-send-email>`_ section of the the Git
+ documentation.
+
+ If all goes well the patch will appear on the `DPDK dev mailing list
+ <http://dpdk.org/ml/listinfo/dev>`_ and in the `DPDK Patchwork
+ <http://dpdk.org/dev/patchwork/project/dpdk/list/>`_.
diff --git a/doc/guides/guidelines/index.rst b/doc/guides/guidelines/index.rst
index bfb9fa3..1050d99 100644
--- a/doc/guides/guidelines/index.rst
+++ b/doc/guides/guidelines/index.rst
@@ -8,3 +8,5 @@ Guidelines
coding_style
design
versioning
+ documentation
+
--
1.8.1.4
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2] doc: fix minor sphinx build warning
@ 2015-07-02 14:15 8% John McNamara
2015-07-06 14:55 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: John McNamara @ 2015-07-02 14:15 UTC (permalink / raw)
To: dev
Fix for a minor Sphinx build warning in the ABI guidelines docs:
versioning.rst:126: WARNING: Bullet list ends without a
blank line; unexpected unindent.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/guidelines/versioning.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
index a1c9368..ea789cb 100644
--- a/doc/guides/guidelines/versioning.rst
+++ b/doc/guides/guidelines/versioning.rst
@@ -122,9 +122,9 @@ The macros exported are:
the linker to bind references to symbol ``b`` to the internal symbol
``b_e``.
-* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the fully
-qualified function ``p``, so that if a symbol becomes versioned, it can still be
-mapped back to the public symbol name.
+* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
+ fully qualified function ``p``, so that if a symbol becomes versioned, it
+ can still be mapped back to the public symbol name.
Examples of ABI Macro use
-------------------------
--
1.8.1.4
V2: Removed main heading label.
^ permalink raw reply [relevance 8%]
* [dpdk-dev] [PATCH v3 0/7] ethdev: add support for ieee1588 timestamping
2015-06-29 13:42 4% [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping John McNamara
2015-06-29 13:42 14% ` [dpdk-dev] [PATCH v2 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
2015-07-02 1:24 0% ` [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping Lu, Wenzhuo
@ 2015-07-02 15:16 4% ` John McNamara
2015-07-02 15:16 14% ` [dpdk-dev] [PATCH v3 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
` (2 more replies)
2 siblings, 3 replies; 200+ results
From: John McNamara @ 2015-07-02 15:16 UTC (permalink / raw)
To: dev
This patchset adds ethdev API to enable and read IEEE1588/802.1AS PTP timestamps from devices that support it. The following functions are added:
rte_eth_timesync_enable()
rte_eth_timesync_disable()
rte_eth_timesync_read_rx_timestamp()
rte_eth_timesync_read_tx_timestamp()
The "ieee1588" forwarding mode in testpmd is also refactored to demonstrate the new API and to clean up the code.
Adds support for igb, ixgbe and i40e.
V3:
* Fixed issued with version.map.
V2:
* Added i40e support.
* Renamed ethdev functions from rte_eth_ieee15888_*() to rte_eth_timesync_*()
since 802.1AS can be supported through the same interfaces.
V1:
* Initial version for
John McNamara (7):
ethdev: add support for ieee1588 timestamping
e1000: add support for ieee1588 timestamping
ixgbe: add support for ieee1588 timestamping
i40e: add support for ieee1588 timestamping
app/testpmd: refactor ieee1588 forwarding
doc: document ieee1588 forwarding mode
abi: announce mbuf addition for ieee1588 in DPDK 2.2
app/test-pmd/ieee1588fwd.c | 466 ++--------------------------
doc/guides/rel_notes/abi.rst | 5 +
doc/guides/testpmd_app_ug/run_app.rst | 2 +-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +
drivers/net/e1000/igb_ethdev.c | 115 +++++++
drivers/net/i40e/i40e_ethdev.c | 143 +++++++++
drivers/net/i40e/i40e_rxtx.c | 39 ++-
drivers/net/ixgbe/ixgbe_ethdev.c | 122 ++++++++
lib/librte_ether/rte_ethdev.c | 70 ++++-
lib/librte_ether/rte_ethdev.h | 90 +++++-
lib/librte_ether/rte_ether_version.map | 4 +
11 files changed, 615 insertions(+), 443 deletions(-)
--
1.8.1.4
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2
2015-07-02 15:16 4% ` [dpdk-dev] [PATCH v3 " John McNamara
@ 2015-07-02 15:16 14% ` John McNamara
2015-07-06 13:16 4% ` Thomas Monjalon
2015-07-03 8:22 0% ` [dpdk-dev] [PATCH v3 0/7] ethdev: add support for ieee1588 timestamping Lu, Wenzhuo
2015-07-08 1:59 0% ` Fu, JingguoX
2 siblings, 1 reply; 200+ results
From: John McNamara @ 2015-07-02 15:16 UTC (permalink / raw)
To: dev
Add announcement of a dedicated additional field in the mbuf
to support ieee1588 in DPDK 2.2.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/rel_notes/abi.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index f00a6ee..51dacb2 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -38,3 +38,8 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+
+* In DPDK 2.1 the IEEE1588/802.1AS support in the i40e driver makes use of the
+ ``udata64`` field in the mbuf to pass the timesync register index to the
+ user. In DPDK 2.2 this will be moved to a new field in the mbuf.
+
--
1.8.1.4
^ permalink raw reply [relevance 14%]
* Re: [dpdk-dev] [PATCH 2/3] doc: added guidelines on dpdk documentation
2015-07-02 13:50 3% ` [dpdk-dev] [PATCH 2/3] " John McNamara
@ 2015-07-02 16:20 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-02 16:20 UTC (permalink / raw)
To: John McNamara; +Cc: dev
2015-07-02 14:50, John McNamara:
> Added guidelines on the purpose and structure of the DPDK
> documentation, how to build it and guidelines for creating it.
>
> Also added guidelines on how to format and submit a documentation patch.
Good idea to have guidelines for doc.
But I think the submission guidelines shouldn't be specific to doc.
Could you move it to a contributing.rst file?
Guidelines from the website could be moved there.
> + In general developers do not have to update the Release Notes apart from
> + adding ABI announcements.
Someone must update the release notes.
Why not doing it atomicly when introducing a new feature?
> + The guideline documents record the DPDK guidelines on coding, design, ABI
> + usage and documentation.
> +
> + These should be changed to clarify or improve guidelines.
The guideline documents record community process, expectations and design
directions.
They can be extended, amended or discussed by submitting a patch and getting
community approval.
> +* Sphinx.
Sphinx (also called python-sphinx).
> +
> +* TexLive.
TexLive (at least TexLive-core, extra Latex support and extra fonts).
> + # Ubuntu/Debian.
> +
> + sudo apt-get -y install texlive-full
lighter:
sudo apt-get -y install texlive-latex-extra texlive-fonts-extra texlive-fonts-recommended
> + # Red Hat/Fedora, selective install.
> + sudo yum -y install texlive
> + sudo yum -y install texlive-latex
> + sudo yum -y install texlive-collection-latex
> + sudo yum -y install texlive-collection-latexrecommended
> + sudo yum -y install texlive-collection-latexextra
> + sudo yum -y install texlive-dejavu
simpler:
sudo yum -y install texlive-collection-latexextra, texlive-collection-fontsextra
> + aspell --lang=en_US --check doc/guides/sample_app_ug/mydoc.rst
Good tip!
What about making it more visible? :)
> +* Use one sentence per line in a paragraph, i.e., put a newline character
> + after each period/full stop.
What about adding this?
Only blank line will generate a newline.
I think breaking lines at end of sentence is more important than
wrapping at 80 char, because it will help to keep patches
readable.
> +* Use one line per paragraph.
Why this recommendation? I think it doesn't help.
> +* Avoid lines longer than 80 character in literal blocks since they can exceed
> + the page width when converted to PDF documentation. If possible try to wrap
> + the text at sensible locations. For example a long command line could be
> + documented like this and still work if copied directly from the docs::
> +
> + build/app/testpmd -c7 -n3 --vdev=eth_pcap0,iface=eth0 \
> + --vdev=eth_pcap1,iface=eth1 \
> + -- -i --nb-cores=2 --nb-ports=2 \
> + --total-num-mbufs=2048
Yes. Maybe that "avoid" is not strong enough.
> +* RST tables should be used sparingly. They are hard to format and to edit,
> + they are often rendered incorrectly in PDF format, and the same information
> + can usually be shown just as clearly with a list.
... or with a definition list.
> +* The use of a label is preferred since it works across files and will still
> + work if the header text changes.
Artificial labels are a bit ugly.
If a header change, there will be an error for the link, right?
> +Doxygen Guidelines
> +------------------
I think you should split your patch here and have a separate patch to move
the doxygen guidelines from the coding style doc.
> +Patching the Documentation
> +--------------------------
> +
> +One of the easiest ways to contribute to DPDK is to submit a patch to the
> +documentation.
> +
> +Over time the documentation may contain information that is slightly out of
> +date or that could be improved upon. Newcomers to the DPDK project often
> +notice these issues as they work through the examples and how-to guides.
> +
> +Rather than emailing the development list, or even ignoring the issue, it is
> +just as easy to submit a patch to fix it. The following instructions explain
> +how to do that and since they are meant to encourage contributions they assume
> +no development experience or prior exposure to the DPDK workflow.
> +
> +#. Install the documentation dependencies as shown above. As a minimum you
> + should install Sphinx::
> +
Using a link to above section would ease future update or extension.
> + # Ubuntu/Debian.
> + sudo apt-get -y install python-sphinx
> +
> + # Red Hat/Fedora.
> + sudo yum -y install python-sphinx
> +
> + If you are going to patch the API docs you will need Doxygen. You can omit
> + TexLive and Inkscape for now.
> +
>From this point, it could be a link to a starter section in a contributing doc.
> +#. Install ``git`` as follows::
[...]
> +#. Clone the DPDK repository (this can take a minute or two)::
[...]
>From this point, it is specific to doc.
> + make doc-guides-html
> +
> + If you get warnings about missing utilities go back and work through
> + installing the dependencies again.
[...]
> + You can ignore a warning about upgrading Sphinx, that is optional. If
> + you are building the documentation on Mac OS you can ignore a warning
> + from ``sed``.
Not aware of this warning. Could it be removed?
> +#. If everything is okay you can commit your changes to your local repository
> + and generate a patch. The first step is to add the file(s) that you
> + modified::
> +
> + git add doc/guides/linux_gsg/quick_start.rst
> +
> +#. Now commit the changes to the local repository. You must "sign" the commit
> + by using ``-s``. This will insert the name and email address that you
> + configured in your ``.gitconfig`` above::
> +
> + git commit -s
For a primer doc, "git commit -as" skip the "git add" step and would be OK.
> + doc: fix minor typo in linux getting started guide
> +
> + Fixed a minor typo in the Linux Getting Started Guide.
No need to repeat the title.
It would be more interesting to know why it is better after the patch.
In case of a typo, no comment is needed after the title.
>From this point, it is not specific to doc.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] mk: enable next abi in static libs
@ 2015-07-02 22:05 20% Thomas Monjalon
2015-07-06 13:18 4% ` Thomas Monjalon
2015-07-08 14:55 8% ` [dpdk-dev] [PATCH v2 0/2] next abi option Thomas Monjalon
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2015-07-02 22:05 UTC (permalink / raw)
To: dev
When a change makes really hard to keep ABI compatibility,
instead of waiting next release to break the ABI, it is smoother
to introduce the new code and enable it only for static libraries.
The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
When the release is out, a dynamically linked application can use
the new shared libraries without rebuild while developpers can prepare
their application for the next ABI by reading the deprecation notice
and easily testing the new code.
When starting the next release cycle, the "ifdefs" will be removed
and the ABI break will be marked by incrementing LIBABIVER.
The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
It is automatically enabled for static libraries and disabled for
shared libraries.
It can be forced to another value by editing the generated .config file.
It shouldn't be enabled for shared libraries because it would break the
ABI without changing the version number LIBABIVER. That's why a warning
is printed in this case.
The guideline is also updated to integrate this new possibility.
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
doc/guides/guidelines/versioning.rst | 2 ++
lib/Makefile | 4 ++++
mk/rte.sdkconfig.mk | 3 +++
pkg/dpdk.spec | 1 +
scripts/validate-abi.sh | 2 ++
5 files changed, 12 insertions(+)
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
index a1c9368..6bc2a8e 100644
--- a/doc/guides/guidelines/versioning.rst
+++ b/doc/guides/guidelines/versioning.rst
@@ -57,6 +57,8 @@ being provided. The requirements for doing so are:
#. A full deprecation cycle, as explained above, must be made to offer
downstream consumers sufficient warning of the change.
+ The changes may be shown and used in static builds before the deprecation
+ cycle by conditioning them with RTE_NEXT_ABI option.
#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
incorporated must be incremented in parallel with the ABI changes
diff --git a/lib/Makefile b/lib/Makefile
index 5f480f9..ebf56ba 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -31,6 +31,10 @@
include $(RTE_SDK)/mk/rte.vars.mk
+ifeq '$(CONFIG_RTE_BUILD_SHARED_LIB)$(CONFIG_RTE_NEXT_ABI)' 'yy'
+$(info WARNING: Shared libraries versioning is tainted!)
+endif
+
DIRS-y += librte_compat
DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_MALLOC) += librte_malloc
diff --git a/mk/rte.sdkconfig.mk b/mk/rte.sdkconfig.mk
index f8d95b1..135825c 100644
--- a/mk/rte.sdkconfig.mk
+++ b/mk/rte.sdkconfig.mk
@@ -77,6 +77,9 @@ $(RTE_OUTPUT)/.config: $(RTE_CONFIG_TEMPLATE) FORCE | $(RTE_OUTPUT)
$(CPP) -undef -P -x assembler-with-cpp \
-ffreestanding \
-o $(RTE_OUTPUT)/.config_tmp $(RTE_CONFIG_TEMPLATE) ; \
+ printf 'CONFIG_RTE_NEXT_ABI=' >> $(RTE_OUTPUT)/.config_tmp ; \
+ sed -n 's,CONFIG_RTE_BUILD_SHARED_LIB=,,p' $(RTE_OUTPUT)/.config_tmp | \
+ tr 'yn' 'ny' >> $(RTE_OUTPUT)/.config_tmp ; \
if ! cmp -s $(RTE_OUTPUT)/.config_tmp $(RTE_OUTPUT)/.config; then \
cp $(RTE_OUTPUT)/.config_tmp $(RTE_OUTPUT)/.config ; \
cp $(RTE_OUTPUT)/.config_tmp $(RTE_OUTPUT)/.config.orig ; \
diff --git a/pkg/dpdk.spec b/pkg/dpdk.spec
index 5f6ec6a..fb71ccc 100644
--- a/pkg/dpdk.spec
+++ b/pkg/dpdk.spec
@@ -82,6 +82,7 @@ make O=%{target} T=%{target} config
sed -ri 's,(RTE_MACHINE=).*,\1%{machine},' %{target}/.config
sed -ri 's,(RTE_APP_TEST=).*,\1n,' %{target}/.config
sed -ri 's,(RTE_BUILD_SHARED_LIB=).*,\1y,' %{target}/.config
+sed -ri 's,(RTE_NEXT_ABI=).*,\1n,' %{target}/.config
sed -ri 's,(LIBRTE_VHOST=).*,\1y,' %{target}/.config
sed -ri 's,(LIBRTE_PMD_PCAP=).*,\1y,' %{target}/.config
sed -ri 's,(LIBRTE_PMD_XENVIRT=).*,\1y,' %{target}/.config
diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
index 1747b8b..4476433 100755
--- a/scripts/validate-abi.sh
+++ b/scripts/validate-abi.sh
@@ -157,6 +157,7 @@ git checkout $TAG1
# Make sure we configure SHARED libraries
# Also turn off IGB and KNI as those require kernel headers to build
sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
+sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
@@ -198,6 +199,7 @@ git checkout $TAG2
# Make sure we configure SHARED libraries
# Also turn off IGB and KNI as those require kernel headers to build
sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
+sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
--
2.4.2
^ permalink raw reply [relevance 20%]
* Re: [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types
2015-07-02 9:31 0% ` Olivier MATZ
@ 2015-07-03 1:30 0% ` Zhang, Helin
0 siblings, 0 replies; 200+ results
From: Zhang, Helin @ 2015-07-03 1:30 UTC (permalink / raw)
To: Olivier MATZ, dev
> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Thursday, July 2, 2015 5:32 PM
> To: Zhang, Helin; dev@dpdk.org
> Cc: Cao, Waterman; Liang, Cunming; Liu, Jijiang; Ananyev, Konstantin; Richardson,
> Bruce; yongwang@vmware.com; Wu, Jingjing
> Subject: Re: [PATCH v8 03/18] mbuf: add definitions of unified packet types
>
> Hi Helin,
>
> On 07/02/2015 03:30 AM, Zhang, Helin wrote:
> > Hi Oliver
> >
> > Thanks for your helps!
> >
> >> -----Original Message-----
> >> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> >> Sent: Tuesday, June 30, 2015 4:44 PM
> >> To: Zhang, Helin; dev@dpdk.org
> >> Cc: Cao, Waterman; Liang, Cunming; Liu, Jijiang; Ananyev, Konstantin;
> >> Richardson, Bruce; yongwang@vmware.com; Wu, Jingjing
> >> Subject: Re: [PATCH v8 03/18] mbuf: add definitions of unified packet
> >> types
> >>
> >> Hi Helin,
> >>
> >> This is greatly documented, thanks!
> >> Please find a small comment below.
> >>
> >> On 06/23/2015 03:50 AM, Helin Zhang wrote:
> >>> As there are only 6 bit flags in ol_flags for indicating packet
> >>> types, which is not enough to describe all the possible packet types
> >>> hardware can recognize. For example, i40e hardware can recognize
> >>> more than 150 packet types. Unified packet type is composed of L2
> >>> type, L3 type, L4 type, tunnel type, inner L2 type, inner L3 type
> >>> and inner L4 type fields, and can be stored in 'struct rte_mbuf' of
> >>> 32 bits field 'packet_type'.
> >>> To avoid breaking ABI compatibility, all the changes would be
> >>> enabled by RTE_NEXT_ABI, which is disabled by default.
> >>>
> >>> [...]
> >>> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> >>> index 0315561..0ee0c55 100644
> >>> --- a/lib/librte_mbuf/rte_mbuf.h
> >>> +++ b/lib/librte_mbuf/rte_mbuf.h
> >>> @@ -201,6 +201,493 @@ extern "C" {
> >>> /* 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.
> >>> + * - Bit 3:0 is for L2 types.
> >>> + * - Bit 7:4 is for L3 or outer L3 (for tunneling case) types.
> >>> + * - Bit 11:8 is for L4 or outer L4 (for tunneling case) types.
> >>> + * - Bit 15:12 is for tunnel types.
> >>> + * - Bit 19:16 is for inner L2 types.
> >>> + * - Bit 23:20 is for inner L3 types.
> >>> + * - Bit 27:24 is for inner L4 types.
> >>> + * - Bit 31:28 is reserved.
> >>> + *
> >>> + * To be compatible with Vector PMD, RTE_PTYPE_L3_IPV4,
> >>> +RTE_PTYPE_L3_IPV4_EXT,
> >>> + * RTE_PTYPE_L3_IPV6, RTE_PTYPE_L3_IPV6_EXT, RTE_PTYPE_L4_TCP,
> >>> +RTE_PTYPE_L4_UDP
> >>> + * and RTE_PTYPE_L4_SCTP should be kept as below in a contiguous 7 bits.
> >>> + *
> >>> + * Note that L3 types values are selected for checking IPV4/IPV6
> >>> +header from
> >>> + * performance point of view. Reading annotations of
> >>> +RTE_ETH_IS_IPV4_HDR and
> >>> + * RTE_ETH_IS_IPV6_HDR is needed for any future changes of L3 type
> values.
> >>> + *
> >>> + * Note that the packet types of the same packet recognized by
> >>> +different
> >>> + * hardware may be different, as different hardware may have
> >>> +different
> >>> + * capability of packet type recognition.
> >>> + *
> >>> + * examples:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=0x29
> >>> + * | 'version'=6, 'next header'=0x3A
> >>> + * | 'ICMPv6 header'>
> >>> + * will be recognized on i40e hardware as packet type combination
> >>> +of,
> >>> + * RTE_PTYPE_L2_MAC |
> >>> + * RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
> >>> + * RTE_PTYPE_TUNNEL_IP |
> >>> + * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
> >>> + * RTE_PTYPE_INNER_L4_ICMP.
> >>> + *
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=0x2F
> >>> + * | 'GRE header'
> >>> + * | 'version'=6, 'next header'=0x11
> >>> + * | 'UDP header'>
> >>> + * will be recognized on i40e hardware as packet type combination
> >>> +of,
> >>> + * RTE_PTYPE_L2_MAC |
> >>> + * RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
> >>> + * RTE_PTYPE_TUNNEL_GRENAT |
> >>> + * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
> >>> + * RTE_PTYPE_INNER_L4_UDP.
> >>> + */
> >>> +#define RTE_PTYPE_UNKNOWN 0x00000000
> >>> +/**
> >>> + * MAC (Media Access Control) packet type.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=[0x0800|0x86DD|others]> */
> >>> +#define RTE_PTYPE_L2_MAC 0x00000001
> >>
> >> I'm wondering if RTE_PTYPE_L2_ETHER is not a better name?
> > Ethernet includes both Data Link Layer and Physical Layer, while MAC
> > is for Data Link Layer only. I would prefer to keep 'MAC' in the names, rather
> than 'ether'.
> > Any opinions from others?
>
> Just to precise what I'm saying: MAC is the interface between the logical link and
> the physical layer. It is different depending on the physical media (Ethernet,
> Token Ring, WLAN, ...).
> Every packet has a MAC layer and I think "MAC" does not bring any information.
>
> Having "ETHER" in the name would inform the software that it can expect an
> ethernet header. In the future, I would expect to have more L2 types like PPP.
OK, good explanation! I will change the name and thanks!
>
> I also have another question about RTE_PTYPE_L2_MAC. You describe it as
> "<'ether type'=[0x0800|0x86DD|others]>".
> What is the meaning of "others"? Does it mean that it is valid to set
> RTE_PTYPE_L2_MAC for any received packet?
OK. I think others should be removed. As ARP/LLDP like packet types are combined
together with MAC type.
>
> For instance, an ARP packet. The driver has the choice to set:
> A- RTE_PTYPE_UNKNOWN: the driver does not know the L2 packet
> type
> B- RTE_PTYPE_L2_MAC: the driver knows it's an ethernet packet
> (it should be the case for all received packets today as
> dpdk only supports ethernet ports)
> C- RTE_PTYPE_L2_ARP: the driver knows that the packet carries
> an ARP header after the ethernet header.
>
> Is it correct for a driver to always set B- for all received packets?
Currently it combines ether type and other ether type based protocols together.
So if it is a L2_LLDP, it could be treated as MAC + LLDP, while MAC means MAC only or MAC + L3.
>
> Another thing that bothers me a bit is that L2_ARP, L2_LLDP, L2_MAC_TIMESYNC,
> (...) are not really L2 types. The L2 type is Ethernet. On the other hand, they are
> not L3 type either.
> So, I have no other solution. The OSI model is probably a bit too theorical, and we
> have to choose the solution that is the most useful for the applications, even if it
> does not absolutely matches the theory ;)
Yes, they are a bit bothering. Currently they are combined together with L2 types.
Maybe it needs to define a MISC PACKET TYPE field, as we still have 4 bits available there.
Thanks,
Helin
>
>
> Regards,
> Olivier
>
>
> >
> > Regards,
> > Helin
> >
> >>
> >>
> >>> +/**
> >>> + * MAC (Media Access Control) packet type for time sync.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x88F7>
> >>> + */
> >>> +#define RTE_PTYPE_L2_MAC_TIMESYNC 0x00000002
> >>> +/**
> >>> + * ARP (Address Resolution Protocol) packet type.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0806>
> >>> + */
> >>> +#define RTE_PTYPE_L2_ARP 0x00000003
> >>> +/**
> >>> + * LLDP (Link Layer Discovery Protocol) packet type.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x88CC>
> >>> + */
> >>> +#define RTE_PTYPE_L2_LLDP 0x00000004
> >>
> >> Maybe ETHER should appear in these names too, what do you think?
> > Same as above.
> >
> >>
> >>
> >>
> >>
> >>> +/**
> >>> + * Mask of layer 2 packet types.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + */
> >>> +#define RTE_PTYPE_L2_MASK 0x0000000f
> >>> +/**
> >>> + * IP (Internet Protocol) version 4 packet type.
> >>> + * It is used for outer packet for tunneling cases, and does not
> >>> +contain any
> >>> + * header option.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'ihl'=5>
> >>> + */
> >>> +#define RTE_PTYPE_L3_IPV4 0x00000010
> >>> +/**
> >>> + * IP (Internet Protocol) version 4 packet type.
> >>> + * It is used for outer packet for tunneling cases, and contains
> >>> +header
> >>> + * options.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'ihl'=[6-15], 'options'> */
> >>> +#define RTE_PTYPE_L3_IPV4_EXT 0x00000030
> >>> +/**
> >>> + * IP (Internet Protocol) version 6 packet type.
> >>> + * It is used for outer packet for tunneling cases, and does not
> >>> +contain any
> >>> + * extension header.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=0x3B> */
> >>> +#define RTE_PTYPE_L3_IPV6 0x00000040
> >>> +/**
> >>> + * IP (Internet Protocol) version 4 packet type.
> >>> + * It is used for outer packet for tunneling cases, and may or
> >>> +maynot contain
> >>> + * header options.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'ihl'=[5-15], <'options'>> */
> >>> +#define RTE_PTYPE_L3_IPV4_EXT_UNKNOWN 0x00000090
> >>> +/**
> >>> + * IP (Internet Protocol) version 6 packet type.
> >>> + * It is used for outer packet for tunneling cases, and contains
> >>> +extension
> >>> + * headers.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> >>> + * 'extension headers'>
> >>> + */
> >>> +#define RTE_PTYPE_L3_IPV6_EXT 0x000000c0
> >>> +/**
> >>> + * IP (Internet Protocol) version 6 packet type.
> >>> + * It is used for outer packet for tunneling cases, and may or
> >>> +maynot contain
> >>> + * extension headers.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next
> header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> >>> + * <'extension headers'>>
> >>> + */
> >>> +#define RTE_PTYPE_L3_IPV6_EXT_UNKNOWN 0x000000e0
> >>> +/**
> >>> + * Mask of layer 3 packet types.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + */
> >>> +#define RTE_PTYPE_L3_MASK 0x000000f0
> >>> +/**
> >>> + * TCP (Transmission Control Protocol) packet type.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=6, 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=6>
> >>> + */
> >>> +#define RTE_PTYPE_L4_TCP 0x00000100
> >>> +/**
> >>> + * UDP (User Datagram Protocol) packet type.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=17, 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=17> */
> >>> +#define RTE_PTYPE_L4_UDP 0x00000200
> >>> +/**
> >>> + * Fragmented IP (Internet Protocol) packet type.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + *
> >>> + * It refers to those packets of any IP types, which can be
> >>> +recognized as
> >>> + * fragmented. A fragmented packet cannot be recognized as any
> >>> +other
> >>> +L4 types
> >>> + * (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP, RTE_PTYPE_L4_SCTP,
> >>> +RTE_PTYPE_L4_ICMP,
> >>> + * RTE_PTYPE_L4_NONFRAG).
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'MF'=1>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=44> */
> >>> +#define RTE_PTYPE_L4_FRAG 0x00000300
> >>> +/**
> >>> + * SCTP (Stream Control Transmission Protocol) packet type.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=132, 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=132> */
> >>> +#define RTE_PTYPE_L4_SCTP 0x00000400
> >>> +/**
> >>> + * ICMP (Internet Control Message Protocol) packet type.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=1, 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=1>
> >>> + */
> >>> +#define RTE_PTYPE_L4_ICMP 0x00000500
> >>> +/**
> >>> + * Non-fragmented IP (Internet Protocol) packet type.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + *
> >>> + * It refers to those packets of any IP types, while cannot be
> >>> +recognized as
> >>> + * any of above L4 types (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP,
> >>> + * RTE_PTYPE_L4_FRAG, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP).
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'!=[6|17|44|132|1]> */
> >>> +#define RTE_PTYPE_L4_NONFRAG 0x00000600
> >>> +/**
> >>> + * Mask of layer 4 packet types.
> >>> + * It is used for outer packet for tunneling cases.
> >>> + */
> >>> +#define RTE_PTYPE_L4_MASK 0x00000f00
> >>> +/**
> >>> + * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=[4|41]>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=[4|41]> */
> >>> +#define RTE_PTYPE_TUNNEL_IP 0x00001000
> >>> +/**
> >>> + * GRE (Generic Routing Encapsulation) tunneling packet type.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=47>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=47> */
> >>> +#define RTE_PTYPE_TUNNEL_GRE 0x00002000
> >>> +/**
> >>> + * VXLAN (Virtual eXtensible Local Area Network) tunneling packet type.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=17
> >>> + * | 'destination port'=4798>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=17
> >>> + * | 'destination port'=4798>
> >>> + */
> >>> +#define RTE_PTYPE_TUNNEL_VXLAN 0x00003000
> >>> +/**
> >>> + * NVGRE (Network Virtualization using Generic Routing
> >>> +Encapsulation) tunneling
> >>> + * packet type.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=47
> >>> + * | 'protocol type'=0x6558>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=47
> >>> + * | 'protocol type'=0x6558'>
> >>> + */
> >>> +#define RTE_PTYPE_TUNNEL_NVGRE 0x00004000
> >>> +/**
> >>> + * GENEVE (Generic Network Virtualization Encapsulation) tunneling
> >>> +packet
> >> type.
> >>> + *
> >>> + * Packet format:
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=17
> >>> + * | 'destination port'=6081>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=17
> >>> + * | 'destination port'=6081>
> >>> + */
> >>> +#define RTE_PTYPE_TUNNEL_GENEVE 0x00005000
> >>> +/**
> >>> + * Tunneling packet type of Teredo, VXLAN (Virtual eXtensible Local
> >>> +Area
> >>> + * Network) or GRE (Generic Routing Encapsulation) could be
> >>> +recognized as this
> >>> + * packet type, if they can not be recognized independently as of
> >>> +hardware
> >>> + * capability.
> >>> + */
> >>> +#define RTE_PTYPE_TUNNEL_GRENAT 0x00006000
> >>> +/**
> >>> + * Mask of tunneling packet types.
> >>> + */
> >>> +#define RTE_PTYPE_TUNNEL_MASK 0x0000f000
> >>> +/**
> >>> + * MAC (Media Access Control) packet type.
> >>> + * It is used for inner packet type only.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=[0x800|0x86DD]>
> >>> + */
> >>> +#define RTE_PTYPE_INNER_L2_MAC 0x00010000
> >>> +/**
> >>> + * MAC (Media Access Control) packet type with VLAN (Virtual Local
> >>> +Area
> >>> + * Network) tag.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=[0x800|0x86DD], vlan=[1-4095]> */
> >>> +#define RTE_PTYPE_INNER_L2_MAC_VLAN 0x00020000
> >>> +/**
> >>> + * Mask of inner layer 2 packet types.
> >>> + */
> >>> +#define RTE_PTYPE_INNER_L2_MASK 0x000f0000
> >>> +/**
> >>> + * IP (Internet Protocol) version 4 packet type.
> >>> + * It is used for inner packet only, and does not contain any header option.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'ihl'=5>
> >>> + */
> >>> +#define RTE_PTYPE_INNER_L3_IPV4 0x00100000
> >>> +/**
> >>> + * IP (Internet Protocol) version 4 packet type.
> >>> + * It is used for inner packet only, and contains header options.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'ihl'=[6-15], 'options'> */
> >>> +#define RTE_PTYPE_INNER_L3_IPV4_EXT 0x00200000
> >>> +/**
> >>> + * IP (Internet Protocol) version 6 packet type.
> >>> + * It is used for inner packet only, and does not contain any extension
> header.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=0x3B> */
> >>> +#define RTE_PTYPE_INNER_L3_IPV6 0x00300000
> >>> +/**
> >>> + * IP (Internet Protocol) version 4 packet type.
> >>> + * It is used for inner packet only, and may or maynot contain header
> options.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'ihl'=[5-15], <'options'>> */ #define
> >>> +RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN 0x00400000
> >>> +/**
> >>> + * IP (Internet Protocol) version 6 packet type.
> >>> + * It is used for inner packet only, and contains extension headers.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> >>> + * 'extension headers'>
> >>> + */
> >>> +#define RTE_PTYPE_INNER_L3_IPV6_EXT 0x00500000
> >>> +/**
> >>> + * IP (Internet Protocol) version 6 packet type.
> >>> + * It is used for inner packet only, and may or maynot contain
> >>> +extension
> >>> + * headers.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next
> header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
> >>> + * <'extension headers'>>
> >>> + */
> >>> +#define RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN 0x00600000
> >>> +/**
> >>> + * Mask of inner layer 3 packet types.
> >>> + */
> >>> +#define RTE_PTYPE_INNER_INNER_L3_MASK 0x00f00000
> >>> +/**
> >>> + * TCP (Transmission Control Protocol) packet type.
> >>> + * It is used for inner packet only.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=6, 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=6>
> >>> + */
> >>> +#define RTE_PTYPE_INNER_L4_TCP 0x01000000
> >>> +/**
> >>> + * UDP (User Datagram Protocol) packet type.
> >>> + * It is used for inner packet only.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=17, 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=17> */
> >>> +#define RTE_PTYPE_INNER_L4_UDP 0x02000000
> >>> +/**
> >>> + * Fragmented IP (Internet Protocol) packet type.
> >>> + * It is used for inner packet only, and may or maynot have layer 4 packet.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'MF'=1>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=44> */
> >>> +#define RTE_PTYPE_INNER_L4_FRAG 0x03000000
> >>> +/**
> >>> + * SCTP (Stream Control Transmission Protocol) packet type.
> >>> + * It is used for inner packet only.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=132, 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=132> */
> >>> +#define RTE_PTYPE_INNER_L4_SCTP 0x04000000
> >>> +/**
> >>> + * ICMP (Internet Control Message Protocol) packet type.
> >>> + * It is used for inner packet only.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'=1, 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'=1>
> >>> + */
> >>> +#define RTE_PTYPE_INNER_L4_ICMP 0x05000000
> >>> +/**
> >>> + * Non-fragmented IP (Internet Protocol) packet type.
> >>> + * It is used for inner packet only, and may or maynot have other
> >>> +unknown layer
> >>> + * 4 packet types.
> >>> + *
> >>> + * Packet format (inner only):
> >>> + * <'ether type'=0x0800
> >>> + * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
> >>> + * or,
> >>> + * <'ether type'=0x86DD
> >>> + * | 'version'=6, 'next header'!=[6|17|44|132|1]> */
> >>> +#define RTE_PTYPE_INNER_L4_NONFRAG 0x06000000
> >>> +/**
> >>> + * Mask of inner layer 4 packet types.
> >>> + */
> >>> +#define RTE_PTYPE_INNER_L4_MASK 0x0f000000
> >>> +
> >>> +/**
> >>> + * 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.
> >>> + */
> >>> +#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.
> >>> + */
> >>> +#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 */
> >>> +
> >>> /**
> >>> * Get the name of a RX offload flag
> >>> *
> >>>
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 0/7] ethdev: add support for ieee1588 timestamping
2015-07-02 15:16 4% ` [dpdk-dev] [PATCH v3 " John McNamara
2015-07-02 15:16 14% ` [dpdk-dev] [PATCH v3 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
@ 2015-07-03 8:22 0% ` Lu, Wenzhuo
2015-07-08 1:59 0% ` Fu, JingguoX
2 siblings, 0 replies; 200+ results
From: Lu, Wenzhuo @ 2015-07-03 8:22 UTC (permalink / raw)
To: Mcnamara, John, dev
Hi,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of John McNamara
> Sent: Thursday, July 2, 2015 11:16 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 0/7] ethdev: add support for ieee1588
> timestamping
>
> This patchset adds ethdev API to enable and read IEEE1588/802.1AS PTP
> timestamps from devices that support it. The following functions are added:
>
> rte_eth_timesync_enable()
> rte_eth_timesync_disable()
> rte_eth_timesync_read_rx_timestamp()
> rte_eth_timesync_read_tx_timestamp()
>
> The "ieee1588" forwarding mode in testpmd is also refactored to demonstrate
> the new API and to clean up the code.
>
> Adds support for igb, ixgbe and i40e.
>
> V3:
> * Fixed issued with version.map.
>
> V2:
> * Added i40e support.
>
> * Renamed ethdev functions from rte_eth_ieee15888_*() to
> rte_eth_timesync_*()
> since 802.1AS can be supported through the same interfaces.
>
> V1:
> * Initial version for
>
>
> John McNamara (7):
> ethdev: add support for ieee1588 timestamping
> e1000: add support for ieee1588 timestamping
> ixgbe: add support for ieee1588 timestamping
> i40e: add support for ieee1588 timestamping
> app/testpmd: refactor ieee1588 forwarding
> doc: document ieee1588 forwarding mode
> abi: announce mbuf addition for ieee1588 in DPDK 2.2
>
> app/test-pmd/ieee1588fwd.c | 466 ++--------------------------
> doc/guides/rel_notes/abi.rst | 5 +
> doc/guides/testpmd_app_ug/run_app.rst | 2 +-
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +
> drivers/net/e1000/igb_ethdev.c | 115 +++++++
> drivers/net/i40e/i40e_ethdev.c | 143 +++++++++
> drivers/net/i40e/i40e_rxtx.c | 39 ++-
> drivers/net/ixgbe/ixgbe_ethdev.c | 122 ++++++++
> lib/librte_ether/rte_ethdev.c | 70 ++++-
> lib/librte_ether/rte_ethdev.h | 90 +++++-
> lib/librte_ether/rte_ether_version.map | 4 +
> 11 files changed, 615 insertions(+), 443 deletions(-)
>
> --
> 1.8.1.4
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v9 00/19] unified packet type
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
` (18 preceding siblings ...)
2015-06-23 16:13 0% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Ananyev, Konstantin
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 01/19] mbuf: redefine packet_type in rte_mbuf Helin Zhang
` (18 more replies)
19 siblings, 19 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
Currently only 6 bits which are stored in ol_flags are used to indicate the
packet types. This is not enough, as some NIC hardware can recognize quite
a lot of packet types, e.g i40e hardware can recognize more than 150 packet
types. Hiding those packet types hides hardware offload capabilities which
could be quite useful for improving performance and for end users.
So an unified packet types are needed to support all possible PMDs. A 16 bits
packet_type in mbuf structure can be changed to 32 bits and used for this
purpose. In addition, all packet types stored in ol_flag field should be
deleted at all, and 6 bits of ol_flags can be save as the benifit.
Initially, 32 bits of packet_type can be divided into several sub fields to
indicate different packet type information of a packet. The initial design
is to divide those bits into fields for L2 types, L3 types, L4 types, tunnel
types, inner L2 types, inner L3 types and inner L4 types. All PMDs should
translate the offloaded packet types into these 7 fields of information, for
user applications.
To avoid breaking ABI compatibility, currently all the code changes for
unified packet type are disabled at compile time by default. Users can enable
it manually by defining the macro of RTE_NEXT_ABI. The code changes will be
valid by default in a future release, and the old version will be deleted
accordingly, after the ABI change process is done.
Note that this patch set should be integrated after another patch set for
'[PATCH v3 0/7] support i40e QinQ stripping and insertion', to clearly solve
the conflict during integration. As both patch sets modified 'struct rte_mbuf',
and the final layout of the 'struct rte_mbuf' is key to vectorized ixgbe PMD.
Its v8 version was acked by Konstantin Ananyev <konstantin.ananyev@intel.com>
v2 changes:
* Enlarged the packet_type field from 16 bits to 32 bits.
* Redefined the packet type sub-fields.
* Updated the 'struct rte_kni_mbuf' for KNI according to the mbuf changes.
* Used redefined packet types and enlarged packet_type field for all PMDs
and corresponding applications.
* Removed changes in bond and its relevant application, as there is no need
at all according to the recent bond changes.
v3 changes:
* Put the mbuf layout changes into a single patch.
* Put vector ixgbe changes right after mbuf changes.
* Disabled vector ixgbe PMD by default, as mbuf layout changed, and then
re-enabled it after vector ixgbe PMD updated.
* Put the definitions of unified packet type into a single patch.
* Minor bug fixes and enhancements in l3fwd example.
v4 changes:
* Added detailed description of each packet types.
* Supported unified packet type of fm10k.
* Added printing logs of packet types of each received packet for rxonly
mode in testpmd.
* Removed several useless code lines which block packet type unification from
app/test/packet_burst_generator.c.
v5 changes:
* Added more detailed description for each packet types, together with examples.
* Rolled back the macro definitions of RX packet flags, for ABI compitability.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
* Integrated with patch set for '[PATCH v3 0/7] support i40e QinQ stripping
and insertion', to clearly solve the conflicts during merging.
v8 changes:
* Moved the field of 'vlan_tci_outer' in 'struct rte_mbuf' to the end of the 1st
cache line, to avoid breaking any vectorized PMD storing, as fields of
'packet_type, pkt_len, data_len, vlan_tci, rss' should be in an contiguous 128
bits.
v9 changes:
* Put the mbuf changes and vector PMD changes together, as they are
tightly relevant.
* Renamed MAC to ETHER in packet type names.
* Corrected the packet type explanation of RTE_PTYPE_L2_ETHER.
* Reworked newly added cxgbe driver and tep_termination example application to
support unified packet type, which is disabled by default.
Helin Zhang (19):
mbuf: redefine packet_type in rte_mbuf
mbuf: add definitions of unified packet types
e1000: replace bit mask based packet type with unified packet type
ixgbe: replace bit mask based packet type with unified packet type
i40e: replace bit mask based packet type with unified packet type
enic: replace bit mask based packet type with unified packet type
vmxnet3: replace bit mask based packet type with unified packet type
fm10k: replace bit mask based packet type with unified packet type
cxgbe: replace bit mask based packet type with unified packet type
app/test-pipeline: replace bit mask based packet type with unified
packet type
app/testpmd: replace bit mask based packet type with unified packet
type
app/test: Remove useless code
examples/ip_fragmentation: replace bit mask based packet type with
unified packet type
examples/ip_reassembly: replace bit mask based packet type with
unified packet type
examples/l3fwd-acl: replace bit mask based packet type with unified
packet type
examples/l3fwd-power: replace bit mask based packet type with unified
packet type
examples/l3fwd: replace bit mask based packet type with unified packet
type
examples/tep_termination: replace bit mask based packet type with
unified packet type
mbuf: remove old packet type bit masks
app/test-pipeline/pipeline_hash.c | 13 +
app/test-pmd/csumonly.c | 14 +
app/test-pmd/rxonly.c | 183 +++++++
app/test/packet_burst_generator.c | 6 +-
drivers/net/cxgbe/sge.c | 8 +
drivers/net/e1000/igb_rxtx.c | 104 ++++
drivers/net/enic/enic_main.c | 26 +
drivers/net/fm10k/fm10k_rxtx.c | 27 +
drivers/net/i40e/i40e_rxtx.c | 554 +++++++++++++++++++++
drivers/net/ixgbe/ixgbe_rxtx.c | 163 ++++++
drivers/net/ixgbe/ixgbe_rxtx_vec.c | 75 ++-
drivers/net/vmxnet3/vmxnet3_rxtx.c | 8 +
examples/ip_fragmentation/main.c | 9 +
examples/ip_reassembly/main.c | 9 +
examples/l3fwd-acl/main.c | 29 +-
examples/l3fwd-power/main.c | 8 +
examples/l3fwd/main.c | 123 ++++-
examples/tep_termination/vxlan.c | 4 +
.../linuxapp/eal/include/exec-env/rte_kni_common.h | 6 +
lib/librte_mbuf/rte_mbuf.c | 4 +
lib/librte_mbuf/rte_mbuf.h | 516 +++++++++++++++++++
21 files changed, 1876 insertions(+), 13 deletions(-)
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 01/19] mbuf: redefine packet_type in rte_mbuf
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
@ 2015-07-03 8:32 3% ` Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 02/19] mbuf: add definitions of unified packet types Helin Zhang
` (17 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
In order to unify the packet type, the field of 'packet_type' in 'struct rte_mbuf'
needs to be extended from 16 to 32 bits. Accordingly, some fields in 'struct rte_mbuf'
are re-organized to support this change for Vector PMD. As 'struct rte_kni_mbuf' for
KNI should be right mapped to 'struct rte_mbuf', it should be modified accordingly.
In ixgbe PMD driver, corresponding changes are added for the mbuf changes, especially
the bit masks of packet type for 'ol_flags' are replaced by unified packet type. In
addition, more packet types (UDP, TCP and SCTP) are supported in vectorized ixgbe PMD.
To avoid breaking ABI compatibility, all the changes would be enabled by RTE_NEXT_ABI,
which is disabled by default.
Note that around 2% performance drop (64B) was observed of doing 4 ports (1 port per
82599 card) IO forwarding on the same SNB core.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Signed-off-by: Cunming Liang <cunming.liang@intel.com>
---
drivers/net/ixgbe/ixgbe_rxtx_vec.c | 75 +++++++++++++++++++++-
.../linuxapp/eal/include/exec-env/rte_kni_common.h | 6 ++
lib/librte_mbuf/rte_mbuf.h | 26 ++++++++
3 files changed, 105 insertions(+), 2 deletions(-)
v2 changes:
* Enlarged the packet_type field from 16 bits to 32 bits.
* Redefined the packet type sub-fields.
* Updated the 'struct rte_kni_mbuf' for KNI according to the mbuf changes.
v3 changes:
* Put the mbuf layout changes into a single patch.
* Disabled vector ixgbe PMD by default, as mbuf layout changed.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
* Integrated with changes of QinQ stripping/insertion.
v8 changes:
* Moved the field of 'vlan_tci_outer' in 'struct rte_mbuf' to the end
of the 1st cache line, to avoid breaking any vectorized PMD storing.
v9 changes:
* Put the mbuf changes and vector PMD changes together, as they are
tightly relevant.
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec.c b/drivers/net/ixgbe/ixgbe_rxtx_vec.c
index abd10f6..ccea7cd 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec.c
@@ -134,6 +134,12 @@ ixgbe_rxq_rearm(struct ixgbe_rx_queue *rxq)
*/
#ifdef RTE_IXGBE_RX_OLFLAGS_ENABLE
+#ifdef RTE_NEXT_ABI
+#define OLFLAGS_MASK_V (((uint64_t)PKT_RX_VLAN_PKT << 48) | \
+ ((uint64_t)PKT_RX_VLAN_PKT << 32) | \
+ ((uint64_t)PKT_RX_VLAN_PKT << 16) | \
+ ((uint64_t)PKT_RX_VLAN_PKT))
+#else
#define OLFLAGS_MASK ((uint16_t)(PKT_RX_VLAN_PKT | PKT_RX_IPV4_HDR |\
PKT_RX_IPV4_HDR_EXT | PKT_RX_IPV6_HDR |\
PKT_RX_IPV6_HDR_EXT))
@@ -142,11 +148,26 @@ ixgbe_rxq_rearm(struct ixgbe_rx_queue *rxq)
((uint64_t)OLFLAGS_MASK << 16) | \
((uint64_t)OLFLAGS_MASK))
#define PTYPE_SHIFT (1)
+#endif /* RTE_NEXT_ABI */
+
#define VTAG_SHIFT (3)
static inline void
desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
{
+#ifdef RTE_NEXT_ABI
+ __m128i vtag0, vtag1;
+ union {
+ uint16_t e[4];
+ uint64_t dword;
+ } vol;
+
+ vtag0 = _mm_unpackhi_epi16(descs[0], descs[1]);
+ vtag1 = _mm_unpackhi_epi16(descs[2], descs[3]);
+ vtag1 = _mm_unpacklo_epi32(vtag0, vtag1);
+ vtag1 = _mm_srli_epi16(vtag1, VTAG_SHIFT);
+ vol.dword = _mm_cvtsi128_si64(vtag1) & OLFLAGS_MASK_V;
+#else
__m128i ptype0, ptype1, vtag0, vtag1;
union {
uint16_t e[4];
@@ -166,6 +187,7 @@ desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
ptype1 = _mm_or_si128(ptype1, vtag1);
vol.dword = _mm_cvtsi128_si64(ptype1) & OLFLAGS_MASK_V;
+#endif /* RTE_NEXT_ABI */
rx_pkts[0]->ol_flags = vol.e[0];
rx_pkts[1]->ol_flags = vol.e[1];
@@ -196,6 +218,18 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
int pos;
uint64_t var;
__m128i shuf_msk;
+#ifdef RTE_NEXT_ABI
+ __m128i crc_adjust = _mm_set_epi16(
+ 0, 0, 0, /* ignore non-length fields */
+ -rxq->crc_len, /* sub crc on data_len */
+ 0, /* ignore high-16bits of pkt_len */
+ -rxq->crc_len, /* sub crc on pkt_len */
+ 0, 0 /* ignore pkt_type field */
+ );
+ __m128i dd_check, eop_check;
+ __m128i desc_mask = _mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFF07F0);
+#else
__m128i crc_adjust = _mm_set_epi16(
0, 0, 0, 0, /* ignore non-length fields */
0, /* ignore high-16bits of pkt_len */
@@ -204,6 +238,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
0 /* ignore pkt_type field */
);
__m128i dd_check, eop_check;
+#endif /* RTE_NEXT_ABI */
if (unlikely(nb_pkts < RTE_IXGBE_VPMD_RX_BURST))
return 0;
@@ -232,6 +267,18 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
eop_check = _mm_set_epi64x(0x0000000200000002LL, 0x0000000200000002LL);
/* mask to shuffle from desc. to mbuf */
+#ifdef RTE_NEXT_ABI
+ shuf_msk = _mm_set_epi8(
+ 7, 6, 5, 4, /* octet 4~7, 32bits rss */
+ 15, 14, /* octet 14~15, low 16 bits vlan_macip */
+ 13, 12, /* octet 12~13, 16 bits data_len */
+ 0xFF, 0xFF, /* skip high 16 bits pkt_len, zero out */
+ 13, 12, /* octet 12~13, low 16 bits pkt_len */
+ 0xFF, 0xFF, /* skip high 16 bits pkt_type */
+ 1, /* octet 1, 8 bits pkt_type field */
+ 0 /* octet 0, 4 bits offset 4 pkt_type field */
+ );
+#else
shuf_msk = _mm_set_epi8(
7, 6, 5, 4, /* octet 4~7, 32bits rss */
0xFF, 0xFF, /* skip high 16 bits vlan_macip, zero out */
@@ -241,18 +288,28 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
13, 12, /* octet 12~13, 16 bits data_len */
0xFF, 0xFF /* skip pkt_type field */
);
+#endif /* RTE_NEXT_ABI */
/* Cache is empty -> need to scan the buffer rings, but first move
* the next 'n' mbufs into the cache */
sw_ring = &rxq->sw_ring[rxq->rx_tail];
- /*
- * A. load 4 packet in one loop
+#ifdef RTE_NEXT_ABI
+ /* A. load 4 packet in one loop
+ * [A*. mask out 4 unused dirty field in desc]
* B. copy 4 mbuf point from swring to rx_pkts
* C. calc the number of DD bits among the 4 packets
* [C*. extract the end-of-packet bit, if requested]
* D. fill info. from desc to mbuf
*/
+#else
+ /* A. load 4 packet in one loop
+ * B. copy 4 mbuf point from swring to rx_pkts
+ * C. calc the number of DD bits among the 4 packets
+ * [C*. extract the end-of-packet bit, if requested]
+ * D. fill info. from desc to mbuf
+ */
+#endif /* RTE_NEXT_ABI */
for (pos = 0, nb_pkts_recd = 0; pos < RTE_IXGBE_VPMD_RX_BURST;
pos += RTE_IXGBE_DESCS_PER_LOOP,
rxdp += RTE_IXGBE_DESCS_PER_LOOP) {
@@ -289,6 +346,16 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
/* B.2 copy 2 mbuf point into rx_pkts */
_mm_storeu_si128((__m128i *)&rx_pkts[pos+2], mbp2);
+#ifdef RTE_NEXT_ABI
+ /* A* mask out 0~3 bits RSS type */
+ descs[3] = _mm_and_si128(descs[3], desc_mask);
+ descs[2] = _mm_and_si128(descs[2], desc_mask);
+
+ /* A* mask out 0~3 bits RSS type */
+ descs[1] = _mm_and_si128(descs[1], desc_mask);
+ descs[0] = _mm_and_si128(descs[0], desc_mask);
+#endif /* RTE_NEXT_ABI */
+
/* avoid compiler reorder optimization */
rte_compiler_barrier();
@@ -301,7 +368,11 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
/* C.1 4=>2 filter staterr info only */
sterr_tmp1 = _mm_unpackhi_epi32(descs[1], descs[0]);
+#ifdef RTE_NEXT_ABI
+ /* set ol_flags with vlan packet type */
+#else
/* set ol_flags with packet type and vlan tag */
+#endif /* RTE_NEXT_ABI */
desc_to_olflags_v(descs, &rx_pkts[pos]);
/* D.2 pkt 3,4 set in_port/nb_seg and remove crc */
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
index 1e55c2d..e9f38bd 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
@@ -117,9 +117,15 @@ struct rte_kni_mbuf {
uint16_t data_off; /**< Start address of data in segment buffer. */
char pad1[4];
uint64_t ol_flags; /**< Offload features. */
+#ifdef RTE_NEXT_ABI
+ char pad2[4];
+ uint32_t pkt_len; /**< Total pkt len: sum of all segment data_len. */
+ uint16_t data_len; /**< Amount of data in segment buffer. */
+#else
char pad2[2];
uint16_t data_len; /**< Amount of data in segment buffer. */
uint32_t pkt_len; /**< Total pkt len: sum of all segment data_len. */
+#endif
/* fields on second cache line */
char pad3[8] __attribute__((__aligned__(RTE_CACHE_LINE_SIZE)));
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 80419df..ac29da3 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -276,6 +276,28 @@ 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.
+ */
+ union {
+ uint32_t packet_type; /**< L2/L3/L4 and tunnel information. */
+ struct {
+ uint32_t l2_type:4; /**< (Outer) L2 type. */
+ uint32_t l3_type:4; /**< (Outer) L3 type. */
+ uint32_t l4_type:4; /**< (Outer) L4 type. */
+ uint32_t tun_type:4; /**< Tunnel type. */
+ uint32_t inner_l2_type:4; /**< Inner L2 type. */
+ uint32_t inner_l3_type:4; /**< Inner L3 type. */
+ uint32_t inner_l4_type:4; /**< Inner L4 type. */
+ };
+ };
+
+ 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
@@ -287,6 +309,7 @@ struct rte_mbuf {
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 {
@@ -307,6 +330,9 @@ struct rte_mbuf {
} 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;
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 02/19] mbuf: add definitions of unified packet types
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 01/19] mbuf: redefine packet_type in rte_mbuf Helin Zhang
@ 2015-07-03 8:32 3% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 03/19] e1000: replace bit mask based packet type with unified packet type Helin Zhang
` (16 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
As there are only 6 bit flags in ol_flags for indicating packet
types, which is not enough to describe all the possible packet
types hardware can recognize. For example, i40e hardware can
recognize more than 150 packet types. Unified packet type is
composed of L2 type, L3 type, L4 type, tunnel type, inner L2 type,
inner L3 type and inner L4 type fields, and can be stored in
'struct rte_mbuf' of 32 bits field 'packet_type'.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
lib/librte_mbuf/rte_mbuf.h | 486 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 486 insertions(+)
v3 changes:
* Put the definitions of unified packet type into a single patch.
v4 changes:
* Added detailed description of each packet types.
v5 changes:
* Re-worded the commit logs.
* Added more detailed description for all packet types, together with examples.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
v9 changes:
* Renamed MAC to ETHER in packet type names.
* Corrected the packet type explanation of RTE_PTYPE_L2_ETHER.
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index ac29da3..3a17d95 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -202,6 +202,492 @@ extern "C" {
/* 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.
+ * - Bit 3:0 is for L2 types.
+ * - Bit 7:4 is for L3 or outer L3 (for tunneling case) types.
+ * - Bit 11:8 is for L4 or outer L4 (for tunneling case) types.
+ * - Bit 15:12 is for tunnel types.
+ * - Bit 19:16 is for inner L2 types.
+ * - Bit 23:20 is for inner L3 types.
+ * - Bit 27:24 is for inner L4 types.
+ * - Bit 31:28 is reserved.
+ *
+ * To be compatible with Vector PMD, RTE_PTYPE_L3_IPV4, RTE_PTYPE_L3_IPV4_EXT,
+ * RTE_PTYPE_L3_IPV6, RTE_PTYPE_L3_IPV6_EXT, RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP
+ * and RTE_PTYPE_L4_SCTP should be kept as below in a contiguous 7 bits.
+ *
+ * Note that L3 types values are selected for checking IPV4/IPV6 header from
+ * performance point of view. Reading annotations of RTE_ETH_IS_IPV4_HDR and
+ * RTE_ETH_IS_IPV6_HDR is needed for any future changes of L3 type values.
+ *
+ * Note that the packet types of the same packet recognized by different
+ * hardware may be different, as different hardware may have different
+ * capability of packet type recognition.
+ *
+ * examples:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=0x29
+ * | 'version'=6, 'next header'=0x3A
+ * | 'ICMPv6 header'>
+ * will be recognized on i40e hardware as packet type combination of,
+ * RTE_PTYPE_L2_ETHER |
+ * RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ * RTE_PTYPE_TUNNEL_IP |
+ * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_INNER_L4_ICMP.
+ *
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x2F
+ * | 'GRE header'
+ * | 'version'=6, 'next header'=0x11
+ * | 'UDP header'>
+ * will be recognized on i40e hardware as packet type combination of,
+ * RTE_PTYPE_L2_ETHER |
+ * RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_TUNNEL_GRENAT |
+ * RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ * RTE_PTYPE_INNER_L4_UDP.
+ */
+#define RTE_PTYPE_UNKNOWN 0x00000000
+/**
+ * Ethernet packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=[0x0800|0x86DD]>
+ */
+#define RTE_PTYPE_L2_ETHER 0x00000001
+/**
+ * Ethernet packet type for time sync.
+ *
+ * Packet format:
+ * <'ether type'=0x88F7>
+ */
+#define RTE_PTYPE_L2_ETHER_TIMESYNC 0x00000002
+/**
+ * ARP (Address Resolution Protocol) packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0806>
+ */
+#define RTE_PTYPE_L2_ETHER_ARP 0x00000003
+/**
+ * LLDP (Link Layer Discovery Protocol) packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x88CC>
+ */
+#define RTE_PTYPE_L2_ETHER_LLDP 0x00000004
+/**
+ * Mask of layer 2 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L2_MASK 0x0000000f
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and does not contain any
+ * header option.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=5>
+ */
+#define RTE_PTYPE_L3_IPV4 0x00000010
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and contains header
+ * options.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[6-15], 'options'>
+ */
+#define RTE_PTYPE_L3_IPV4_EXT 0x00000030
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and does not contain any
+ * extension header.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x3B>
+ */
+#define RTE_PTYPE_L3_IPV6 0x00000040
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for outer packet for tunneling cases, and may or maynot contain
+ * header options.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[5-15], <'options'>>
+ */
+#define RTE_PTYPE_L3_IPV4_EXT_UNKNOWN 0x00000090
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and contains extension
+ * headers.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * 'extension headers'>
+ */
+#define RTE_PTYPE_L3_IPV6_EXT 0x000000c0
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for outer packet for tunneling cases, and may or maynot contain
+ * extension headers.
+ *
+ * Packet format:
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * <'extension headers'>>
+ */
+#define RTE_PTYPE_L3_IPV6_EXT_UNKNOWN 0x000000e0
+/**
+ * Mask of layer 3 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L3_MASK 0x000000f0
+/**
+ * TCP (Transmission Control Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=6, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=6>
+ */
+#define RTE_PTYPE_L4_TCP 0x00000100
+/**
+ * UDP (User Datagram Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17>
+ */
+#define RTE_PTYPE_L4_UDP 0x00000200
+/**
+ * Fragmented IP (Internet Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * It refers to those packets of any IP types, which can be recognized as
+ * fragmented. A fragmented packet cannot be recognized as any other L4 types
+ * (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP,
+ * RTE_PTYPE_L4_NONFRAG).
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'MF'=1>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=44>
+ */
+#define RTE_PTYPE_L4_FRAG 0x00000300
+/**
+ * SCTP (Stream Control Transmission Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=132, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=132>
+ */
+#define RTE_PTYPE_L4_SCTP 0x00000400
+/**
+ * ICMP (Internet Control Message Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=1, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=1>
+ */
+#define RTE_PTYPE_L4_ICMP 0x00000500
+/**
+ * Non-fragmented IP (Internet Protocol) packet type.
+ * It is used for outer packet for tunneling cases.
+ *
+ * It refers to those packets of any IP types, while cannot be recognized as
+ * any of above L4 types (RTE_PTYPE_L4_TCP, RTE_PTYPE_L4_UDP,
+ * RTE_PTYPE_L4_FRAG, RTE_PTYPE_L4_SCTP, RTE_PTYPE_L4_ICMP).
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'!=[6|17|44|132|1]>
+ */
+#define RTE_PTYPE_L4_NONFRAG 0x00000600
+/**
+ * Mask of layer 4 packet types.
+ * It is used for outer packet for tunneling cases.
+ */
+#define RTE_PTYPE_L4_MASK 0x00000f00
+/**
+ * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=[4|41]>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[4|41]>
+ */
+#define RTE_PTYPE_TUNNEL_IP 0x00001000
+/**
+ * GRE (Generic Routing Encapsulation) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=47>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=47>
+ */
+#define RTE_PTYPE_TUNNEL_GRE 0x00002000
+/**
+ * VXLAN (Virtual eXtensible Local Area Network) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17
+ * | 'destination port'=4798>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17
+ * | 'destination port'=4798>
+ */
+#define RTE_PTYPE_TUNNEL_VXLAN 0x00003000
+/**
+ * NVGRE (Network Virtualization using Generic Routing Encapsulation) tunneling
+ * packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=47
+ * | 'protocol type'=0x6558>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=47
+ * | 'protocol type'=0x6558'>
+ */
+#define RTE_PTYPE_TUNNEL_NVGRE 0x00004000
+/**
+ * GENEVE (Generic Network Virtualization Encapsulation) tunneling packet type.
+ *
+ * Packet format:
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17
+ * | 'destination port'=6081>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17
+ * | 'destination port'=6081>
+ */
+#define RTE_PTYPE_TUNNEL_GENEVE 0x00005000
+/**
+ * Tunneling packet type of Teredo, VXLAN (Virtual eXtensible Local Area
+ * Network) or GRE (Generic Routing Encapsulation) could be recognized as this
+ * packet type, if they can not be recognized independently as of hardware
+ * capability.
+ */
+#define RTE_PTYPE_TUNNEL_GRENAT 0x00006000
+/**
+ * Mask of tunneling packet types.
+ */
+#define RTE_PTYPE_TUNNEL_MASK 0x0000f000
+/**
+ * Ethernet packet type.
+ * It is used for inner packet type only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=[0x800|0x86DD]>
+ */
+#define RTE_PTYPE_INNER_L2_ETHER 0x00010000
+/**
+ * Ethernet packet type with VLAN (Virtual Local Area Network) tag.
+ *
+ * Packet format (inner only):
+ * <'ether type'=[0x800|0x86DD], vlan=[1-4095]>
+ */
+#define RTE_PTYPE_INNER_L2_ETHER_VLAN 0x00020000
+/**
+ * Mask of inner layer 2 packet types.
+ */
+#define RTE_PTYPE_INNER_L2_MASK 0x000f0000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and does not contain any header option.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=5>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4 0x00100000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and contains header options.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[6-15], 'options'>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4_EXT 0x00200000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and does not contain any extension header.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=0x3B>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6 0x00300000
+/**
+ * IP (Internet Protocol) version 4 packet type.
+ * It is used for inner packet only, and may or maynot contain header options.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'ihl'=[5-15], <'options'>>
+ */
+#define RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN 0x00400000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and contains extension headers.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * 'extension headers'>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6_EXT 0x00500000
+/**
+ * IP (Internet Protocol) version 6 packet type.
+ * It is used for inner packet only, and may or maynot contain extension
+ * headers.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=[0x3B|0x0|0x2B|0x2C|0x32|0x33|0x3C|0x87],
+ * <'extension headers'>>
+ */
+#define RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN 0x00600000
+/**
+ * Mask of inner layer 3 packet types.
+ */
+#define RTE_PTYPE_INNER_INNER_L3_MASK 0x00f00000
+/**
+ * TCP (Transmission Control Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=6, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=6>
+ */
+#define RTE_PTYPE_INNER_L4_TCP 0x01000000
+/**
+ * UDP (User Datagram Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=17, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=17>
+ */
+#define RTE_PTYPE_INNER_L4_UDP 0x02000000
+/**
+ * Fragmented IP (Internet Protocol) packet type.
+ * It is used for inner packet only, and may or maynot have layer 4 packet.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'MF'=1>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=44>
+ */
+#define RTE_PTYPE_INNER_L4_FRAG 0x03000000
+/**
+ * SCTP (Stream Control Transmission Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=132, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=132>
+ */
+#define RTE_PTYPE_INNER_L4_SCTP 0x04000000
+/**
+ * ICMP (Internet Control Message Protocol) packet type.
+ * It is used for inner packet only.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'=1, 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'=1>
+ */
+#define RTE_PTYPE_INNER_L4_ICMP 0x05000000
+/**
+ * Non-fragmented IP (Internet Protocol) packet type.
+ * It is used for inner packet only, and may or maynot have other unknown layer
+ * 4 packet types.
+ *
+ * Packet format (inner only):
+ * <'ether type'=0x0800
+ * | 'version'=4, 'protocol'!=[6|17|132|1], 'MF'=0>
+ * or,
+ * <'ether type'=0x86DD
+ * | 'version'=6, 'next header'!=[6|17|44|132|1]>
+ */
+#define RTE_PTYPE_INNER_L4_NONFRAG 0x06000000
+/**
+ * Mask of inner layer 4 packet types.
+ */
+#define RTE_PTYPE_INNER_L4_MASK 0x0f000000
+
+/**
+ * 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.
+ */
+#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.
+ */
+#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 */
+
/**
* Get the name of a RX offload flag
*
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 04/19] ixgbe: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (2 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 03/19] e1000: replace bit mask based packet type with unified packet type Helin Zhang
@ 2015-07-03 8:32 3% ` Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 05/19] i40e: " Helin Zhang
` (14 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet type among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Note that around 2.5% performance drop (64B) was observed of doing
4 ports (1 port per 82599 card) IO forwarding on the same SNB core.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/ixgbe/ixgbe_rxtx.c | 163 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 163 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
v9 changes:
* Renamed MAC to ETHER in packet type names.
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index a211096..1455e54 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -860,6 +860,110 @@ end_of_tx:
* RX functions
*
**********************************************************************/
+#ifdef RTE_NEXT_ABI
+#define IXGBE_PACKET_TYPE_IPV4 0X01
+#define IXGBE_PACKET_TYPE_IPV4_TCP 0X11
+#define IXGBE_PACKET_TYPE_IPV4_UDP 0X21
+#define IXGBE_PACKET_TYPE_IPV4_SCTP 0X41
+#define IXGBE_PACKET_TYPE_IPV4_EXT 0X03
+#define IXGBE_PACKET_TYPE_IPV4_EXT_SCTP 0X43
+#define IXGBE_PACKET_TYPE_IPV6 0X04
+#define IXGBE_PACKET_TYPE_IPV6_TCP 0X14
+#define IXGBE_PACKET_TYPE_IPV6_UDP 0X24
+#define IXGBE_PACKET_TYPE_IPV6_EXT 0X0C
+#define IXGBE_PACKET_TYPE_IPV6_EXT_TCP 0X1C
+#define IXGBE_PACKET_TYPE_IPV6_EXT_UDP 0X2C
+#define IXGBE_PACKET_TYPE_IPV4_IPV6 0X05
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_TCP 0X15
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_UDP 0X25
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT 0X0D
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_TCP 0X1D
+#define IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_UDP 0X2D
+#define IXGBE_PACKET_TYPE_MAX 0X80
+#define IXGBE_PACKET_TYPE_MASK 0X7F
+#define IXGBE_PACKET_TYPE_SHIFT 0X04
+static inline uint32_t
+ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
+{
+ static const uint32_t
+ ptype_table[IXGBE_PACKET_TYPE_MAX] __rte_cache_aligned = {
+ [IXGBE_PACKET_TYPE_IPV4] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4,
+ [IXGBE_PACKET_TYPE_IPV4_EXT] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [IXGBE_PACKET_TYPE_IPV6] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6,
+ [IXGBE_PACKET_TYPE_IPV6_EXT] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT,
+ [IXGBE_PACKET_TYPE_IPV4_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV6_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV6_EXT_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_TCP,
+ [IXGBE_PACKET_TYPE_IPV4_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV6_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV6_EXT_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_IPV6_EXT_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_UDP,
+ [IXGBE_PACKET_TYPE_IPV4_SCTP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP,
+ [IXGBE_PACKET_TYPE_IPV4_EXT_SCTP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_SCTP,
+ };
+ if (unlikely(pkt_info & IXGBE_RXDADV_PKTTYPE_ETQF))
+ return RTE_PTYPE_UNKNOWN;
+
+ pkt_info = (pkt_info >> IXGBE_PACKET_TYPE_SHIFT) &
+ IXGBE_PACKET_TYPE_MASK;
+
+ return ptype_table[pkt_info];
+}
+
+static inline uint64_t
+ixgbe_rxd_pkt_info_to_pkt_flags(uint16_t pkt_info)
+{
+ static uint64_t ip_rss_types_map[16] __rte_cache_aligned = {
+ 0, PKT_RX_RSS_HASH, PKT_RX_RSS_HASH, PKT_RX_RSS_HASH,
+ 0, PKT_RX_RSS_HASH, 0, PKT_RX_RSS_HASH,
+ PKT_RX_RSS_HASH, 0, 0, 0,
+ 0, 0, 0, PKT_RX_FDIR,
+ };
+#ifdef RTE_LIBRTE_IEEE1588
+ static uint64_t ip_pkt_etqf_map[8] = {
+ 0, 0, 0, PKT_RX_IEEE1588_PTP,
+ 0, 0, 0, 0,
+ };
+
+ if (likely(pkt_info & IXGBE_RXDADV_PKTTYPE_ETQF))
+ return ip_pkt_etqf_map[(pkt_info >> 4) & 0X07] |
+ ip_rss_types_map[pkt_info & 0XF];
+ else
+ return ip_rss_types_map[pkt_info & 0XF];
+#else
+ return ip_rss_types_map[pkt_info & 0XF];
+#endif
+}
+#else /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
{
@@ -895,6 +999,7 @@ rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
#endif
return pkt_flags | ip_rss_types_map[hl_tp_rs & 0xF];
}
+#endif /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_status_to_pkt_flags(uint32_t rx_status)
@@ -950,7 +1055,13 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
struct rte_mbuf *mb;
uint16_t pkt_len;
uint64_t pkt_flags;
+#ifdef RTE_NEXT_ABI
+ int nb_dd;
+ uint32_t s[LOOK_AHEAD];
+ uint16_t pkt_info[LOOK_AHEAD];
+#else
int s[LOOK_AHEAD], nb_dd;
+#endif /* RTE_NEXT_ABI */
int i, j, nb_rx = 0;
@@ -973,6 +1084,12 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
for (j = LOOK_AHEAD-1; j >= 0; --j)
s[j] = rxdp[j].wb.upper.status_error;
+#ifdef RTE_NEXT_ABI
+ for (j = LOOK_AHEAD-1; j >= 0; --j)
+ pkt_info[j] = rxdp[j].wb.lower.lo_dword.
+ hs_rss.pkt_info;
+#endif /* RTE_NEXT_ABI */
+
/* Compute how many status bits were set */
nb_dd = 0;
for (j = 0; j < LOOK_AHEAD; ++j)
@@ -989,12 +1106,22 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
mb->vlan_tci = rte_le_to_cpu_16(rxdp[j].wb.upper.vlan);
/* convert descriptor fields to rte mbuf flags */
+#ifdef RTE_NEXT_ABI
+ pkt_flags = rx_desc_status_to_pkt_flags(s[j]);
+ pkt_flags |= rx_desc_error_to_pkt_flags(s[j]);
+ pkt_flags |=
+ ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info[j]);
+ mb->ol_flags = pkt_flags;
+ mb->packet_type =
+ ixgbe_rxd_pkt_info_to_pkt_type(pkt_info[j]);
+#else /* RTE_NEXT_ABI */
pkt_flags = rx_desc_hlen_type_rss_to_pkt_flags(
rxdp[j].wb.lower.lo_dword.data);
/* reuse status field from scan list */
pkt_flags |= rx_desc_status_to_pkt_flags(s[j]);
pkt_flags |= rx_desc_error_to_pkt_flags(s[j]);
mb->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
mb->hash.rss = rxdp[j].wb.lower.hi_dword.rss;
@@ -1211,7 +1338,11 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
union ixgbe_adv_rx_desc rxd;
uint64_t dma_addr;
uint32_t staterr;
+#ifdef RTE_NEXT_ABI
+ uint32_t pkt_info;
+#else
uint32_t hlen_type_rss;
+#endif
uint16_t pkt_len;
uint16_t rx_id;
uint16_t nb_rx;
@@ -1329,6 +1460,19 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
rxm->data_len = pkt_len;
rxm->port = rxq->port_id;
+#ifdef RTE_NEXT_ABI
+ pkt_info = rte_le_to_cpu_32(rxd.wb.lower.lo_dword.hs_rss.
+ pkt_info);
+ /* Only valid if PKT_RX_VLAN_PKT set in pkt_flags */
+ rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan);
+
+ pkt_flags = rx_desc_status_to_pkt_flags(staterr);
+ pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
+ pkt_flags = pkt_flags |
+ ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info);
+ rxm->ol_flags = pkt_flags;
+ rxm->packet_type = ixgbe_rxd_pkt_info_to_pkt_type(pkt_info);
+#else /* RTE_NEXT_ABI */
hlen_type_rss = rte_le_to_cpu_32(rxd.wb.lower.lo_dword.data);
/* Only valid if PKT_RX_VLAN_PKT set in pkt_flags */
rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan);
@@ -1337,6 +1481,7 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
rxm->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
rxm->hash.rss = rxd.wb.lower.hi_dword.rss;
@@ -1410,6 +1555,23 @@ ixgbe_fill_cluster_head_buf(
uint8_t port_id,
uint32_t staterr)
{
+#ifdef RTE_NEXT_ABI
+ uint16_t pkt_info;
+ uint64_t pkt_flags;
+
+ head->port = port_id;
+
+ /* The vlan_tci field is only valid when PKT_RX_VLAN_PKT is
+ * set in the pkt_flags field.
+ */
+ head->vlan_tci = rte_le_to_cpu_16(desc->wb.upper.vlan);
+ pkt_info = rte_le_to_cpu_32(desc->wb.lower.lo_dword.hs_rss.pkt_info);
+ pkt_flags = rx_desc_status_to_pkt_flags(staterr);
+ pkt_flags |= rx_desc_error_to_pkt_flags(staterr);
+ pkt_flags |= ixgbe_rxd_pkt_info_to_pkt_flags(pkt_info);
+ head->ol_flags = pkt_flags;
+ head->packet_type = ixgbe_rxd_pkt_info_to_pkt_type(pkt_info);
+#else /* RTE_NEXT_ABI */
uint32_t hlen_type_rss;
uint64_t pkt_flags;
@@ -1425,6 +1587,7 @@ ixgbe_fill_cluster_head_buf(
pkt_flags |= rx_desc_status_to_pkt_flags(staterr);
pkt_flags |= rx_desc_error_to_pkt_flags(staterr);
head->ol_flags = pkt_flags;
+#endif /* RTE_NEXT_ABI */
if (likely(pkt_flags & PKT_RX_RSS_HASH))
head->hash.rss = rte_le_to_cpu_32(desc->wb.lower.hi_dword.rss);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 06/19] enic: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (4 preceding siblings ...)
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 05/19] i40e: " Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 07/19] vmxnet3: " Helin Zhang
` (12 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/enic/enic_main.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 15313c2..f47e96c 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -423,7 +423,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
rx_pkt->pkt_len = bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
rx_pkt->ol_flags |= PKT_RX_IP_CKSUM_BAD;
@@ -432,7 +436,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
rx_pkt->ol_flags |= PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV6;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
} else {
/* Header split */
if (sop && !eop) {
@@ -445,7 +453,11 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
*rx_pkt_bucket = rx_pkt;
rx_pkt->pkt_len = bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
rx_pkt->ol_flags |=
@@ -457,13 +469,22 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ rx_pkt->packet_type = RTE_PTYPE_L3_IPV6;
+#else
rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
} else {
/* Payload */
hdr_rx_pkt = *rx_pkt_bucket;
hdr_rx_pkt->pkt_len += bytes_written;
if (ipv4) {
+#ifdef RTE_NEXT_ABI
+ hdr_rx_pkt->packet_type =
+ RTE_PTYPE_L3_IPV4;
+#else
hdr_rx_pkt->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!csum_not_calc) {
if (unlikely(!ipv4_csum_ok))
hdr_rx_pkt->ol_flags |=
@@ -475,7 +496,12 @@ static int enic_rq_indicate_buf(struct vnic_rq *rq,
PKT_RX_L4_CKSUM_BAD;
}
} else if (ipv6)
+#ifdef RTE_NEXT_ABI
+ hdr_rx_pkt->packet_type =
+ RTE_PTYPE_L3_IPV6;
+#else
hdr_rx_pkt->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
}
}
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 07/19] vmxnet3: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (5 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 06/19] enic: " Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 08/19] fm10k: " Helin Zhang
` (11 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/vmxnet3/vmxnet3_rxtx.c | 8 ++++++++
1 file changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index a1eac45..25ae2f6 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -649,9 +649,17 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = RTE_PTYPE_L3_IPV4_EXT;
+#else
rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
+#endif
else
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = RTE_PTYPE_L3_IPV4;
+#else
rxm->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (!rcd->cnc) {
if (!rcd->ipc)
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 05/19] i40e: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (3 preceding siblings ...)
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 04/19] ixgbe: " Helin Zhang
@ 2015-07-03 8:32 3% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 06/19] enic: " Helin Zhang
` (13 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/i40e/i40e_rxtx.c | 554 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 554 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
v9 changes:
* Renamed MAC to ETHER in packet type names.
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index b2e1d6d..a608d1f 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -176,6 +176,540 @@ i40e_rxd_error_to_pkt_flags(uint64_t qword)
return flags;
}
+#ifdef RTE_NEXT_ABI
+/* For each value it means, datasheet of hardware can tell more details */
+static inline uint32_t
+i40e_rxd_pkt_type_mapping(uint8_t ptype)
+{
+ static const uint32_t ptype_table[UINT8_MAX] __rte_cache_aligned = {
+ /* L2 types */
+ /* [0] reserved */
+ [1] = RTE_PTYPE_L2_ETHER,
+ [2] = RTE_PTYPE_L2_ETHER_TIMESYNC,
+ /* [3] - [5] reserved */
+ [6] = RTE_PTYPE_L2_ETHER_LLDP,
+ /* [7] - [10] reserved */
+ [11] = RTE_PTYPE_L2_ETHER_ARP,
+ /* [12] - [21] reserved */
+
+ /* Non tunneled IPv4 */
+ [22] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [23] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [24] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [25] reserved */
+ [26] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [27] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [28] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+
+ /* IPv4 --> IPv4 */
+ [29] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [30] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [31] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [32] reserved */
+ [33] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [34] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [35] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> IPv6 */
+ [36] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [37] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [38] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [39] reserved */
+ [40] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [41] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [42] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN */
+ [43] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> IPv4 */
+ [44] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [45] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [46] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [47] reserved */
+ [48] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [49] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [50] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> IPv6 */
+ [51] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [52] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [53] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [54] reserved */
+ [55] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [56] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [57] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC */
+ [58] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC --> IPv4 */
+ [59] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [60] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [61] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [62] reserved */
+ [63] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [64] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [65] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC --> IPv6 */
+ [66] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [67] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [68] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [69] reserved */
+ [70] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [71] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [72] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN */
+ [73] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv4 */
+ [74] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [75] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [76] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [77] reserved */
+ [78] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [79] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [80] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv4 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv6 */
+ [81] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [82] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [83] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [84] reserved */
+ [85] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [86] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [87] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* Non tunneled IPv6 */
+ [88] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [89] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [90] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [91] reserved */
+ [92] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [93] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [94] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+
+ /* IPv6 --> IPv4 */
+ [95] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [96] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [97] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [98] reserved */
+ [99] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [100] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [101] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> IPv6 */
+ [102] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [103] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [104] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [105] reserved */
+ [106] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [107] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [108] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN */
+ [109] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> IPv4 */
+ [110] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [111] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [112] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [113] reserved */
+ [114] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [115] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [116] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> IPv6 */
+ [117] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [118] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [119] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [120] reserved */
+ [121] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [122] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [123] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC */
+ [124] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC --> IPv4 */
+ [125] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [126] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [127] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [128] reserved */
+ [129] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [130] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [131] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC --> IPv6 */
+ [132] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [133] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [134] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [135] reserved */
+ [136] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [137] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [138] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN */
+ [139] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv4 */
+ [140] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [141] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [142] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [143] reserved */
+ [144] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [145] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [146] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* IPv6 --> GRE/Teredo/VXLAN --> MAC/VLAN --> IPv6 */
+ [147] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_FRAG,
+ [148] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_NONFRAG,
+ [149] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_UDP,
+ /* [150] reserved */
+ [151] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_TCP,
+ [152] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_SCTP,
+ [153] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_TUNNEL_GRENAT |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN |
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+ RTE_PTYPE_INNER_L4_ICMP,
+
+ /* All others reserved */
+ };
+
+ return ptype_table[ptype];
+}
+#else /* RTE_NEXT_ABI */
/* Translate pkt types to pkt flags */
static inline uint64_t
i40e_rxd_ptype_to_pkt_flags(uint64_t qword)
@@ -443,6 +977,7 @@ i40e_rxd_ptype_to_pkt_flags(uint64_t qword)
return ip_ptype_map[ptype];
}
+#endif /* RTE_NEXT_ABI */
#define I40E_RX_DESC_EXT_STATUS_FLEXBH_MASK 0x03
#define I40E_RX_DESC_EXT_STATUS_FLEXBH_FD_ID 0x01
@@ -730,11 +1265,18 @@ i40e_rx_scan_hw_ring(struct i40e_rx_queue *rxq)
i40e_rxd_to_vlan_tci(mb, &rxdp[j]);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ mb->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >>
+ I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
mb->packet_type = (uint16_t)((qword1 &
I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
mb->hash.rss = rte_le_to_cpu_32(\
rxdp[j].wb.qword0.hi_dword.rss);
@@ -971,9 +1513,15 @@ i40e_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
i40e_rxd_to_vlan_tci(rxm, &rxd);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
rxm->packet_type = (uint16_t)((qword1 & I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
rxm->hash.rss =
rte_le_to_cpu_32(rxd.wb.qword0.hi_dword.rss);
@@ -1129,10 +1677,16 @@ i40e_recv_scattered_pkts(void *rx_queue,
i40e_rxd_to_vlan_tci(first_seg, &rxd);
pkt_flags = i40e_rxd_status_to_pkt_flags(qword1);
pkt_flags |= i40e_rxd_error_to_pkt_flags(qword1);
+#ifdef RTE_NEXT_ABI
+ first_seg->packet_type =
+ i40e_rxd_pkt_type_mapping((uint8_t)((qword1 &
+ I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT));
+#else
pkt_flags |= i40e_rxd_ptype_to_pkt_flags(qword1);
first_seg->packet_type = (uint16_t)((qword1 &
I40E_RXD_QW1_PTYPE_MASK) >>
I40E_RXD_QW1_PTYPE_SHIFT);
+#endif /* RTE_NEXT_ABI */
if (pkt_flags & PKT_RX_RSS_HASH)
rxm->hash.rss =
rte_le_to_cpu_32(rxd.wb.qword0.hi_dword.rss);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 08/19] fm10k: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (6 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 07/19] vmxnet3: " Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 09/19] cxgbe: " Helin Zhang
` (10 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/fm10k/fm10k_rxtx.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
v4 changes:
* Supported unified packet type of fm10k from v4.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
v9 changes:
* Renamed MAC to ETHER in packet type names.
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index f5d1ad0..d3bcdca 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -68,12 +68,37 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
static inline void
rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
{
+#ifdef RTE_NEXT_ABI
+ static const uint32_t
+ ptype_table[FM10K_RXD_PKTTYPE_MASK >> FM10K_RXD_PKTTYPE_SHIFT]
+ __rte_cache_aligned = {
+ [FM10K_PKTTYPE_OTHER] = RTE_PTYPE_L2_ETHER,
+ [FM10K_PKTTYPE_IPV4] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4,
+ [FM10K_PKTTYPE_IPV4_EX] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [FM10K_PKTTYPE_IPV6] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6,
+ [FM10K_PKTTYPE_IPV6_EX] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [FM10K_PKTTYPE_IPV4 | FM10K_PKTTYPE_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [FM10K_PKTTYPE_IPV6 | FM10K_PKTTYPE_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [FM10K_PKTTYPE_IPV4 | FM10K_PKTTYPE_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [FM10K_PKTTYPE_IPV6 | FM10K_PKTTYPE_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ };
+
+ m->packet_type = ptype_table[(d->w.pkt_info & FM10K_RXD_PKTTYPE_MASK)
+ >> FM10K_RXD_PKTTYPE_SHIFT];
+#else /* RTE_NEXT_ABI */
uint16_t ptype;
static const uint16_t pt_lut[] = { 0,
PKT_RX_IPV4_HDR, PKT_RX_IPV4_HDR_EXT,
PKT_RX_IPV6_HDR, PKT_RX_IPV6_HDR_EXT,
0, 0, 0
};
+#endif /* RTE_NEXT_ABI */
if (d->w.pkt_info & FM10K_RXD_RSSTYPE_MASK)
m->ol_flags |= PKT_RX_RSS_HASH;
@@ -97,9 +122,11 @@ rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
if (unlikely(d->d.staterr & FM10K_RXD_STATUS_RXE))
m->ol_flags |= PKT_RX_RECIP_ERR;
+#ifndef RTE_NEXT_ABI
ptype = (d->d.data & FM10K_RXD_PKTTYPE_MASK_L3) >>
FM10K_RXD_PKTTYPE_SHIFT;
m->ol_flags |= pt_lut[(uint8_t)ptype];
+#endif
}
uint16_t
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 03/19] e1000: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 01/19] mbuf: redefine packet_type in rte_mbuf Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 02/19] mbuf: add definitions of unified packet types Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 04/19] ixgbe: " Helin Zhang
` (15 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/e1000/igb_rxtx.c | 104 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
v9 changes:
* Renamed MAC to ETHER in packet type names.
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index 43d6703..165144c 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -590,6 +590,101 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
* RX functions
*
**********************************************************************/
+#ifdef RTE_NEXT_ABI
+#define IGB_PACKET_TYPE_IPV4 0X01
+#define IGB_PACKET_TYPE_IPV4_TCP 0X11
+#define IGB_PACKET_TYPE_IPV4_UDP 0X21
+#define IGB_PACKET_TYPE_IPV4_SCTP 0X41
+#define IGB_PACKET_TYPE_IPV4_EXT 0X03
+#define IGB_PACKET_TYPE_IPV4_EXT_SCTP 0X43
+#define IGB_PACKET_TYPE_IPV6 0X04
+#define IGB_PACKET_TYPE_IPV6_TCP 0X14
+#define IGB_PACKET_TYPE_IPV6_UDP 0X24
+#define IGB_PACKET_TYPE_IPV6_EXT 0X0C
+#define IGB_PACKET_TYPE_IPV6_EXT_TCP 0X1C
+#define IGB_PACKET_TYPE_IPV6_EXT_UDP 0X2C
+#define IGB_PACKET_TYPE_IPV4_IPV6 0X05
+#define IGB_PACKET_TYPE_IPV4_IPV6_TCP 0X15
+#define IGB_PACKET_TYPE_IPV4_IPV6_UDP 0X25
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT 0X0D
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT_TCP 0X1D
+#define IGB_PACKET_TYPE_IPV4_IPV6_EXT_UDP 0X2D
+#define IGB_PACKET_TYPE_MAX 0X80
+#define IGB_PACKET_TYPE_MASK 0X7F
+#define IGB_PACKET_TYPE_SHIFT 0X04
+static inline uint32_t
+igb_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
+{
+ static const uint32_t
+ ptype_table[IGB_PACKET_TYPE_MAX] __rte_cache_aligned = {
+ [IGB_PACKET_TYPE_IPV4] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4,
+ [IGB_PACKET_TYPE_IPV4_EXT] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4_EXT,
+ [IGB_PACKET_TYPE_IPV6] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6,
+ [IGB_PACKET_TYPE_IPV4_IPV6] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6,
+ [IGB_PACKET_TYPE_IPV6_EXT] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6_EXT,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT,
+ [IGB_PACKET_TYPE_IPV4_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV6_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_TCP,
+ [IGB_PACKET_TYPE_IPV6_EXT_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT_TCP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_TCP,
+ [IGB_PACKET_TYPE_IPV4_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV6_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6 | RTE_PTYPE_INNER_L4_UDP,
+ [IGB_PACKET_TYPE_IPV6_EXT_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_IPV6_EXT_UDP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_IP |
+ RTE_PTYPE_INNER_L3_IPV6_EXT | RTE_PTYPE_INNER_L4_UDP,
+ [IGB_PACKET_TYPE_IPV4_SCTP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_SCTP,
+ [IGB_PACKET_TYPE_IPV4_EXT_SCTP] = RTE_PTYPE_L2_ETHER |
+ RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_SCTP,
+ };
+ if (unlikely(pkt_info & E1000_RXDADV_PKTTYPE_ETQF))
+ return RTE_PTYPE_UNKNOWN;
+
+ pkt_info = (pkt_info >> IGB_PACKET_TYPE_SHIFT) & IGB_PACKET_TYPE_MASK;
+
+ return ptype_table[pkt_info];
+}
+
+static inline uint64_t
+rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
+{
+ uint64_t pkt_flags = ((hl_tp_rs & 0x0F) == 0) ? 0 : PKT_RX_RSS_HASH;
+
+#if defined(RTE_LIBRTE_IEEE1588)
+ static uint32_t ip_pkt_etqf_map[8] = {
+ 0, 0, 0, PKT_RX_IEEE1588_PTP,
+ 0, 0, 0, 0,
+ };
+
+ pkt_flags |= ip_pkt_etqf_map[(hl_tp_rs >> 4) & 0x07];
+#endif
+
+ return pkt_flags;
+}
+#else /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
{
@@ -617,6 +712,7 @@ rx_desc_hlen_type_rss_to_pkt_flags(uint32_t hl_tp_rs)
#endif
return pkt_flags | (((hl_tp_rs & 0x0F) == 0) ? 0 : PKT_RX_RSS_HASH);
}
+#endif /* RTE_NEXT_ABI */
static inline uint64_t
rx_desc_status_to_pkt_flags(uint32_t rx_status)
@@ -790,6 +886,10 @@ eth_igb_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
rxm->ol_flags = pkt_flags;
+#ifdef RTE_NEXT_ABI
+ rxm->packet_type = igb_rxd_pkt_info_to_pkt_type(rxd.wb.lower.
+ lo_dword.hs_rss.pkt_info);
+#endif
/*
* Store the mbuf address into the next entry of the array
@@ -1024,6 +1124,10 @@ eth_igb_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
pkt_flags = pkt_flags | rx_desc_status_to_pkt_flags(staterr);
pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
first_seg->ol_flags = pkt_flags;
+#ifdef RTE_NEXT_ABI
+ first_seg->packet_type = igb_rxd_pkt_info_to_pkt_type(rxd.wb.
+ lower.lo_dword.hs_rss.pkt_info);
+#endif
/* Prefetch data of first segment, if configured to do so. */
rte_packet_prefetch((char *)first_seg->buf_addr +
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 09/19] cxgbe: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (7 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 08/19] fm10k: " Helin Zhang
@ 2015-07-03 8:32 3% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 10/19] app/test-pipeline: " Helin Zhang
` (9 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be enabled
by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
drivers/net/cxgbe/sge.c | 8 ++++++++
1 file changed, 8 insertions(+)
v9 changes:
* Added unified packet type support in newly added cxgbe driver.
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 359296e..fdae0b4 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -1326,14 +1326,22 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
mbuf->port = pkt->iff;
if (pkt->l2info & htonl(F_RXF_IP)) {
+#ifdef RTE_NEXT_ABI
+ mbuf->packet_type = RTE_PTYPE_L3_IPV4;
+#else
mbuf->ol_flags |= PKT_RX_IPV4_HDR;
+#endif
if (unlikely(!csum_ok))
mbuf->ol_flags |= PKT_RX_IP_CKSUM_BAD;
if ((pkt->l2info & htonl(F_RXF_UDP | F_RXF_TCP)) && !csum_ok)
mbuf->ol_flags |= PKT_RX_L4_CKSUM_BAD;
} else if (pkt->l2info & htonl(F_RXF_IP6)) {
+#ifdef RTE_NEXT_ABI
+ mbuf->packet_type = RTE_PTYPE_L3_IPV6;
+#else
mbuf->ol_flags |= PKT_RX_IPV6_HDR;
+#endif
}
mbuf->port = pkt->iff;
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 10/19] app/test-pipeline: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (8 preceding siblings ...)
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 09/19] cxgbe: " Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 11/19] app/testpmd: " Helin Zhang
` (8 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
app/test-pipeline/pipeline_hash.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
index 4598ad4..aa3f9e5 100644
--- a/app/test-pipeline/pipeline_hash.c
+++ b/app/test-pipeline/pipeline_hash.c
@@ -459,20 +459,33 @@ app_main_loop_rx_metadata(void) {
signature = RTE_MBUF_METADATA_UINT32_PTR(m, 0);
key = RTE_MBUF_METADATA_UINT8_PTR(m, 32);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
ip_hdr = (struct ipv4_hdr *)
&m_data[sizeof(struct ether_hdr)];
ip_dst = ip_hdr->dst_addr;
k32 = (uint32_t *) key;
k32[0] = ip_dst & 0xFFFFFF00;
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
} else {
+#endif
ipv6_hdr = (struct ipv6_hdr *)
&m_data[sizeof(struct ether_hdr)];
ipv6_dst = ipv6_hdr->dst_addr;
memcpy(key, ipv6_dst, 16);
+#ifdef RTE_NEXT_ABI
+ } else
+ continue;
+#else
}
+#endif
*signature = test_hash(key, 0, 0);
}
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 11/19] app/testpmd: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (9 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 10/19] app/test-pipeline: " Helin Zhang
@ 2015-07-03 8:32 3% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 12/19] app/test: Remove useless code Helin Zhang
` (7 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
---
app/test-pmd/csumonly.c | 14 ++++
app/test-pmd/rxonly.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 197 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v4 changes:
* Added printing logs of packet types of each received packet in rxonly mode.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
v9 changes:
* Renamed MAC to ETHER in packet type names.
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 4287940..1bf3485 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -202,8 +202,14 @@ parse_ethernet(struct ether_hdr *eth_hdr, struct testpmd_offload_info *info)
/* Parse a vxlan header */
static void
+#ifdef RTE_NEXT_ABI
+parse_vxlan(struct udp_hdr *udp_hdr,
+ struct testpmd_offload_info *info,
+ uint32_t pkt_type)
+#else
parse_vxlan(struct udp_hdr *udp_hdr, struct testpmd_offload_info *info,
uint64_t mbuf_olflags)
+#endif
{
struct ether_hdr *eth_hdr;
@@ -211,8 +217,12 @@ parse_vxlan(struct udp_hdr *udp_hdr, struct testpmd_offload_info *info,
* (rfc7348) or that the rx offload flag is set (i40e only
* currently) */
if (udp_hdr->dst_port != _htons(4789) &&
+#ifdef RTE_NEXT_ABI
+ RTE_ETH_IS_TUNNEL_PKT(pkt_type) == 0)
+#else
(mbuf_olflags & (PKT_RX_TUNNEL_IPV4_HDR |
PKT_RX_TUNNEL_IPV6_HDR)) == 0)
+#endif
return;
info->is_tunnel = 1;
@@ -549,7 +559,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
struct udp_hdr *udp_hdr;
udp_hdr = (struct udp_hdr *)((char *)l3_hdr +
info.l3_len);
+#ifdef RTE_NEXT_ABI
+ parse_vxlan(udp_hdr, &info, m->packet_type);
+#else
parse_vxlan(udp_hdr, &info, m->ol_flags);
+#endif
} else if (info.l4_proto == IPPROTO_GRE) {
struct simple_gre_hdr *gre_hdr;
gre_hdr = (struct simple_gre_hdr *)
diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
index 4a9f86e..632056d 100644
--- a/app/test-pmd/rxonly.c
+++ b/app/test-pmd/rxonly.c
@@ -91,7 +91,11 @@ pkt_burst_receive(struct fwd_stream *fs)
uint64_t ol_flags;
uint16_t nb_rx;
uint16_t i, packet_type;
+#ifdef RTE_NEXT_ABI
+ uint16_t is_encapsulation;
+#else
uint64_t is_encapsulation;
+#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t start_tsc;
@@ -135,8 +139,12 @@ pkt_burst_receive(struct fwd_stream *fs)
ol_flags = mb->ol_flags;
packet_type = mb->packet_type;
+#ifdef RTE_NEXT_ABI
+ is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
+#else
is_encapsulation = ol_flags & (PKT_RX_TUNNEL_IPV4_HDR |
PKT_RX_TUNNEL_IPV6_HDR);
+#endif
print_ether_addr(" src=", ð_hdr->s_addr);
print_ether_addr(" - dst=", ð_hdr->d_addr);
@@ -163,6 +171,177 @@ pkt_burst_receive(struct fwd_stream *fs)
if (ol_flags & PKT_RX_QINQ_PKT)
printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x",
mb->vlan_tci, mb->vlan_tci_outer);
+#ifdef RTE_NEXT_ABI
+ if (mb->packet_type) {
+ uint32_t ptype;
+
+ /* (outer) L2 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L2_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L2_ETHER:
+ printf(" - (outer) L2 type: ETHER");
+ break;
+ case RTE_PTYPE_L2_ETHER_TIMESYNC:
+ printf(" - (outer) L2 type: ETHER_Timesync");
+ break;
+ case RTE_PTYPE_L2_ETHER_ARP:
+ printf(" - (outer) L2 type: ETHER_ARP");
+ break;
+ case RTE_PTYPE_L2_ETHER_LLDP:
+ printf(" - (outer) L2 type: ETHER_LLDP");
+ break;
+ default:
+ printf(" - (outer) L2 type: Unknown");
+ break;
+ }
+
+ /* (outer) L3 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L3_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L3_IPV4:
+ printf(" - (outer) L3 type: IPV4");
+ break;
+ case RTE_PTYPE_L3_IPV4_EXT:
+ printf(" - (outer) L3 type: IPV4_EXT");
+ break;
+ case RTE_PTYPE_L3_IPV6:
+ printf(" - (outer) L3 type: IPV6");
+ break;
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ printf(" - (outer) L3 type: IPV4_EXT_UNKNOWN");
+ break;
+ case RTE_PTYPE_L3_IPV6_EXT:
+ printf(" - (outer) L3 type: IPV6_EXT");
+ break;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ printf(" - (outer) L3 type: IPV6_EXT_UNKNOWN");
+ break;
+ default:
+ printf(" - (outer) L3 type: Unknown");
+ break;
+ }
+
+ /* (outer) L4 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L4_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L4_TCP:
+ printf(" - (outer) L4 type: TCP");
+ break;
+ case RTE_PTYPE_L4_UDP:
+ printf(" - (outer) L4 type: UDP");
+ break;
+ case RTE_PTYPE_L4_FRAG:
+ printf(" - (outer) L4 type: L4_FRAG");
+ break;
+ case RTE_PTYPE_L4_SCTP:
+ printf(" - (outer) L4 type: SCTP");
+ break;
+ case RTE_PTYPE_L4_ICMP:
+ printf(" - (outer) L4 type: ICMP");
+ break;
+ case RTE_PTYPE_L4_NONFRAG:
+ printf(" - (outer) L4 type: L4_NONFRAG");
+ break;
+ default:
+ printf(" - (outer) L4 type: Unknown");
+ break;
+ }
+
+ /* packet tunnel type */
+ ptype = mb->packet_type & RTE_PTYPE_TUNNEL_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_TUNNEL_IP:
+ printf(" - Tunnel type: IP");
+ break;
+ case RTE_PTYPE_TUNNEL_GRE:
+ printf(" - Tunnel type: GRE");
+ break;
+ case RTE_PTYPE_TUNNEL_VXLAN:
+ printf(" - Tunnel type: VXLAN");
+ break;
+ case RTE_PTYPE_TUNNEL_NVGRE:
+ printf(" - Tunnel type: NVGRE");
+ break;
+ case RTE_PTYPE_TUNNEL_GENEVE:
+ printf(" - Tunnel type: GENEVE");
+ break;
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ printf(" - Tunnel type: GRENAT");
+ break;
+ default:
+ printf(" - Tunnel type: Unknown");
+ break;
+ }
+
+ /* inner L2 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L2_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ printf(" - Inner L2 type: ETHER");
+ break;
+ case RTE_PTYPE_INNER_L2_ETHER_VLAN:
+ printf(" - Inner L2 type: ETHER_VLAN");
+ break;
+ default:
+ printf(" - Inner L2 type: Unknown");
+ break;
+ }
+
+ /* inner L3 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_INNER_L3_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L3_IPV4:
+ printf(" - Inner L3 type: IPV4");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV4_EXT:
+ printf(" - Inner L3 type: IPV4_EXT");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6:
+ printf(" - Inner L3 type: IPV6");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ printf(" - Inner L3 type: IPV4_EXT_UNKNOWN");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT:
+ printf(" - Inner L3 type: IPV6_EXT");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ printf(" - Inner L3 type: IPV6_EXT_UNKOWN");
+ break;
+ default:
+ printf(" - Inner L3 type: Unknown");
+ break;
+ }
+
+ /* inner L4 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L4_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ printf(" - Inner L4 type: TCP");
+ break;
+ case RTE_PTYPE_INNER_L4_UDP:
+ printf(" - Inner L4 type: UDP");
+ break;
+ case RTE_PTYPE_INNER_L4_FRAG:
+ printf(" - Inner L4 type: L4_FRAG");
+ break;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ printf(" - Inner L4 type: SCTP");
+ break;
+ case RTE_PTYPE_INNER_L4_ICMP:
+ printf(" - Inner L4 type: ICMP");
+ break;
+ case RTE_PTYPE_INNER_L4_NONFRAG:
+ printf(" - Inner L4 type: L4_NONFRAG");
+ break;
+ default:
+ printf(" - Inner L4 type: Unknown");
+ break;
+ }
+ printf("\n");
+ } else
+ printf("Unknown packet type\n");
+#endif /* RTE_NEXT_ABI */
if (is_encapsulation) {
struct ipv4_hdr *ipv4_hdr;
struct ipv6_hdr *ipv6_hdr;
@@ -176,7 +355,11 @@ pkt_burst_receive(struct fwd_stream *fs)
l2_len = sizeof(struct ether_hdr);
/* Do not support ipv4 option field */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(packet_type)) {
+#else
if (ol_flags & PKT_RX_TUNNEL_IPV4_HDR) {
+#endif
l3_len = sizeof(struct ipv4_hdr);
ipv4_hdr = rte_pktmbuf_mtod_offset(mb,
struct ipv4_hdr *,
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 13/19] examples/ip_fragmentation: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (11 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 12/19] app/test: Remove useless code Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 14/19] examples/ip_reassembly: " Helin Zhang
` (5 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/ip_fragmentation/main.c | 9 +++++++++
1 file changed, 9 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 0922ba6..b71d05f 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -283,7 +283,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf,
len = qconf->tx_mbufs[port_out].len;
/* if this is an IPv4 packet */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
struct ipv4_hdr *ip_hdr;
uint32_t ip_dst;
/* Read the lookup key (i.e. ip_dst) from the input packet */
@@ -317,9 +321,14 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf,
if (unlikely (len2 < 0))
return;
}
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+ /* if this is an IPv6 packet */
+#else
}
/* if this is an IPv6 packet */
else if (m->ol_flags & PKT_RX_IPV6_HDR) {
+#endif
struct ipv6_hdr *ip_hdr;
ipv6 = 1;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 14/19] examples/ip_reassembly: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (12 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 13/19] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 15/19] examples/l3fwd-acl: " Helin Zhang
` (4 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/ip_reassembly/main.c | 9 +++++++++
1 file changed, 9 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 9ecb6f9..f1c47ad 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -356,7 +356,11 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue,
dst_port = portid;
/* if packet is IPv4 */
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & (PKT_RX_IPV4_HDR)) {
+#endif
struct ipv4_hdr *ip_hdr;
uint32_t ip_dst;
@@ -396,9 +400,14 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue,
}
eth_hdr->ether_type = rte_be_to_cpu_16(ETHER_TYPE_IPv4);
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+ /* if packet is IPv6 */
+#else
}
/* if packet is IPv6 */
else if (m->ol_flags & (PKT_RX_IPV6_HDR | PKT_RX_IPV6_HDR_EXT)) {
+#endif
struct ipv6_extension_fragment *frag_hdr;
struct ipv6_hdr *ip_hdr;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 12/19] app/test: Remove useless code
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (10 preceding siblings ...)
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 11/19] app/testpmd: " Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 13/19] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
` (6 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
Severl useless code lines are added accidently, which blocks packet
type unification. They should be deleted at all.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
app/test/packet_burst_generator.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
v4 changes:
* Removed several useless code lines which block packet type unification.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c
index 28d9e25..d9d808b 100644
--- a/app/test/packet_burst_generator.c
+++ b/app/test/packet_burst_generator.c
@@ -273,19 +273,21 @@ nomore_mbuf:
if (ipv4) {
pkt->vlan_tci = ETHER_TYPE_IPv4;
pkt->l3_len = sizeof(struct ipv4_hdr);
-
+#ifndef RTE_NEXT_ABI
if (vlan_enabled)
pkt->ol_flags = PKT_RX_IPV4_HDR | PKT_RX_VLAN_PKT;
else
pkt->ol_flags = PKT_RX_IPV4_HDR;
+#endif
} else {
pkt->vlan_tci = ETHER_TYPE_IPv6;
pkt->l3_len = sizeof(struct ipv6_hdr);
-
+#ifndef RTE_NEXT_ABI
if (vlan_enabled)
pkt->ol_flags = PKT_RX_IPV6_HDR | PKT_RX_VLAN_PKT;
else
pkt->ol_flags = PKT_RX_IPV6_HDR;
+#endif
}
pkts_burst[nb_pkt] = pkt;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 15/19] examples/l3fwd-acl: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (13 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 14/19] examples/ip_reassembly: " Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 16/19] examples/l3fwd-power: " Helin Zhang
` (3 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd-acl/main.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 29cb25e..b2bdf2f 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -645,10 +645,13 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
struct ipv4_hdr *ipv4_hdr;
struct rte_mbuf *pkt = pkts_in[index];
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
int type = pkt->ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_IPV6_HDR);
if (type == PKT_RX_IPV4_HDR) {
-
+#endif
ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
sizeof(struct ether_hdr));
@@ -667,9 +670,11 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
/* Not a valid IPv4 packet */
rte_pktmbuf_free(pkt);
}
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (type == PKT_RX_IPV6_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv6[acl->num_ipv6] = MBUF_IPV6_2PROTO(pkt);
acl->m_ipv6[(acl->num_ipv6)++] = pkt;
@@ -687,17 +692,22 @@ prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
{
struct rte_mbuf *pkt = pkts_in[index];
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
int type = pkt->ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_IPV6_HDR);
if (type == PKT_RX_IPV4_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv4[acl->num_ipv4] = MBUF_IPV4_2PROTO(pkt);
acl->m_ipv4[(acl->num_ipv4)++] = pkt;
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (type == PKT_RX_IPV6_HDR) {
-
+#endif
/* Fill acl structure */
acl->data_ipv6[acl->num_ipv6] = MBUF_IPV6_2PROTO(pkt);
acl->m_ipv6[(acl->num_ipv6)++] = pkt;
@@ -745,10 +755,17 @@ send_one_packet(struct rte_mbuf *m, uint32_t res)
/* in the ACL list, drop it */
#ifdef L3FWDACL_DEBUG
if ((res & ACL_DENY_SIGNATURE) != 0) {
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type))
+ dump_acl4_rule(m, res);
+ else if (RTE_ETH_IS_IPV6_HDR(m->packet_type))
+ dump_acl6_rule(m, res);
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR)
dump_acl4_rule(m, res);
else
dump_acl6_rule(m, res);
+#endif /* RTE_NEXT_ABI */
}
#endif
rte_pktmbuf_free(m);
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 16/19] examples/l3fwd-power: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (14 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 15/19] examples/l3fwd-acl: " Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 17/19] examples/l3fwd: " Helin Zhang
` (2 subsequent siblings)
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd-power/main.c | 8 ++++++++
1 file changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index d4eba1a..dbbebdd 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -635,7 +635,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
/* Handle IPv4 headers.*/
ipv4_hdr =
rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
@@ -670,8 +674,12 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
}
else {
+#endif
/* Handle IPv6 headers.*/
#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
struct ipv6_hdr *ipv6_hdr;
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v9 17/19] examples/l3fwd: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (15 preceding siblings ...)
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 16/19] examples/l3fwd-power: " Helin Zhang
@ 2015-07-03 8:32 3% ` Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 18/19] examples/tep_termination: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 19/19] mbuf: remove old packet type bit masks Helin Zhang
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/l3fwd/main.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 120 insertions(+), 3 deletions(-)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
v3 changes:
* Minor bug fixes and enhancements.
v5 changes:
* Re-worded the commit logs.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 5c22ed1..b1bcb35 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -939,7 +939,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+#else
if (m->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
/* Handle IPv4 headers.*/
ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
sizeof(struct ether_hdr));
@@ -970,8 +974,11 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
-
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+#else
} else {
+#endif
/* Handle IPv6 headers.*/
struct ipv6_hdr *ipv6_hdr;
@@ -990,8 +997,13 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
send_single_packet(m, dst_port);
+#ifdef RTE_NEXT_ABI
+ } else
+ /* Free the mbuf that contains non-IPV4/IPV6 packet */
+ rte_pktmbuf_free(m);
+#else
}
-
+#endif
}
#ifdef DO_RFC_1812_CHECKS
@@ -1015,12 +1027,19 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qcon
* to BAD_PORT value.
*/
static inline __attribute__((always_inline)) void
+#ifdef RTE_NEXT_ABI
+rfc1812_process(struct ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t ptype)
+#else
rfc1812_process(struct ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t flags)
+#endif
{
uint8_t ihl;
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(ptype)) {
+#else
if ((flags & PKT_RX_IPV4_HDR) != 0) {
-
+#endif
ihl = ipv4_hdr->version_ihl - IPV4_MIN_VER_IHL;
ipv4_hdr->time_to_live--;
@@ -1050,11 +1069,19 @@ get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
struct ipv6_hdr *ipv6_hdr;
struct ether_hdr *eth_hdr;
+#ifdef RTE_NEXT_ABI
+ if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+#else
if (pkt->ol_flags & PKT_RX_IPV4_HDR) {
+#endif
if (rte_lpm_lookup(qconf->ipv4_lookup_struct, dst_ipv4,
&next_hop) != 0)
next_hop = portid;
+#ifdef RTE_NEXT_ABI
+ } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+#else
} else if (pkt->ol_flags & PKT_RX_IPV6_HDR) {
+#endif
eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
ipv6_hdr = (struct ipv6_hdr *)(eth_hdr + 1);
if (rte_lpm6_lookup(qconf->ipv6_lookup_struct,
@@ -1088,12 +1115,52 @@ process_packet(struct lcore_conf *qconf, struct rte_mbuf *pkt,
ve = val_eth[dp];
dst_port[0] = dp;
+#ifdef RTE_NEXT_ABI
+ rfc1812_process(ipv4_hdr, dst_port, pkt->packet_type);
+#else
rfc1812_process(ipv4_hdr, dst_port, pkt->ol_flags);
+#endif
te = _mm_blend_epi16(te, ve, MASK_ETH);
_mm_store_si128((__m128i *)eth_hdr, te);
}
+#ifdef RTE_NEXT_ABI
+/*
+ * Read packet_type and destination IPV4 addresses from 4 mbufs.
+ */
+static inline void
+processx4_step1(struct rte_mbuf *pkt[FWDSTEP],
+ __m128i *dip,
+ uint32_t *ipv4_flag)
+{
+ struct ipv4_hdr *ipv4_hdr;
+ struct ether_hdr *eth_hdr;
+ uint32_t x0, x1, x2, x3;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[0], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x0 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] = pkt[0]->packet_type & RTE_PTYPE_L3_IPV4;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[1], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x1 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[1]->packet_type;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[2], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x2 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[2]->packet_type;
+
+ eth_hdr = rte_pktmbuf_mtod(pkt[3], struct ether_hdr *);
+ ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+ x3 = ipv4_hdr->dst_addr;
+ ipv4_flag[0] &= pkt[3]->packet_type;
+
+ dip[0] = _mm_set_epi32(x3, x2, x1, x0);
+}
+#else /* RTE_NEXT_ABI */
/*
* Read ol_flags and destination IPV4 addresses from 4 mbufs.
*/
@@ -1126,14 +1193,24 @@ processx4_step1(struct rte_mbuf *pkt[FWDSTEP], __m128i *dip, uint32_t *flag)
dip[0] = _mm_set_epi32(x3, x2, x1, x0);
}
+#endif /* RTE_NEXT_ABI */
/*
* Lookup into LPM for destination port.
* If lookup fails, use incoming port (portid) as destination port.
*/
static inline void
+#ifdef RTE_NEXT_ABI
+processx4_step2(const struct lcore_conf *qconf,
+ __m128i dip,
+ uint32_t ipv4_flag,
+ uint8_t portid,
+ struct rte_mbuf *pkt[FWDSTEP],
+ uint16_t dprt[FWDSTEP])
+#else
processx4_step2(const struct lcore_conf *qconf, __m128i dip, uint32_t flag,
uint8_t portid, struct rte_mbuf *pkt[FWDSTEP], uint16_t dprt[FWDSTEP])
+#endif /* RTE_NEXT_ABI */
{
rte_xmm_t dst;
const __m128i bswap_mask = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11,
@@ -1143,7 +1220,11 @@ processx4_step2(const struct lcore_conf *qconf, __m128i dip, uint32_t flag,
dip = _mm_shuffle_epi8(dip, bswap_mask);
/* if all 4 packets are IPV4. */
+#ifdef RTE_NEXT_ABI
+ if (likely(ipv4_flag)) {
+#else
if (likely(flag != 0)) {
+#endif
rte_lpm_lookupx4(qconf->ipv4_lookup_struct, dip, dprt, portid);
} else {
dst.x = dip;
@@ -1193,6 +1274,16 @@ processx4_step3(struct rte_mbuf *pkt[FWDSTEP], uint16_t dst_port[FWDSTEP])
_mm_store_si128(p[2], te[2]);
_mm_store_si128(p[3], te[3]);
+#ifdef RTE_NEXT_ABI
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[0] + 1),
+ &dst_port[0], pkt[0]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[1] + 1),
+ &dst_port[1], pkt[1]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[2] + 1),
+ &dst_port[2], pkt[2]->packet_type);
+ rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[3] + 1),
+ &dst_port[3], pkt[3]->packet_type);
+#else /* RTE_NEXT_ABI */
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[0] + 1),
&dst_port[0], pkt[0]->ol_flags);
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[1] + 1),
@@ -1201,6 +1292,7 @@ processx4_step3(struct rte_mbuf *pkt[FWDSTEP], uint16_t dst_port[FWDSTEP])
&dst_port[2], pkt[2]->ol_flags);
rfc1812_process((struct ipv4_hdr *)((struct ether_hdr *)p[3] + 1),
&dst_port[3], pkt[3]->ol_flags);
+#endif /* RTE_NEXT_ABI */
}
/*
@@ -1387,7 +1479,11 @@ main_loop(__attribute__((unused)) void *dummy)
uint16_t *lp;
uint16_t dst_port[MAX_PKT_BURST];
__m128i dip[MAX_PKT_BURST / FWDSTEP];
+#ifdef RTE_NEXT_ABI
+ uint32_t ipv4_flag[MAX_PKT_BURST / FWDSTEP];
+#else
uint32_t flag[MAX_PKT_BURST / FWDSTEP];
+#endif
uint16_t pnum[MAX_PKT_BURST + 1];
#endif
@@ -1457,6 +1553,18 @@ main_loop(__attribute__((unused)) void *dummy)
*/
int32_t n = RTE_ALIGN_FLOOR(nb_rx, 4);
for (j = 0; j < n ; j+=4) {
+#ifdef RTE_NEXT_ABI
+ uint32_t pkt_type =
+ pkts_burst[j]->packet_type &
+ pkts_burst[j+1]->packet_type &
+ pkts_burst[j+2]->packet_type &
+ pkts_burst[j+3]->packet_type;
+ if (pkt_type & RTE_PTYPE_L3_IPV4) {
+ simple_ipv4_fwd_4pkts(
+ &pkts_burst[j], portid, qconf);
+ } else if (pkt_type &
+ RTE_PTYPE_L3_IPV6) {
+#else /* RTE_NEXT_ABI */
uint32_t ol_flag = pkts_burst[j]->ol_flags
& pkts_burst[j+1]->ol_flags
& pkts_burst[j+2]->ol_flags
@@ -1465,6 +1573,7 @@ main_loop(__attribute__((unused)) void *dummy)
simple_ipv4_fwd_4pkts(&pkts_burst[j],
portid, qconf);
} else if (ol_flag & PKT_RX_IPV6_HDR) {
+#endif /* RTE_NEXT_ABI */
simple_ipv6_fwd_4pkts(&pkts_burst[j],
portid, qconf);
} else {
@@ -1489,13 +1598,21 @@ main_loop(__attribute__((unused)) void *dummy)
for (j = 0; j != k; j += FWDSTEP) {
processx4_step1(&pkts_burst[j],
&dip[j / FWDSTEP],
+#ifdef RTE_NEXT_ABI
+ &ipv4_flag[j / FWDSTEP]);
+#else
&flag[j / FWDSTEP]);
+#endif
}
k = RTE_ALIGN_FLOOR(nb_rx, FWDSTEP);
for (j = 0; j != k; j += FWDSTEP) {
processx4_step2(qconf, dip[j / FWDSTEP],
+#ifdef RTE_NEXT_ABI
+ ipv4_flag[j / FWDSTEP], portid,
+#else
flag[j / FWDSTEP], portid,
+#endif
&pkts_burst[j], &dst_port[j]);
}
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 18/19] examples/tep_termination: replace bit mask based packet type with unified packet type
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (16 preceding siblings ...)
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 17/19] examples/l3fwd: " Helin Zhang
@ 2015-07-03 8:32 3% ` Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 19/19] mbuf: remove old packet type bit masks Helin Zhang
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
To unify packet types among all PMDs, bit masks of packet type for
'ol_flags' are replaced by unified packet type.
To avoid breaking ABI compatibility, all the changes would be enabled
by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
examples/tep_termination/vxlan.c | 4 ++++
1 file changed, 4 insertions(+)
v9 changes:
* Used unified packet type to check if it is a VXLAN packet, included in
RTE_NEXT_ABI which is disabled by default.
diff --git a/examples/tep_termination/vxlan.c b/examples/tep_termination/vxlan.c
index b2a2f53..ae4bc9e 100644
--- a/examples/tep_termination/vxlan.c
+++ b/examples/tep_termination/vxlan.c
@@ -180,8 +180,12 @@ decapsulation(struct rte_mbuf *pkt)
* (rfc7348) or that the rx offload flag is set (i40e only
* currently)*/
if (udp_hdr->dst_port != rte_cpu_to_be_16(DEFAULT_VXLAN_PORT) &&
+#ifdef RTE_NEXT_ABI
+ ((pkt->packet_type & RTE_PTYPE_TUNNEL_MASK) == 0)
+#else
(pkt->ol_flags & (PKT_RX_TUNNEL_IPV4_HDR |
PKT_RX_TUNNEL_IPV6_HDR)) == 0)
+#endif
return -1;
outer_header_len = info.outer_l2_len + info.outer_l3_len
+ sizeof(struct udp_hdr) + sizeof(struct vxlan_hdr);
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 19/19] mbuf: remove old packet type bit masks
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
` (17 preceding siblings ...)
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 18/19] examples/tep_termination: " Helin Zhang
@ 2015-07-03 8:32 4% ` Helin Zhang
18 siblings, 0 replies; 200+ results
From: Helin Zhang @ 2015-07-03 8:32 UTC (permalink / raw)
To: dev
As unified packet types are used instead, those old bit masks and
the relevant macros for packet type indication need to be removed.
To avoid breaking ABI compatibility, all the changes would be
enabled by RTE_NEXT_ABI, which is disabled by default.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
lib/librte_mbuf/rte_mbuf.c | 4 ++++
lib/librte_mbuf/rte_mbuf.h | 4 ++++
2 files changed, 8 insertions(+)
v2 changes:
* Used redefined packet types and enlarged packet_type field in mbuf.
* Redefined the bit masks for packet RX offload flags.
v5 changes:
* Rolled back the bit masks of RX flags, for ABI compatibility.
v6 changes:
* Disabled the code changes for unified packet type by default, to
avoid breaking ABI compatibility.
v7 changes:
* Renamed RTE_UNIFIED_PKT_TYPE to RTE_NEXT_ABI.
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index f506517..4320dd4 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -251,14 +251,18 @@ const char *rte_get_rx_ol_flag_name(uint64_t mask)
/* case PKT_RX_HBUF_OVERFLOW: return "PKT_RX_HBUF_OVERFLOW"; */
/* case PKT_RX_RECIP_ERR: return "PKT_RX_RECIP_ERR"; */
/* case PKT_RX_MAC_ERR: return "PKT_RX_MAC_ERR"; */
+#ifndef RTE_NEXT_ABI
case PKT_RX_IPV4_HDR: return "PKT_RX_IPV4_HDR";
case PKT_RX_IPV4_HDR_EXT: return "PKT_RX_IPV4_HDR_EXT";
case PKT_RX_IPV6_HDR: return "PKT_RX_IPV6_HDR";
case PKT_RX_IPV6_HDR_EXT: return "PKT_RX_IPV6_HDR_EXT";
+#endif /* RTE_NEXT_ABI */
case PKT_RX_IEEE1588_PTP: return "PKT_RX_IEEE1588_PTP";
case PKT_RX_IEEE1588_TMST: return "PKT_RX_IEEE1588_TMST";
+#ifndef RTE_NEXT_ABI
case PKT_RX_TUNNEL_IPV4_HDR: return "PKT_RX_TUNNEL_IPV4_HDR";
case PKT_RX_TUNNEL_IPV6_HDR: return "PKT_RX_TUNNEL_IPV6_HDR";
+#endif /* RTE_NEXT_ABI */
default: return NULL;
}
}
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 3a17d95..b90c73f 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -92,14 +92,18 @@ 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. */
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2] doc: announce ABI changes planned for unified packet type
@ 2015-07-03 8:49 21% ` Helin Zhang
2015-07-07 17:45 21% ` [dpdk-dev] [PATCH v3] " Helin Zhang
0 siblings, 1 reply; 200+ results
From: Helin Zhang @ 2015-07-03 8:49 UTC (permalink / raw)
To: dev
The significant ABI changes are planned for unified packet type
which will be supported from release 2.2. Here announces that ABI
changes in detail.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
doc/guides/rel_notes/abi.rst | 1 +
1 file changed, 1 insertion(+)
v2 changes:
* Added 'struct rte_kni_mbuf' to the ABI change announcement.
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index 110c486..4328367 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -12,3 +12,4 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* Significant ABI changes are planned for struct rte_mbuf, struct rte_kni_mbuf, and several PKT_RX_ flags will be removed, to support unified packet type from release 2.2. The upcoming release 2.1 will not have those changes. There is no backward compatibility planned from release 2.2. All binaries will need to be rebuilt from release 2.2.
--
1.9.3
^ permalink raw reply [relevance 21%]
* [dpdk-dev] [PATCH v7 0/9] Dynamic memzones
2015-06-26 15:29 4% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Sergio Gonzalez Monroy
` (2 preceding siblings ...)
2015-06-26 16:13 0% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Ananyev, Konstantin
@ 2015-07-03 9:55 4% ` Sergio Gonzalez Monroy
2015-07-03 9:55 1% ` [dpdk-dev] [PATCH v7 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-07-03 9:55 14% ` [dpdk-dev] [PATCH v7 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
3 siblings, 2 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-07-03 9:55 UTC (permalink / raw)
To: dev
Current implemetation allows reserving/creating memzones but not the opposite
(unreserve/free). This affects mempools and other memzone based objects.
>From my point of view, implementing free functionality for memzones would look
like malloc over memsegs.
Thus, this approach moves malloc inside eal (which in turn removes a circular
dependency), where malloc heaps are composed of memsegs.
We keep both malloc and memzone APIs as they are, but memzones allocate its
memory by calling malloc_heap_alloc.
Some extra functionality is required in malloc to allow for boundary constrained
memory requests.
In summary, currently malloc is based on memzones, and with this approach
memzones are based on malloc.
v7:
- Create a separated maintainer section for memory allocation
v6:
- Fix bad patch for rte_memzone_free
v5:
- Fix rte_memzone_free
- Improve rte_memzone_free unit test
v4:
- Rebase and fix couple of merge issues
v3:
- Create dummy librte_malloc
- Add deprecation notice
- Rework some of the code
- Doc update
- checkpatch
v2:
- New rte_memzone_free
- Support memzone len = 0
- Add all available memsegs to malloc heap at init
- Update memzone/malloc unit tests
Sergio Gonzalez Monroy (9):
eal: move librte_malloc to eal/common
eal: memzone allocated by malloc
app/test: update malloc/memzone unit tests
config: remove CONFIG_RTE_MALLOC_MEMZONE_SIZE
eal: remove free_memseg and references to it
eal: new rte_memzone_free
app/test: rte_memzone_free unit test
doc: announce ABI change of librte_malloc
doc: update malloc documentation
MAINTAINERS | 22 +-
app/test/test_malloc.c | 86 ----
app/test/test_memzone.c | 456 ++++------------------
config/common_bsdapp | 8 +-
config/common_linuxapp | 8 +-
doc/guides/prog_guide/env_abstraction_layer.rst | 220 ++++++++++-
doc/guides/prog_guide/img/malloc_heap.png | Bin 81329 -> 80952 bytes
doc/guides/prog_guide/index.rst | 1 -
doc/guides/prog_guide/malloc_lib.rst | 233 -----------
doc/guides/prog_guide/overview.rst | 11 +-
doc/guides/rel_notes/abi.rst | 1 +
drivers/net/af_packet/Makefile | 1 -
drivers/net/bonding/Makefile | 1 -
drivers/net/e1000/Makefile | 2 +-
drivers/net/enic/Makefile | 2 +-
drivers/net/fm10k/Makefile | 2 +-
drivers/net/i40e/Makefile | 2 +-
drivers/net/ixgbe/Makefile | 2 +-
drivers/net/mlx4/Makefile | 1 -
drivers/net/null/Makefile | 1 -
drivers/net/pcap/Makefile | 1 -
drivers/net/virtio/Makefile | 2 +-
drivers/net/vmxnet3/Makefile | 2 +-
drivers/net/xenvirt/Makefile | 2 +-
lib/Makefile | 2 +-
lib/librte_acl/Makefile | 2 +-
lib/librte_eal/bsdapp/eal/Makefile | 4 +-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 19 +
lib/librte_eal/common/Makefile | 1 +
lib/librte_eal/common/eal_common_memzone.c | 339 ++++++----------
lib/librte_eal/common/include/rte_eal_memconfig.h | 5 +-
lib/librte_eal/common/include/rte_malloc.h | 342 ++++++++++++++++
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/include/rte_memzone.h | 11 +
lib/librte_eal/common/malloc_elem.c | 344 ++++++++++++++++
lib/librte_eal/common/malloc_elem.h | 192 +++++++++
lib/librte_eal/common/malloc_heap.c | 206 ++++++++++
lib/librte_eal/common/malloc_heap.h | 70 ++++
lib/librte_eal/common/rte_malloc.c | 259 ++++++++++++
lib/librte_eal/linuxapp/eal/Makefile | 4 +-
lib/librte_eal/linuxapp/eal/eal_ivshmem.c | 17 +-
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 19 +
lib/librte_hash/Makefile | 2 +-
lib/librte_lpm/Makefile | 2 +-
lib/librte_malloc/Makefile | 6 +-
lib/librte_malloc/malloc_elem.c | 320 ---------------
lib/librte_malloc/malloc_elem.h | 190 ---------
lib/librte_malloc/malloc_heap.c | 208 ----------
lib/librte_malloc/malloc_heap.h | 70 ----
lib/librte_malloc/rte_malloc.c | 228 +----------
lib/librte_malloc/rte_malloc.h | 342 ----------------
lib/librte_malloc/rte_malloc_version.map | 16 -
lib/librte_mempool/Makefile | 2 -
lib/librte_port/Makefile | 1 -
lib/librte_ring/Makefile | 3 +-
lib/librte_table/Makefile | 1 -
56 files changed, 1938 insertions(+), 2359 deletions(-)
delete mode 100644 doc/guides/prog_guide/malloc_lib.rst
create mode 100644 lib/librte_eal/common/include/rte_malloc.h
create mode 100644 lib/librte_eal/common/malloc_elem.c
create mode 100644 lib/librte_eal/common/malloc_elem.h
create mode 100644 lib/librte_eal/common/malloc_heap.c
create mode 100644 lib/librte_eal/common/malloc_heap.h
create mode 100644 lib/librte_eal/common/rte_malloc.c
delete mode 100644 lib/librte_malloc/malloc_elem.c
delete mode 100644 lib/librte_malloc/malloc_elem.h
delete mode 100644 lib/librte_malloc/malloc_heap.c
delete mode 100644 lib/librte_malloc/malloc_heap.h
delete mode 100644 lib/librte_malloc/rte_malloc.h
--
1.9.3
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 2/9] eal: memzone allocated by malloc
2015-07-03 9:55 4% ` [dpdk-dev] [PATCH v7 " Sergio Gonzalez Monroy
@ 2015-07-03 9:55 1% ` Sergio Gonzalez Monroy
2015-07-03 9:55 14% ` [dpdk-dev] [PATCH v7 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
1 sibling, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-07-03 9:55 UTC (permalink / raw)
To: dev
In the current memory hierarchy, memsegs are groups of physically
contiguous hugepages, memzones are slices of memsegs and malloc further
slices memzones into smaller memory chunks.
This patch modifies malloc so it partitions memsegs instead of memzones.
Thus memzones would call malloc internally for memory allocation while
maintaining its ABI.
It would be possible to free memzones and therefore any other structure
based on memzones, ie. mempools
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
lib/librte_eal/common/eal_common_memzone.c | 274 ++++++----------------
lib/librte_eal/common/include/rte_eal_memconfig.h | 2 +-
lib/librte_eal/common/include/rte_malloc_heap.h | 3 +-
lib/librte_eal/common/malloc_elem.c | 68 ++++--
lib/librte_eal/common/malloc_elem.h | 14 +-
lib/librte_eal/common/malloc_heap.c | 140 ++++++-----
lib/librte_eal/common/malloc_heap.h | 6 +-
lib/librte_eal/common/rte_malloc.c | 7 +-
8 files changed, 197 insertions(+), 317 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c
index aee184a..943012b 100644
--- a/lib/librte_eal/common/eal_common_memzone.c
+++ b/lib/librte_eal/common/eal_common_memzone.c
@@ -50,15 +50,15 @@
#include <rte_string_fns.h>
#include <rte_common.h>
+#include "malloc_heap.h"
+#include "malloc_elem.h"
#include "eal_private.h"
-/* internal copy of free memory segments */
-static struct rte_memseg *free_memseg = NULL;
-
static inline const struct rte_memzone *
memzone_lookup_thread_unsafe(const char *name)
{
const struct rte_mem_config *mcfg;
+ const struct rte_memzone *mz;
unsigned i = 0;
/* get pointer to global configuration */
@@ -68,8 +68,9 @@ memzone_lookup_thread_unsafe(const char *name)
* the algorithm is not optimal (linear), but there are few
* zones and this function should be called at init only
*/
- for (i = 0; i < RTE_MAX_MEMZONE && mcfg->memzone[i].addr != NULL; i++) {
- if (!strncmp(name, mcfg->memzone[i].name, RTE_MEMZONE_NAMESIZE))
+ for (i = 0; i < RTE_MAX_MEMZONE; i++) {
+ mz = &mcfg->memzone[i];
+ if (mz->addr != NULL && !strncmp(name, mz->name, RTE_MEMZONE_NAMESIZE))
return &mcfg->memzone[i];
}
@@ -88,39 +89,45 @@ rte_memzone_reserve(const char *name, size_t len, int socket_id,
len, socket_id, flags, RTE_CACHE_LINE_SIZE);
}
-/*
- * Helper function for memzone_reserve_aligned_thread_unsafe().
- * Calculate address offset from the start of the segment.
- * Align offset in that way that it satisfy istart alignmnet and
- * buffer of the requested length would not cross specified boundary.
- */
-static inline phys_addr_t
-align_phys_boundary(const struct rte_memseg *ms, size_t len, size_t align,
- size_t bound)
+/* Find the heap with the greatest free block size */
+static void
+find_heap_max_free_elem(int *s, size_t *len, unsigned align)
{
- phys_addr_t addr_offset, bmask, end, start;
- size_t step;
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- step = RTE_MAX(align, bound);
- bmask = ~((phys_addr_t)bound - 1);
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate offset to closest alignment */
- start = RTE_ALIGN_CEIL(ms->phys_addr, align);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size > *len) {
+ *len = stats.greatest_free_size;
+ *s = i;
+ }
+ }
+ *len -= (MALLOC_ELEM_OVERHEAD + align);
+}
- while (addr_offset + len < ms->len) {
+/* Find a heap that can allocate the requested size */
+static void
+find_heap_suitable(int *s, size_t len, unsigned align)
+{
+ struct rte_mem_config *mcfg;
+ struct rte_malloc_socket_stats stats;
+ unsigned i;
- /* check, do we meet boundary condition */
- end = start + len - (len != 0);
- if ((start & bmask) == (end & bmask))
- break;
+ /* get pointer to global configuration */
+ mcfg = rte_eal_get_configuration()->mem_config;
- /* calculate next offset */
- start = RTE_ALIGN_CEIL(start + 1, step);
- addr_offset = start - ms->phys_addr;
+ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
+ malloc_heap_get_stats(&mcfg->malloc_heaps[i], &stats);
+ if (stats.greatest_free_size >= len + MALLOC_ELEM_OVERHEAD + align) {
+ *s = i;
+ break;
+ }
}
-
- return addr_offset;
}
static const struct rte_memzone *
@@ -128,13 +135,7 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
int socket_id, unsigned flags, unsigned align, unsigned bound)
{
struct rte_mem_config *mcfg;
- unsigned i = 0;
- int memseg_idx = -1;
- uint64_t addr_offset, seg_offset = 0;
size_t requested_len;
- size_t memseg_len = 0;
- phys_addr_t memseg_physaddr;
- void *memseg_addr;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
@@ -166,7 +167,6 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
if (align < RTE_CACHE_LINE_SIZE)
align = RTE_CACHE_LINE_SIZE;
-
/* align length on cache boundary. Check for overflow before doing so */
if (len > SIZE_MAX - RTE_CACHE_LINE_MASK) {
rte_errno = EINVAL; /* requested size too big */
@@ -180,129 +180,50 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
requested_len = RTE_MAX((size_t)RTE_CACHE_LINE_SIZE, len);
/* check that boundary condition is valid */
- if (bound != 0 &&
- (requested_len > bound || !rte_is_power_of_2(bound))) {
+ if (bound != 0 && (requested_len > bound || !rte_is_power_of_2(bound))) {
rte_errno = EINVAL;
return NULL;
}
- /* find the smallest segment matching requirements */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- /* last segment */
- if (free_memseg[i].addr == NULL)
- break;
+ if (len == 0) {
+ if (bound != 0)
+ requested_len = bound;
+ else
+ requested_len = 0;
+ }
- /* empty segment, skip it */
- if (free_memseg[i].len == 0)
- continue;
-
- /* bad socket ID */
- if (socket_id != SOCKET_ID_ANY &&
- free_memseg[i].socket_id != SOCKET_ID_ANY &&
- socket_id != free_memseg[i].socket_id)
- continue;
-
- /*
- * calculate offset to closest alignment that
- * meets boundary conditions.
- */
- addr_offset = align_phys_boundary(free_memseg + i,
- requested_len, align, bound);
-
- /* check len */
- if ((requested_len + addr_offset) > free_memseg[i].len)
- continue;
-
- /* check flags for hugepage sizes */
- if ((flags & RTE_MEMZONE_2MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_1G)
- continue;
- if ((flags & RTE_MEMZONE_1GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_2M)
- continue;
- if ((flags & RTE_MEMZONE_16MB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16G)
- continue;
- if ((flags & RTE_MEMZONE_16GB) &&
- free_memseg[i].hugepage_sz == RTE_PGSIZE_16M)
- continue;
-
- /* this segment is the best until now */
- if (memseg_idx == -1) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- /* find the biggest contiguous zone */
- else if (len == 0) {
- if (free_memseg[i].len > memseg_len) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
- }
- }
- /*
- * find the smallest (we already checked that current
- * zone length is > len
- */
- else if (free_memseg[i].len + align < memseg_len ||
- (free_memseg[i].len <= memseg_len + align &&
- addr_offset < seg_offset)) {
- memseg_idx = i;
- memseg_len = free_memseg[i].len;
- seg_offset = addr_offset;
+ if (socket_id == SOCKET_ID_ANY) {
+ if (requested_len == 0)
+ find_heap_max_free_elem(&socket_id, &requested_len, align);
+ else
+ find_heap_suitable(&socket_id, requested_len, align);
+
+ if (socket_id == SOCKET_ID_ANY) {
+ rte_errno = ENOMEM;
+ return NULL;
}
}
- /* no segment found */
- if (memseg_idx == -1) {
- /*
- * If RTE_MEMZONE_SIZE_HINT_ONLY flag is specified,
- * try allocating again without the size parameter otherwise -fail.
- */
- if ((flags & RTE_MEMZONE_SIZE_HINT_ONLY) &&
- ((flags & RTE_MEMZONE_1GB) || (flags & RTE_MEMZONE_2MB)
- || (flags & RTE_MEMZONE_16MB) || (flags & RTE_MEMZONE_16GB)))
- return memzone_reserve_aligned_thread_unsafe(name,
- len, socket_id, 0, align, bound);
-
+ /* allocate memory on heap */
+ void *mz_addr = malloc_heap_alloc(&mcfg->malloc_heaps[socket_id], NULL,
+ requested_len, flags, align, bound);
+ if (mz_addr == NULL) {
rte_errno = ENOMEM;
return NULL;
}
- /* save aligned physical and virtual addresses */
- memseg_physaddr = free_memseg[memseg_idx].phys_addr + seg_offset;
- memseg_addr = RTE_PTR_ADD(free_memseg[memseg_idx].addr,
- (uintptr_t) seg_offset);
-
- /* if we are looking for a biggest memzone */
- if (len == 0) {
- if (bound == 0)
- requested_len = memseg_len - seg_offset;
- else
- requested_len = RTE_ALIGN_CEIL(memseg_physaddr + 1,
- bound) - memseg_physaddr;
- }
-
- /* set length to correct value */
- len = (size_t)seg_offset + requested_len;
-
- /* update our internal state */
- free_memseg[memseg_idx].len -= len;
- free_memseg[memseg_idx].phys_addr += len;
- free_memseg[memseg_idx].addr =
- (char *)free_memseg[memseg_idx].addr + len;
+ const struct malloc_elem *elem = malloc_elem_from_data(mz_addr);
/* fill the zone in config */
struct rte_memzone *mz = &mcfg->memzone[mcfg->memzone_idx++];
snprintf(mz->name, sizeof(mz->name), "%s", name);
- mz->phys_addr = memseg_physaddr;
- mz->addr = memseg_addr;
- mz->len = requested_len;
- mz->hugepage_sz = free_memseg[memseg_idx].hugepage_sz;
- mz->socket_id = free_memseg[memseg_idx].socket_id;
+ mz->phys_addr = rte_malloc_virt2phy(mz_addr);
+ mz->addr = mz_addr;
+ mz->len = (requested_len == 0 ? elem->size : requested_len);
+ mz->hugepage_sz = elem->ms->hugepage_sz;
+ mz->socket_id = elem->ms->socket_id;
mz->flags = 0;
- mz->memseg_id = memseg_idx;
+ mz->memseg_id = elem->ms - rte_eal_get_configuration()->mem_config->memseg;
return mz;
}
@@ -419,45 +340,6 @@ rte_memzone_dump(FILE *f)
}
/*
- * called by init: modify the free memseg list to have cache-aligned
- * addresses and cache-aligned lengths
- */
-static int
-memseg_sanitize(struct rte_memseg *memseg)
-{
- unsigned phys_align;
- unsigned virt_align;
- unsigned off;
-
- phys_align = memseg->phys_addr & RTE_CACHE_LINE_MASK;
- virt_align = (unsigned long)memseg->addr & RTE_CACHE_LINE_MASK;
-
- /*
- * sanity check: phys_addr and addr must have the same
- * alignment
- */
- if (phys_align != virt_align)
- return -1;
-
- /* memseg is really too small, don't bother with it */
- if (memseg->len < (2 * RTE_CACHE_LINE_SIZE)) {
- memseg->len = 0;
- return 0;
- }
-
- /* align start address */
- off = (RTE_CACHE_LINE_SIZE - phys_align) & RTE_CACHE_LINE_MASK;
- memseg->phys_addr += off;
- memseg->addr = (char *)memseg->addr + off;
- memseg->len -= off;
-
- /* align end address */
- memseg->len &= ~((uint64_t)RTE_CACHE_LINE_MASK);
-
- return 0;
-}
-
-/*
* Init the memzone subsystem
*/
int
@@ -465,14 +347,10 @@ rte_eal_memzone_init(void)
{
struct rte_mem_config *mcfg;
const struct rte_memseg *memseg;
- unsigned i = 0;
/* get pointer to global configuration */
mcfg = rte_eal_get_configuration()->mem_config;
- /* mirror the runtime memsegs from config */
- free_memseg = mcfg->free_memseg;
-
/* secondary processes don't need to initialise anything */
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
return 0;
@@ -485,33 +363,13 @@ rte_eal_memzone_init(void)
rte_rwlock_write_lock(&mcfg->mlock);
- /* fill in uninitialized free_memsegs */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (memseg[i].addr == NULL)
- break;
- if (free_memseg[i].addr != NULL)
- continue;
- memcpy(&free_memseg[i], &memseg[i], sizeof(struct rte_memseg));
- }
-
- /* make all zones cache-aligned */
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if (free_memseg[i].addr == NULL)
- break;
- if (memseg_sanitize(&free_memseg[i]) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Sanity check failed\n", __func__);
- rte_rwlock_write_unlock(&mcfg->mlock);
- return -1;
- }
- }
-
/* delete all zones */
mcfg->memzone_idx = 0;
memset(mcfg->memzone, 0, sizeof(mcfg->memzone));
rte_rwlock_write_unlock(&mcfg->mlock);
- return 0;
+ return rte_eal_malloc_heap_init();
}
/* Walk all reserved memory zones */
diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h
index 34f5abc..055212a 100644
--- a/lib/librte_eal/common/include/rte_eal_memconfig.h
+++ b/lib/librte_eal/common/include/rte_eal_memconfig.h
@@ -73,7 +73,7 @@ struct rte_mem_config {
struct rte_memseg memseg[RTE_MAX_MEMSEG]; /**< Physmem descriptors. */
struct rte_memzone memzone[RTE_MAX_MEMZONE]; /**< Memzone descriptors. */
- /* Runtime Physmem descriptors. */
+ /* Runtime Physmem descriptors - NOT USED */
struct rte_memseg free_memseg[RTE_MAX_MEMSEG];
struct rte_tailq_head tailq_head[RTE_MAX_TAILQ]; /**< Tailqs for objects */
diff --git a/lib/librte_eal/common/include/rte_malloc_heap.h b/lib/librte_eal/common/include/rte_malloc_heap.h
index 716216f..b270356 100644
--- a/lib/librte_eal/common/include/rte_malloc_heap.h
+++ b/lib/librte_eal/common/include/rte_malloc_heap.h
@@ -40,7 +40,7 @@
#include <rte_memory.h>
/* Number of free lists per heap, grouped by size. */
-#define RTE_HEAP_NUM_FREELISTS 5
+#define RTE_HEAP_NUM_FREELISTS 13
/**
* Structure to hold malloc heap
@@ -48,7 +48,6 @@
struct malloc_heap {
rte_spinlock_t lock;
LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
- unsigned mz_count;
unsigned alloc_count;
size_t total_size;
} __rte_cache_aligned;
diff --git a/lib/librte_eal/common/malloc_elem.c b/lib/librte_eal/common/malloc_elem.c
index a5e1248..b54ee33 100644
--- a/lib/librte_eal/common/malloc_elem.c
+++ b/lib/librte_eal/common/malloc_elem.c
@@ -37,7 +37,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_per_lcore.h>
@@ -56,10 +55,10 @@
*/
void
malloc_elem_init(struct malloc_elem *elem,
- struct malloc_heap *heap, const struct rte_memzone *mz, size_t size)
+ struct malloc_heap *heap, const struct rte_memseg *ms, size_t size)
{
elem->heap = heap;
- elem->mz = mz;
+ elem->ms = ms;
elem->prev = NULL;
memset(&elem->free_list, 0, sizeof(elem->free_list));
elem->state = ELEM_FREE;
@@ -70,12 +69,12 @@ malloc_elem_init(struct malloc_elem *elem,
}
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
{
- malloc_elem_init(elem, prev->heap, prev->mz, 0);
+ malloc_elem_init(elem, prev->heap, prev->ms, 0);
elem->prev = prev;
elem->state = ELEM_BUSY; /* mark busy so its never merged */
}
@@ -86,12 +85,24 @@ malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
* fit, return NULL.
*/
static void *
-elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
+elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- const uintptr_t end_pt = (uintptr_t)elem +
+ const size_t bmask = ~(bound - 1);
+ uintptr_t end_pt = (uintptr_t)elem +
elem->size - MALLOC_ELEM_TRAILER_LEN;
- const uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
- const uintptr_t new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
+ uintptr_t new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ uintptr_t new_elem_start;
+
+ /* check boundary */
+ if ((new_data_start & bmask) != ((end_pt - 1) & bmask)) {
+ end_pt = RTE_ALIGN_FLOOR(end_pt, bound);
+ new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+ if (((end_pt - 1) & bmask) != (new_data_start & bmask))
+ return NULL;
+ }
+
+ new_elem_start = new_data_start - MALLOC_ELEM_HEADER_LEN;
/* if the new start point is before the exist start, it won't fit */
return (new_elem_start < (uintptr_t)elem) ? NULL : (void *)new_elem_start;
@@ -102,9 +113,10 @@ elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align)
* alignment request from the current element
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- return elem_start_pt(elem, size, align) != NULL;
+ return elem_start_pt(elem, size, align, bound) != NULL;
}
/*
@@ -115,10 +127,10 @@ static void
split_elem(struct malloc_elem *elem, struct malloc_elem *split_pt)
{
struct malloc_elem *next_elem = RTE_PTR_ADD(elem, elem->size);
- const unsigned old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
- const unsigned new_elem_size = elem->size - old_elem_size;
+ const size_t old_elem_size = (uintptr_t)split_pt - (uintptr_t)elem;
+ const size_t new_elem_size = elem->size - old_elem_size;
- malloc_elem_init(split_pt, elem->heap, elem->mz, new_elem_size);
+ malloc_elem_init(split_pt, elem->heap, elem->ms, new_elem_size);
split_pt->prev = elem;
next_elem->prev = split_pt;
elem->size = old_elem_size;
@@ -168,8 +180,9 @@ malloc_elem_free_list_index(size_t size)
void
malloc_elem_free_list_insert(struct malloc_elem *elem)
{
- size_t idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
+ size_t idx;
+ idx = malloc_elem_free_list_index(elem->size - MALLOC_ELEM_HEADER_LEN);
elem->state = ELEM_FREE;
LIST_INSERT_HEAD(&elem->heap->free_head[idx], elem, free_list);
}
@@ -190,12 +203,26 @@ elem_free_list_remove(struct malloc_elem *elem)
* is not done here, as it's done there previously.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
+malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align,
+ size_t bound)
{
- struct malloc_elem *new_elem = elem_start_pt(elem, size, align);
- const unsigned old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ struct malloc_elem *new_elem = elem_start_pt(elem, size, align, bound);
+ const size_t old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem;
+ const size_t trailer_size = elem->size - old_elem_size - size -
+ MALLOC_ELEM_OVERHEAD;
+
+ elem_free_list_remove(elem);
- if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE){
+ if (trailer_size > MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
+ /* split it, too much free space after elem */
+ struct malloc_elem *new_free_elem =
+ RTE_PTR_ADD(new_elem, size + MALLOC_ELEM_OVERHEAD);
+
+ split_elem(elem, new_free_elem);
+ malloc_elem_free_list_insert(new_free_elem);
+ }
+
+ if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
/* don't split it, pad the element instead */
elem->state = ELEM_BUSY;
elem->pad = old_elem_size;
@@ -208,8 +235,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
new_elem->size = elem->size - elem->pad;
set_header(new_elem);
}
- /* remove element from free list */
- elem_free_list_remove(elem);
return new_elem;
}
@@ -219,7 +244,6 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align)
* Re-insert original element, in case its new size makes it
* belong on a different list.
*/
- elem_free_list_remove(elem);
split_elem(elem, new_elem);
new_elem->state = ELEM_BUSY;
malloc_elem_free_list_insert(elem);
diff --git a/lib/librte_eal/common/malloc_elem.h b/lib/librte_eal/common/malloc_elem.h
index 9790b1a..e05d2ea 100644
--- a/lib/librte_eal/common/malloc_elem.h
+++ b/lib/librte_eal/common/malloc_elem.h
@@ -47,9 +47,9 @@ enum elem_state {
struct malloc_elem {
struct malloc_heap *heap;
- struct malloc_elem *volatile prev; /* points to prev elem in memzone */
+ struct malloc_elem *volatile prev; /* points to prev elem in memseg */
LIST_ENTRY(malloc_elem) free_list; /* list of free elements in heap */
- const struct rte_memzone *mz;
+ const struct rte_memseg *ms;
volatile enum elem_state state;
uint32_t pad;
size_t size;
@@ -136,11 +136,11 @@ malloc_elem_from_data(const void *data)
void
malloc_elem_init(struct malloc_elem *elem,
struct malloc_heap *heap,
- const struct rte_memzone *mz,
+ const struct rte_memseg *ms,
size_t size);
/*
- * initialise a dummy malloc_elem header for the end-of-memzone marker
+ * initialise a dummy malloc_elem header for the end-of-memseg marker
*/
void
malloc_elem_mkend(struct malloc_elem *elem,
@@ -151,14 +151,16 @@ malloc_elem_mkend(struct malloc_elem *elem,
* of the requested size and with the requested alignment
*/
int
-malloc_elem_can_hold(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_can_hold(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* reserve a block of data in an existing malloc_elem. If the malloc_elem
* is much larger than the data block requested, we split the element in two.
*/
struct malloc_elem *
-malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align);
+malloc_elem_alloc(struct malloc_elem *elem, size_t size,
+ unsigned align, size_t bound);
/*
* free a malloc_elem block by adding it to the free list. If the
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index 8861d27..f5fff96 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -39,7 +39,6 @@
#include <sys/queue.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_launch.h>
@@ -54,123 +53,104 @@
#include "malloc_elem.h"
#include "malloc_heap.h"
-/* since the memzone size starts with a digit, it will appear unquoted in
- * rte_config.h, so quote it so it can be passed to rte_str_to_size */
-#define MALLOC_MEMZONE_SIZE RTE_STR(RTE_MALLOC_MEMZONE_SIZE)
-
-/*
- * returns the configuration setting for the memzone size as a size_t value
- */
-static inline size_t
-get_malloc_memzone_size(void)
+static unsigned
+check_hugepage_sz(unsigned flags, size_t hugepage_sz)
{
- return rte_str_to_size(MALLOC_MEMZONE_SIZE);
+ unsigned ret = 1;
+
+ if ((flags & RTE_MEMZONE_2MB) && hugepage_sz == RTE_PGSIZE_1G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_1GB) && hugepage_sz == RTE_PGSIZE_2M)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16MB) && hugepage_sz == RTE_PGSIZE_16G)
+ ret = 0;
+ if ((flags & RTE_MEMZONE_16GB) && hugepage_sz == RTE_PGSIZE_16M)
+ ret = 0;
+
+ return ret;
}
/*
- * reserve an extra memory zone and make it available for use by a particular
- * heap. This reserves the zone and sets a dummy malloc_elem header at the end
+ * Expand the heap with a memseg.
+ * This reserves the zone and sets a dummy malloc_elem header at the end
* to prevent overflow. The rest of the zone is added to free list as a single
* large free block
*/
-static int
-malloc_heap_add_memzone(struct malloc_heap *heap, size_t size, unsigned align)
+static void
+malloc_heap_add_memseg(struct malloc_heap *heap, struct rte_memseg *ms)
{
- const unsigned mz_flags = 0;
- const size_t block_size = get_malloc_memzone_size();
- /* ensure the data we want to allocate will fit in the memzone */
- const size_t min_size = size + align + MALLOC_ELEM_OVERHEAD * 2;
- const struct rte_memzone *mz = NULL;
- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- unsigned numa_socket = heap - mcfg->malloc_heaps;
-
- size_t mz_size = min_size;
- if (mz_size < block_size)
- mz_size = block_size;
-
- char mz_name[RTE_MEMZONE_NAMESIZE];
- snprintf(mz_name, sizeof(mz_name), "MALLOC_S%u_HEAP_%u",
- numa_socket, heap->mz_count++);
-
- /* try getting a block. if we fail and we don't need as big a block
- * as given in the config, we can shrink our request and try again
- */
- do {
- mz = rte_memzone_reserve(mz_name, mz_size, numa_socket,
- mz_flags);
- if (mz == NULL)
- mz_size /= 2;
- } while (mz == NULL && mz_size > min_size);
- if (mz == NULL)
- return -1;
-
/* allocate the memory block headers, one at end, one at start */
- struct malloc_elem *start_elem = (struct malloc_elem *)mz->addr;
- struct malloc_elem *end_elem = RTE_PTR_ADD(mz->addr,
- mz_size - MALLOC_ELEM_OVERHEAD);
+ struct malloc_elem *start_elem = (struct malloc_elem *)ms->addr;
+ struct malloc_elem *end_elem = RTE_PTR_ADD(ms->addr,
+ ms->len - MALLOC_ELEM_OVERHEAD);
end_elem = RTE_PTR_ALIGN_FLOOR(end_elem, RTE_CACHE_LINE_SIZE);
+ const size_t elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- const unsigned elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
- malloc_elem_init(start_elem, heap, mz, elem_size);
+ malloc_elem_init(start_elem, heap, ms, elem_size);
malloc_elem_mkend(end_elem, start_elem);
malloc_elem_free_list_insert(start_elem);
- /* increase heap total size by size of new memzone */
- heap->total_size+=mz_size - MALLOC_ELEM_OVERHEAD;
- return 0;
+ heap->total_size += elem_size;
}
/*
* Iterates through the freelist for a heap to find a free element
* which can store data of the required size and with the requested alignment.
+ * If size is 0, find the biggest available elem.
* Returns null on failure, or pointer to element on success.
*/
static struct malloc_elem *
-find_suitable_element(struct malloc_heap *heap, size_t size, unsigned align)
+find_suitable_element(struct malloc_heap *heap, size_t size,
+ unsigned flags, size_t align, size_t bound)
{
size_t idx;
- struct malloc_elem *elem;
+ struct malloc_elem *elem, *alt_elem = NULL;
for (idx = malloc_elem_free_list_index(size);
- idx < RTE_HEAP_NUM_FREELISTS; idx++)
- {
+ idx < RTE_HEAP_NUM_FREELISTS; idx++) {
for (elem = LIST_FIRST(&heap->free_head[idx]);
- !!elem; elem = LIST_NEXT(elem, free_list))
- {
- if (malloc_elem_can_hold(elem, size, align))
- return elem;
+ !!elem; elem = LIST_NEXT(elem, free_list)) {
+ if (malloc_elem_can_hold(elem, size, align, bound)) {
+ if (check_hugepage_sz(flags, elem->ms->hugepage_sz))
+ return elem;
+ alt_elem = elem;
+ }
}
}
+
+ if ((alt_elem != NULL) && (flags & RTE_MEMZONE_SIZE_HINT_ONLY))
+ return alt_elem;
+
return NULL;
}
/*
- * Main function called by malloc to allocate a block of memory from the
- * heap. It locks the free list, scans it, and adds a new memzone if the
- * scan fails. Once the new memzone is added, it re-scans and should return
+ * Main function to allocate a block of memory from the heap.
+ * It locks the free list, scans it, and adds a new memseg if the
+ * scan fails. Once the new memseg is added, it re-scans and should return
* the new element after releasing the lock.
*/
void *
malloc_heap_alloc(struct malloc_heap *heap,
- const char *type __attribute__((unused)), size_t size, unsigned align)
+ const char *type __attribute__((unused)), size_t size, unsigned flags,
+ size_t align, size_t bound)
{
+ struct malloc_elem *elem;
+
size = RTE_CACHE_LINE_ROUNDUP(size);
align = RTE_CACHE_LINE_ROUNDUP(align);
+
rte_spinlock_lock(&heap->lock);
- struct malloc_elem *elem = find_suitable_element(heap, size, align);
- if (elem == NULL){
- if ((malloc_heap_add_memzone(heap, size, align)) == 0)
- elem = find_suitable_element(heap, size, align);
- }
- if (elem != NULL){
- elem = malloc_elem_alloc(elem, size, align);
+ elem = find_suitable_element(heap, size, flags, align, bound);
+ if (elem != NULL) {
+ elem = malloc_elem_alloc(elem, size, align, bound);
/* increase heap's count of allocated elements */
heap->alloc_count++;
}
rte_spinlock_unlock(&heap->lock);
- return elem == NULL ? NULL : (void *)(&elem[1]);
+ return elem == NULL ? NULL : (void *)(&elem[1]);
}
/*
@@ -206,3 +186,21 @@ malloc_heap_get_stats(const struct malloc_heap *heap,
socket_stats->alloc_count = heap->alloc_count;
return 0;
}
+
+int
+rte_eal_malloc_heap_init(void)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ unsigned ms_cnt;
+ struct rte_memseg *ms;
+
+ if (mcfg == NULL)
+ return -1;
+
+ for (ms = &mcfg->memseg[0], ms_cnt = 0;
+ (ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0);
+ ms_cnt++, ms++)
+ malloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms);
+
+ return 0;
+}
diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h
index a47136d..3ccbef0 100644
--- a/lib/librte_eal/common/malloc_heap.h
+++ b/lib/librte_eal/common/malloc_heap.h
@@ -53,15 +53,15 @@ malloc_get_numa_socket(void)
}
void *
-malloc_heap_alloc(struct malloc_heap *heap, const char *type,
- size_t size, unsigned align);
+malloc_heap_alloc(struct malloc_heap *heap, const char *type, size_t size,
+ unsigned flags, size_t align, size_t bound);
int
malloc_heap_get_stats(const struct malloc_heap *heap,
struct rte_malloc_socket_stats *socket_stats);
int
-rte_eal_heap_memzone_init(void);
+rte_eal_malloc_heap_init(void);
#ifdef __cplusplus
}
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index c313a57..54c2bd8 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -39,7 +39,6 @@
#include <rte_memcpy.h>
#include <rte_memory.h>
-#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_branch_prediction.h>
@@ -87,7 +86,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
return NULL;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[socket], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL || socket_arg != SOCKET_ID_ANY)
return ret;
@@ -98,7 +97,7 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
continue;
ret = malloc_heap_alloc(&mcfg->malloc_heaps[i], type,
- size, align == 0 ? 1 : align);
+ size, 0, align == 0 ? 1 : align, 0);
if (ret != NULL)
return ret;
}
@@ -256,5 +255,5 @@ rte_malloc_virt2phy(const void *addr)
const struct malloc_elem *elem = malloc_elem_from_data(addr);
if (elem == NULL)
return 0;
- return elem->mz->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->mz->addr);
+ return elem->ms->phys_addr + ((uintptr_t)addr - (uintptr_t)elem->ms->addr);
}
--
1.9.3
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v7 8/9] doc: announce ABI change of librte_malloc
2015-07-03 9:55 4% ` [dpdk-dev] [PATCH v7 " Sergio Gonzalez Monroy
2015-07-03 9:55 1% ` [dpdk-dev] [PATCH v7 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
@ 2015-07-03 9:55 14% ` Sergio Gonzalez Monroy
1 sibling, 0 replies; 200+ results
From: Sergio Gonzalez Monroy @ 2015-07-03 9:55 UTC (permalink / raw)
To: dev
Announce the creation of dummy malloc library for 2.1 and removal of
such library, now integrated in librte_eal, for 2.2 release.
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
doc/guides/rel_notes/abi.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index 110c486..50fb6a5 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -12,3 +12,4 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* librte_malloc library has been integrated into librte_eal. The 2.1 release creates a dummy/empty malloc library to fulfill binaries with dynamic linking dependencies on librte_malloc.so. Such dummy library will not be created from release 2.2 so binaries will need to be rebuilt.
--
1.9.3
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [PATCH v4 0/8] Expose IXGBE extended stats to DPDK apps
@ 2015-07-05 17:39 3% Maryam Tahhan
2015-07-05 17:39 9% ` [dpdk-dev] [PATCH v4 4/8] ethdev: remove HW specific stats in stats structs Maryam Tahhan
0 siblings, 1 reply; 200+ results
From: Maryam Tahhan @ 2015-07-05 17:39 UTC (permalink / raw)
To: dev
This patch set implements xstats_get() and xstats_reset() in dev_ops for
ixgbe to expose detailed error statistics to DPDK applications. The
dump_cfg application was extended to demonstrate the usage of
retrieving statistics for DPDK interfaces and renamed to proc_info
in order reflect this new functionality. This patch set also removes non
generic statistics from the statistics strings at the ethdev level and
marks the relevant registers as depricated in struct rte_eth_stats.
v2:
- Fixed patch dependencies.
- Broke down patches into smaller logical changes.
v3:
- Removes non-generic stats fields in rte_stats_strings and deprecates
the fields related to them in struct rte_eth_stats.
- Modifies rte_eth_xstats_get() to return generic stats and extended stats.
v4:
- Replace count use in the loop in ixgbe_dev_xstats_get() function definition with i.
- Breakdown "ixgbe: add NIC specific stats removed from ethdev" into two patches, one
that adds the stats and another that extends ierrors to include more error stats.
- Remove second call to ixgbe_dev_xstats_get() from rte_eth_xstats_get().
Maryam Tahhan (8):
ixgbe: move stats register reads to a new function
ixgbe: add functions to get and reset xstats
ethdev: expose extended error stats
ethdev: remove HW specific stats in stats structs
ixgbe: add NIC specific stats removed from ethdev
ixgbe: return more errors in ierrors
app: remove dump_cfg
app: add a new app proc_info
MAINTAINERS | 4 +
app/Makefile | 2 +-
app/dump_cfg/Makefile | 45 ----
app/dump_cfg/main.c | 92 -------
app/proc_info/Makefile | 45 ++++
app/proc_info/main.c | 512 +++++++++++++++++++++++++++++++++++++++
doc/guides/rel_notes/abi.rst | 11 +
drivers/net/ixgbe/ixgbe_ethdev.c | 194 ++++++++++++---
lib/librte_ether/rte_ethdev.c | 34 ++-
lib/librte_ether/rte_ethdev.h | 30 ++-
mk/rte.sdktest.mk | 4 +-
11 files changed, 767 insertions(+), 206 deletions(-)
delete mode 100644 app/dump_cfg/Makefile
delete mode 100644 app/dump_cfg/main.c
create mode 100644 app/proc_info/Makefile
create mode 100644 app/proc_info/main.c
--
1.9.3
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v4 4/8] ethdev: remove HW specific stats in stats structs
2015-07-05 17:39 3% [dpdk-dev] [PATCH v4 0/8] Expose IXGBE extended stats to DPDK apps Maryam Tahhan
@ 2015-07-05 17:39 9% ` Maryam Tahhan
0 siblings, 0 replies; 200+ results
From: Maryam Tahhan @ 2015-07-05 17:39 UTC (permalink / raw)
To: dev
Remove non generic stats in rte_stats_strings and mark the relevant
fields in struct rte_eth_stats as deprecated.
Signed-off-by: Maryam Tahhan <maryam.tahhan@intel.com>
---
doc/guides/rel_notes/abi.rst | 11 +++++++++++
lib/librte_ether/rte_ethdev.c | 9 ---------
lib/librte_ether/rte_ethdev.h | 30 ++++++++++++++++++++----------
3 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index 110c486..90fe7fa 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -12,3 +12,14 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* The following fields have been deprecated in rte_eth_stats:
+ * uint64_t imissed
+ * uint64_t ibadcrc
+ * uint64_t ibadlen
+ * uint64_t imcasts
+ * uint64_t fdirmatch
+ * uint64_t fdirmiss
+ * uint64_t tx_pause_xon
+ * uint64_t rx_pause_xon
+ * uint64_t tx_pause_xoff
+ * uint64_t rx_pause_xoff
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index e392f60..003c548 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -142,17 +142,8 @@ static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
{"rx_bytes", offsetof(struct rte_eth_stats, ibytes)},
{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
- {"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)},
- {"rx_crc_errors", offsetof(struct rte_eth_stats, ibadcrc)},
- {"rx_bad_length_errors", offsetof(struct rte_eth_stats, ibadlen)},
{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
{"alloc_rx_buff_failed", offsetof(struct rte_eth_stats, rx_nombuf)},
- {"fdir_match", offsetof(struct rte_eth_stats, fdirmatch)},
- {"fdir_miss", offsetof(struct rte_eth_stats, fdirmiss)},
- {"tx_flow_control_xon", offsetof(struct rte_eth_stats, tx_pause_xon)},
- {"rx_flow_control_xon", offsetof(struct rte_eth_stats, rx_pause_xon)},
- {"tx_flow_control_xoff", offsetof(struct rte_eth_stats, tx_pause_xoff)},
- {"rx_flow_control_xoff", offsetof(struct rte_eth_stats, rx_pause_xoff)},
};
#define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index f1219ac..a38d49a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -193,19 +193,29 @@ struct rte_eth_stats {
uint64_t opackets; /**< Total number of successfully transmitted packets.*/
uint64_t ibytes; /**< Total number of successfully received bytes. */
uint64_t obytes; /**< Total number of successfully transmitted bytes. */
- uint64_t imissed; /**< Total of RX missed packets (e.g full FIFO). */
- uint64_t ibadcrc; /**< Total of RX packets with CRC error. */
- uint64_t ibadlen; /**< Total of RX packets with bad length. */
+ /**< Deprecated; Total of RX missed packets (e.g full FIFO). */
+ uint64_t imissed;
+ /**< Deprecated; Total of RX packets with CRC error. */
+ uint64_t ibadcrc;
+ /**< Deprecated; Total of RX packets with bad length. */
+ uint64_t ibadlen;
uint64_t ierrors; /**< Total number of erroneous received packets. */
uint64_t oerrors; /**< Total number of failed transmitted packets. */
- uint64_t imcasts; /**< Total number of multicast received packets. */
+ uint64_t imcasts;
+ /**< Deprecated; Total number of multicast received packets. */
uint64_t rx_nombuf; /**< Total number of RX mbuf allocation failures. */
- uint64_t fdirmatch; /**< Total number of RX packets matching a filter. */
- uint64_t fdirmiss; /**< Total number of RX packets not matching any filter. */
- uint64_t tx_pause_xon; /**< Total nb. of XON pause frame sent. */
- uint64_t rx_pause_xon; /**< Total nb. of XON pause frame received. */
- uint64_t tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */
- uint64_t rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */
+ uint64_t fdirmatch;
+ /**< Deprecated; Total number of RX packets matching a filter. */
+ uint64_t fdirmiss;
+ /**< Deprecated; Total number of RX packets not matching any filter. */
+ uint64_t tx_pause_xon;
+ /**< Deprecated; Total nb. of XON pause frame sent. */
+ uint64_t rx_pause_xon;
+ /**< Deprecated; Total nb. of XON pause frame received. */
+ uint64_t tx_pause_xoff;
+ /**< Deprecated; Total nb. of XOFF pause frame sent. */
+ uint64_t rx_pause_xoff;
+ /**< Deprecated; Total nb. of XOFF pause frame received. */
uint64_t q_ipackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
/**< Total number of queue RX packets. */
uint64_t q_opackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
--
1.9.3
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf
2015-06-26 7:03 5% ` Wu, Jingjing
@ 2015-07-06 1:27 0% ` Wu, Jingjing
2015-07-07 14:51 4% ` Thomas Monjalon
1 sibling, 0 replies; 200+ results
From: Wu, Jingjing @ 2015-07-06 1:27 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
Hi, Thomas
Any suggestions about this patch? Do I need rework it by using macro RTE_NEXT_ABI?
Thanks a lot!
Jingjing
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wu, Jingjing
> Sent: Friday, June 26, 2015 3:03 PM
> To: 'nhorman@tuxdriver.com'
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename
> rte_eth_vmdq_mirror_conf
>
> Hi, Neil
>
> About this patch I have an ABI concern about it.
> This patch just renamed a struct rte_eth_vmdq_mirror_conf to
> rte_eth_mirror_conf, the size and its elements don't change. As my
> understanding, it will not break the ABI. And I also tested it.
> But when I use the script ./scripts/validate-abi.sh to check. A low severity
> problem is reported in symbol "rte_eth_mirror_rule_set"
> - Change: "Base type of 2nd parameter mirror_conf has been changed from
> struct rte_eth_vmdq_mirror_conf to struct rte_eth_mirror_conf."
> - Effect: "Replacement of parameter base type may indicate a change in its
> semantic meaning."
>
> So, I'm not sure whether this patch meet the ABI policy?
>
> Additional, about the validate-abi.sh, does it mean we need to fix all the
> problems it reports? Or we can decide case by case. Can a Low Severity
> problem be acceptable?
>
> Look forward to your reply.
>
> Thanks
>
> Jingjing
>
> > -----Original Message-----
> > From: Wu, Jingjing
> > Sent: Wednesday, June 10, 2015 2:25 PM
> > To: dev@dpdk.org
> > Cc: Wu, Jingjing; Liu, Jijiang; Jiajia, SunX; Zhang, Helin
> > Subject: [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf
> >
> > rename rte_eth_vmdq_mirror_conf to rte_eth_mirror_conf and move the
> > maximum rule id check from ethdev level to driver
> >
> > Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> > ---
> > app/test-pmd/cmdline.c | 22 +++++++++++-----------
> > drivers/net/ixgbe/ixgbe_ethdev.c | 11 +++++++----
> > drivers/net/ixgbe/ixgbe_ethdev.h | 4 +++-
> > lib/librte_ether/rte_ethdev.c | 18 ++----------------
> > lib/librte_ether/rte_ethdev.h | 19 ++++++++++---------
> > 5 files changed, 33 insertions(+), 41 deletions(-)
> >
> > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> > f01db2a..d693bde 100644
> > --- a/app/test-pmd/cmdline.c
> > +++ b/app/test-pmd/cmdline.c
> > @@ -6604,11 +6604,11 @@ cmd_set_mirror_mask_parsed(void
> > *parsed_result, {
> > int ret,nb_item,i;
> > struct cmd_set_mirror_mask_result *res = parsed_result;
> > - struct rte_eth_vmdq_mirror_conf mr_conf;
> > + struct rte_eth_mirror_conf mr_conf;
> >
> > - memset(&mr_conf,0,sizeof(struct rte_eth_vmdq_mirror_conf));
> > + memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
> >
> > - unsigned int vlan_list[ETH_VMDQ_MAX_VLAN_FILTERS];
> > + unsigned int vlan_list[ETH_MIRROR_MAX_VLANS];
> >
> > mr_conf.dst_pool = res->dstpool_id;
> >
> > @@ -6618,11 +6618,11 @@ cmd_set_mirror_mask_parsed(void
> > *parsed_result,
> > } else if(!strcmp(res->what, "vlan-mirror")) {
> > mr_conf.rule_type_mask = ETH_VMDQ_VLAN_MIRROR;
> > nb_item = parse_item_list(res->value, "core",
> > -
> > ETH_VMDQ_MAX_VLAN_FILTERS,vlan_list,1);
> > + ETH_MIRROR_MAX_VLANS, vlan_list,
> > 1);
> > if (nb_item <= 0)
> > return;
> >
> > - for(i=0; i < nb_item; i++) {
> > + for (i = 0; i < nb_item; i++) {
> > if (vlan_list[i] > ETHER_MAX_VLAN_ID) {
> > printf("Invalid vlan_id: must be < 4096\n");
> > return;
> > @@ -6634,10 +6634,10 @@ cmd_set_mirror_mask_parsed(void
> > *parsed_result,
> > }
> >
> > if(!strcmp(res->on, "on"))
> > - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
> > + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
> > res->rule_id, 1);
> > else
> > - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
> > + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
> > res->rule_id, 0);
> > if(ret < 0)
> > printf("mirror rule add error: (%s)\n", strerror(-ret)); @@ -
> > 6711,9 +6711,9 @@ cmd_set_mirror_link_parsed(void *parsed_result, {
> > int ret;
> > struct cmd_set_mirror_link_result *res = parsed_result;
> > - struct rte_eth_vmdq_mirror_conf mr_conf;
> > + struct rte_eth_mirror_conf mr_conf;
> >
> > - memset(&mr_conf,0,sizeof(struct rte_eth_vmdq_mirror_conf));
> > + memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
> > if(!strcmp(res->what, "uplink-mirror")) {
> > mr_conf.rule_type_mask = ETH_VMDQ_UPLINK_MIRROR;
> > }else if(!strcmp(res->what, "downlink-mirror")) @@ -6722,10
> > +6722,10 @@ cmd_set_mirror_link_parsed(void *parsed_result,
> > mr_conf.dst_pool = res->dstpool_id;
> >
> > if(!strcmp(res->on, "on"))
> > - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
> > + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
> > res->rule_id, 1);
> > else
> > - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
> > + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
> > res->rule_id, 0);
> >
> > /* check the return value and print it if is < 0 */ diff --git
> > a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> > index 0d9f9b2..9e767fa 100644
> > --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> > +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> > @@ -209,7 +209,7 @@ static int ixgbe_set_pool_tx(struct rte_eth_dev
> > *dev,uint16_t pool,uint8_t on); static int
> > ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
> > uint64_t pool_mask,uint8_t vlan_on); static int
> > ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
> > - struct rte_eth_vmdq_mirror_conf *mirror_conf,
> > + struct rte_eth_mirror_conf *mirror_conf,
> > uint8_t rule_id, uint8_t on);
> > static int ixgbe_mirror_rule_reset(struct rte_eth_dev *dev,
> > uint8_t rule_id);
> > @@ -3388,7 +3388,7 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev
> > *dev, uint16_t vlan,
> >
> > static int
> > ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
> > - struct rte_eth_vmdq_mirror_conf *mirror_conf,
> > + struct rte_eth_mirror_conf *mirror_conf,
> > uint8_t rule_id, uint8_t on)
> > {
> > uint32_t mr_ctl,vlvf;
> > @@ -3412,7 +3412,10 @@ ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
> > IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> >
> > if (ixgbe_vmdq_mode_check(hw) < 0)
> > - return (-ENOTSUP);
> > + return -ENOTSUP;
> > +
> > + if (rule_id >= IXGBE_MAX_MIRROR_RULES)
> > + return -EINVAL;
> >
> > /* Check if vlan mask is valid */
> > if ((mirror_conf->rule_type_mask & ETH_VMDQ_VLAN_MIRROR)
> && (on)) {
> > @@ -3526,7 +3529,7 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev
> *dev,
> > uint8_t rule_id)
> > return (-ENOTSUP);
> >
> > memset(&mr_info->mr_conf[rule_id], 0,
> > - sizeof(struct rte_eth_vmdq_mirror_conf));
> > + sizeof(struct rte_eth_mirror_conf));
> >
> > /* clear PFVMCTL register */
> > IXGBE_WRITE_REG(hw, IXGBE_MRCTL(rule_id), mr_ctl); diff --git
> > a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
> > index 19237b8..755b674 100644
> > --- a/drivers/net/ixgbe/ixgbe_ethdev.h
> > +++ b/drivers/net/ixgbe/ixgbe_ethdev.h
> > @@ -177,8 +177,10 @@ struct ixgbe_uta_info {
> > uint32_t uta_shadow[IXGBE_MAX_UTA];
> > };
> >
> > +#define IXGBE_MAX_MIRROR_RULES 4 /* Maximum nb. of mirror rules.
> */
> > +
> > struct ixgbe_mirror_info {
> > - struct rte_eth_vmdq_mirror_conf
> > mr_conf[ETH_VMDQ_NUM_MIRROR_RULE];
> > + struct rte_eth_mirror_conf mr_conf[IXGBE_MAX_MIRROR_RULES];
> > /**< store PF mirror rules configuration*/ };
> >
> > diff --git a/lib/librte_ether/rte_ethdev.c
> > b/lib/librte_ether/rte_ethdev.c index 024fe8b..43c7295 100644
> > --- a/lib/librte_ether/rte_ethdev.c
> > +++ b/lib/librte_ether/rte_ethdev.c
> > @@ -3034,7 +3034,7 @@ int rte_eth_set_vf_rate_limit(uint8_t port_id,
> > uint16_t vf, uint16_t tx_rate,
> >
> > int
> > rte_eth_mirror_rule_set(uint8_t port_id,
> > - struct rte_eth_vmdq_mirror_conf *mirror_conf,
> > + struct rte_eth_mirror_conf *mirror_conf,
> > uint8_t rule_id, uint8_t on)
> > {
> > struct rte_eth_dev *dev = &rte_eth_devices[port_id]; @@ -3051,7
> > +3051,7 @@ rte_eth_mirror_rule_set(uint8_t port_id,
> >
> > if (mirror_conf->dst_pool >= ETH_64_POOLS) {
> > PMD_DEBUG_TRACE("Invalid dst pool, pool id must"
> > - "be 0-%d\n",ETH_64_POOLS - 1);
> > + "be 0-%d\n", ETH_64_POOLS - 1);
> > return -EINVAL;
> > }
> >
> > @@ -3062,13 +3062,6 @@ rte_eth_mirror_rule_set(uint8_t port_id,
> > return -EINVAL;
> > }
> >
> > - if(rule_id >= ETH_VMDQ_NUM_MIRROR_RULE)
> > - {
> > - PMD_DEBUG_TRACE("Invalid rule_id, rule_id must be 0-
> > %d\n",
> > - ETH_VMDQ_NUM_MIRROR_RULE - 1);
> > - return -EINVAL;
> > - }
> > -
> > dev = &rte_eth_devices[port_id];
> > FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -
> ENOTSUP);
> >
> > @@ -3085,13 +3078,6 @@ rte_eth_mirror_rule_reset(uint8_t port_id,
> > uint8_t rule_id)
> > return -ENODEV;
> > }
> >
> > - if(rule_id >= ETH_VMDQ_NUM_MIRROR_RULE)
> > - {
> > - PMD_DEBUG_TRACE("Invalid rule_id, rule_id must be 0-
> > %d\n",
> > - ETH_VMDQ_NUM_MIRROR_RULE-1);
> > - return -EINVAL;
> > - }
> > -
> > dev = &rte_eth_devices[port_id];
> > FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_reset, -
> ENOTSUP);
> >
> > diff --git a/lib/librte_ether/rte_ethdev.h
> > b/lib/librte_ether/rte_ethdev.h index 16dbe00..ae22fea 100644
> > --- a/lib/librte_ether/rte_ethdev.h
> > +++ b/lib/librte_ether/rte_ethdev.h
> > @@ -467,8 +467,8 @@ struct rte_eth_rss_conf {
> > #define ETH_VMDQ_ACCEPT_BROADCAST 0x0008 /**< accept broadcast
> > packets. */
> > #define ETH_VMDQ_ACCEPT_MULTICAST 0x0010 /**< multicast
> > promiscuous. */
> >
> > -/* Definitions used for VMDQ mirror rules setting */
> > -#define ETH_VMDQ_NUM_MIRROR_RULE 4 /**< Maximum nb. of
> mirror
> > rules. . */
> > +/** Maximum nb. of vlan per mirror rule */
> > +#define ETH_MIRROR_MAX_VLANS 64
> >
> > #define ETH_VMDQ_POOL_MIRROR 0x0001 /**< Virtual Pool Mirroring.
> */
> > #define ETH_VMDQ_UPLINK_MIRROR 0x0002 /**< Uplink Port Mirroring.
> > */ @@ -480,18 +480,19 @@ struct rte_eth_rss_conf {
> > */
> > struct rte_eth_vlan_mirror {
> > uint64_t vlan_mask; /**< mask for valid VLAN ID. */
> > - uint16_t vlan_id[ETH_VMDQ_MAX_VLAN_FILTERS];
> > - /** VLAN ID list for vlan mirror. */
> > + /** VLAN ID list for vlan mirroring. */
> > + uint16_t vlan_id[ETH_MIRROR_MAX_VLANS];
> > };
> >
> > /**
> > * A structure used to configure traffic mirror of an Ethernet port.
> > */
> > -struct rte_eth_vmdq_mirror_conf {
> > +struct rte_eth_mirror_conf {
> > uint8_t rule_type_mask; /**< Mirroring rule type mask we want to
> set
> > */
> > - uint8_t dst_pool; /**< Destination pool for this mirror rule. */
> > + uint8_t dst_pool; /**< Destination pool for this mirror rule. */
> > uint64_t pool_mask; /**< Bitmap of pool for pool mirroring */
> > - struct rte_eth_vlan_mirror vlan; /**< VLAN ID setting for VLAN
> > mirroring */
> > + /** VLAN ID setting for VLAN mirroring. */
> > + struct rte_eth_vlan_mirror vlan;
> > };
> >
> > /**
> > @@ -1211,7 +1212,7 @@ typedef int (*eth_set_vf_rate_limit_t)(struct
> > rte_eth_dev *dev, /**< @internal Set VF TX rate */
> >
> > typedef int (*eth_mirror_rule_set_t)(struct rte_eth_dev *dev,
> > - struct rte_eth_vmdq_mirror_conf
> > *mirror_conf,
> > + struct rte_eth_mirror_conf *mirror_conf,
> > uint8_t rule_id,
> > uint8_t on);
> > /**< @internal Add a traffic mirroring rule on an Ethernet device */
> > @@ -
> > 3168,7 +3169,7 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port,
> > uint16_t vlan_id,
> > * - (-EINVAL) if the mr_conf information is not correct.
> > */
> > int rte_eth_mirror_rule_set(uint8_t port_id,
> > - struct rte_eth_vmdq_mirror_conf *mirror_conf,
> > + struct rte_eth_mirror_conf *mirror_conf,
> > uint8_t rule_id,
> > uint8_t on);
> >
> > --
> > 1.9.3
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2
2015-07-02 15:16 14% ` [dpdk-dev] [PATCH v3 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
@ 2015-07-06 13:16 4% ` Thomas Monjalon
2015-07-08 13:10 7% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-07-06 13:16 UTC (permalink / raw)
To: dev, nhorman
2015-07-02 16:16, John McNamara:
> --- a/doc/guides/rel_notes/abi.rst
> +++ b/doc/guides/rel_notes/abi.rst
> Deprecation Notices
> -------------------
> +
> +* In DPDK 2.1 the IEEE1588/802.1AS support in the i40e driver makes use of the
> + ``udata64`` field in the mbuf to pass the timesync register index to the
> + user. In DPDK 2.2 this will be moved to a new field in the mbuf.
We need more acknowledgements for this decision, as stated here:
http://dpdk.org/browse/dpdk/tree/doc/guides/guidelines/versioning.rst#n51
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-02 22:05 20% [dpdk-dev] [PATCH] mk: enable next abi in static libs Thomas Monjalon
@ 2015-07-06 13:18 4% ` Thomas Monjalon
2015-07-06 13:35 9% ` Neil Horman
2015-07-08 14:55 8% ` [dpdk-dev] [PATCH v2 0/2] next abi option Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-07-06 13:18 UTC (permalink / raw)
To: dev
Any comment or ack?
2015-07-03 00:05, Thomas Monjalon:
> When a change makes really hard to keep ABI compatibility,
> instead of waiting next release to break the ABI, it is smoother
> to introduce the new code and enable it only for static libraries.
> The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> When the release is out, a dynamically linked application can use
> the new shared libraries without rebuild while developpers can prepare
> their application for the next ABI by reading the deprecation notice
> and easily testing the new code.
> When starting the next release cycle, the "ifdefs" will be removed
> and the ABI break will be marked by incrementing LIBABIVER.
>
> The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> It is automatically enabled for static libraries and disabled for
> shared libraries.
> It can be forced to another value by editing the generated .config file.
> It shouldn't be enabled for shared libraries because it would break the
> ABI without changing the version number LIBABIVER. That's why a warning
> is printed in this case.
>
> The guideline is also updated to integrate this new possibility.
>
> Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-06 13:18 4% ` Thomas Monjalon
@ 2015-07-06 13:35 9% ` Neil Horman
2015-07-06 13:49 8% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-07-06 13:35 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Mon, Jul 06, 2015 at 03:18:51PM +0200, Thomas Monjalon wrote:
> Any comment or ack?
>
> 2015-07-03 00:05, Thomas Monjalon:
> > When a change makes really hard to keep ABI compatibility,
> > instead of waiting next release to break the ABI, it is smoother
> > to introduce the new code and enable it only for static libraries.
> > The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> > When the release is out, a dynamically linked application can use
> > the new shared libraries without rebuild while developpers can prepare
> > their application for the next ABI by reading the deprecation notice
> > and easily testing the new code.
> > When starting the next release cycle, the "ifdefs" will be removed
> > and the ABI break will be marked by incrementing LIBABIVER.
> >
> > The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> > templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> > It is automatically enabled for static libraries and disabled for
> > shared libraries.
> > It can be forced to another value by editing the generated .config file.
> > It shouldn't be enabled for shared libraries because it would break the
> > ABI without changing the version number LIBABIVER. That's why a warning
> > is printed in this case.
> >
> > The guideline is also updated to integrate this new possibility.
> >
> > Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
>
>
Yeah, I'm not sure why this is necessecary. That is to say, if you want to
introduce a new ABI operation prior to the old one being removed, that is precisely what
the versioning macros are for, and can be used to map the static api to the new
version. e.g, given function X that you want to enhance in an ABI breaking way:
1) Separate function X to X_v1 and X_v2
2) Map X_v2 to X@DPDK_v2, map X_v1 to X@DPDK_v1
3) Map the static symbol X to X_v2
4) Post the deprecation notice of X for release 3 immediately
Splitting the static ABI from the shared ABI just means that applications will
have the opportunity to isolate themselves to one kind of build, which is a bad
idea.
Neil
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-06 13:35 9% ` Neil Horman
@ 2015-07-06 13:49 8% ` Thomas Monjalon
2015-07-06 18:22 9% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-07-06 13:49 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-07-06 09:35, Neil Horman:
> On Mon, Jul 06, 2015 at 03:18:51PM +0200, Thomas Monjalon wrote:
> > Any comment or ack?
> >
> > 2015-07-03 00:05, Thomas Monjalon:
> > > When a change makes really hard to keep ABI compatibility,
> > > instead of waiting next release to break the ABI, it is smoother
> > > to introduce the new code and enable it only for static libraries.
> > > The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> > > When the release is out, a dynamically linked application can use
> > > the new shared libraries without rebuild while developpers can prepare
> > > their application for the next ABI by reading the deprecation notice
> > > and easily testing the new code.
> > > When starting the next release cycle, the "ifdefs" will be removed
> > > and the ABI break will be marked by incrementing LIBABIVER.
> > >
> > > The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> > > templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> > > It is automatically enabled for static libraries and disabled for
> > > shared libraries.
> > > It can be forced to another value by editing the generated .config file.
> > > It shouldn't be enabled for shared libraries because it would break the
> > > ABI without changing the version number LIBABIVER. That's why a warning
> > > is printed in this case.
> > >
> > > The guideline is also updated to integrate this new possibility.
> > >
> > > Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
> >
> >
> Yeah, I'm not sure why this is necessecary. That is to say, if you want to
It's explained at the beginning:
"When a change makes really hard to keep ABI compatibility", e.g. mbuf change.
> introduce a new ABI operation prior to the old one being removed, that is precisely what
> the versioning macros are for, and can be used to map the static api to the new
> version. e.g, given function X that you want to enhance in an ABI breaking way:
>
> 1) Separate function X to X_v1 and X_v2
> 2) Map X_v2 to X@DPDK_v2, map X_v1 to X@DPDK_v1
> 3) Map the static symbol X to X_v2
> 4) Post the deprecation notice of X for release 3 immediately
We cannot do that for mbuf change.
> Splitting the static ABI from the shared ABI just means that applications will
> have the opportunity to isolate themselves to one kind of build, which is a bad
> idea.
It helps to be prepared for the next release by testing the app with static libraries.
We agreed to allow API breaking for important changes like mbuf rework.
This option NEXT_ABI is a step between announcement and effective ABI breaking.
I think it's a reasonnable approach. But if nobody ack it, I'm perfectly OK to
drop it and related features (unified packet type and interrupt mode).
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v2] doc: fix minor sphinx build warning
2015-07-02 14:15 8% [dpdk-dev] [PATCH v2] doc: fix minor sphinx build warning John McNamara
@ 2015-07-06 14:55 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-06 14:55 UTC (permalink / raw)
To: John McNamara; +Cc: dev
2015-07-02 15:15, John McNamara:
> Fix for a minor Sphinx build warning in the ABI guidelines docs:
>
> versioning.rst:126: WARNING: Bullet list ends without a
> blank line; unexpected unindent.
>
> Signed-off-by: John McNamara <john.mcnamara@intel.com>
Applied, thanks
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 4/4] ethdev: check support for rx_queue_count and descriptor_done fns
@ 2015-07-06 15:11 3% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-06 15:11 UTC (permalink / raw)
To: nhorman; +Cc: dev
Neil, your ABI expertise is required for this patch.
2015-06-15 11:14, Bruce Richardson:
> On Fri, Jun 12, 2015 at 01:32:56PM -0400, Roger B. Melton wrote:
> > Hi Bruce, Comment in-line. Regards, Roger
> >
> > On 6/12/15 7:28 AM, Bruce Richardson wrote:
> > >The functions rte_eth_rx_queue_count and rte_eth_descriptor_done are
> > >supported by very few PMDs. Therefore, it is best to check for support
> > >for the functions in the ethdev library, so as to avoid crashes
> > >at run-time if the application goes to use those APIs. The performance
> > >impact of this change should be very small as this is a predictable
> > >branch in the function.
> > >
> > >Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > >---
> > > lib/librte_ether/rte_ethdev.h | 8 ++++++--
> > > 1 file changed, 6 insertions(+), 2 deletions(-)
> > >
> > >diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> > >index 827ca3e..9ad1b6a 100644
> > >--- a/lib/librte_ether/rte_ethdev.h
> > >+++ b/lib/librte_ether/rte_ethdev.h
> > >@@ -2496,6 +2496,8 @@ rte_eth_rx_burst(uint8_t port_id, uint16_t queue_id,
> > > * The queue id on the specific port.
> > > * @return
> > > * The number of used descriptors in the specific queue.
> > >+ * NOTE: if function is not supported by device this call
> > >+ * returns (uint32_t)-ENOTSUP
> > > */
> > > static inline uint32_t
> >
> > Why not change the return type to int32_t?
> > In this way, the caller isn't required to make the assumption that a large
> > queue count indicates an error. < 0 means error, other wise it's a valid
> > queue count.
> >
> > This approach would be consistent with other APIs.
> >
>
> Yes, good point, I should see about that. One thing I'm unsure of, though, is
> does this count as ABI breakage? I don't see how it should break any older
> apps, since the return type is the same size, but I'm not sure as we are
> changing the return type of the function.
>
> Neil, can you perhaps comment here? Is changing uint32_t to int32_t ok, from
> an ABI point of view?
>
> Regards,
> /Bruce
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-06 13:49 8% ` Thomas Monjalon
@ 2015-07-06 18:22 9% ` Neil Horman
2015-07-06 21:44 9% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-07-06 18:22 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Mon, Jul 06, 2015 at 03:49:50PM +0200, Thomas Monjalon wrote:
> 2015-07-06 09:35, Neil Horman:
> > On Mon, Jul 06, 2015 at 03:18:51PM +0200, Thomas Monjalon wrote:
> > > Any comment or ack?
> > >
> > > 2015-07-03 00:05, Thomas Monjalon:
> > > > When a change makes really hard to keep ABI compatibility,
> > > > instead of waiting next release to break the ABI, it is smoother
> > > > to introduce the new code and enable it only for static libraries.
> > > > The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> > > > When the release is out, a dynamically linked application can use
> > > > the new shared libraries without rebuild while developpers can prepare
> > > > their application for the next ABI by reading the deprecation notice
> > > > and easily testing the new code.
> > > > When starting the next release cycle, the "ifdefs" will be removed
> > > > and the ABI break will be marked by incrementing LIBABIVER.
> > > >
> > > > The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> > > > templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> > > > It is automatically enabled for static libraries and disabled for
> > > > shared libraries.
> > > > It can be forced to another value by editing the generated .config file.
> > > > It shouldn't be enabled for shared libraries because it would break the
> > > > ABI without changing the version number LIBABIVER. That's why a warning
> > > > is printed in this case.
> > > >
> > > > The guideline is also updated to integrate this new possibility.
> > > >
> > > > Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
> > >
> > >
> > Yeah, I'm not sure why this is necessecary. That is to say, if you want to
>
> It's explained at the beginning:
> "When a change makes really hard to keep ABI compatibility", e.g. mbuf change.
>
Thats not what I was referring to. I was referring to the need to split out
ABI's based on a separate config item only for static libraries. I understand
that sometimes you want a 'preview' of the next abi.
> > introduce a new ABI operation prior to the old one being removed, that is precisely what
> > the versioning macros are for, and can be used to map the static api to the new
> > version. e.g, given function X that you want to enhance in an ABI breaking way:
> >
> > 1) Separate function X to X_v1 and X_v2
> > 2) Map X_v2 to X@DPDK_v2, map X_v1 to X@DPDK_v1
> > 3) Map the static symbol X to X_v2
> > 4) Post the deprecation notice of X for release 3 immediately
>
> We cannot do that for mbuf change.
>
You can actually, its just alot of work. Also, I know this doesn't relate very
closely to the subject, and I apologize, I was really just reacting to the
immediately preceding sentence in the origional post.
> > Splitting the static ABI from the shared ABI just means that applications will
> > have the opportunity to isolate themselves to one kind of build, which is a bad
> > idea.
>
> It helps to be prepared for the next release by testing the app with static libraries.
> We agreed to allow API breaking for important changes like mbuf rework.
> This option NEXT_ABI is a step between announcement and effective ABI breaking.
>
> I think it's a reasonnable approach. But if nobody ack it, I'm perfectly OK to
> drop it and related features (unified packet type and interrupt mode).
>
I'd be ok with it iff:
1) It applies to static and shared ABI's together. That is to say that setting
the NEXT_ABI config flag creates the same ABI changes regardless of other build
configuration. It needs to be used in such a way that a consistent ABI is
presented when set, otherwise it won't be useful.
2) It only applies to the next ABI. That is to say, it can't be a hodgepodge of
the next ABI and the one after that, and the one after that, or it won't provide
an appropriate preview for anyone.
If we can meet those two standards, it would likely be a useful feature to have.
Neil
>
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH 1/2] eal/persistent: new library to hold memory region after program exit
@ 2015-07-06 19:19 1% ` Stephen Hemminger
0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2015-07-06 19:19 UTC (permalink / raw)
To: leeopop; +Cc: dev
Am I right, this library is using Unix shared memory to get
persistent storage. That is going to be slower and more worrying,
the kernel makes no guarantees that virtual to physical mapping
will not change.
There is also an ABI issue in this patch. You are introducing a new
API here, so the symbol should go in a new 2.1 section
> + if((len / RTE_PGSIZE_4K) > 1)
> + {
> + shmget_flag |= SHM_HUGETLB;
> + }
Please follow kernel coding style. This is one of many examples that
needs to be fixed before accepting.
ERROR: "foo* bar" should be "foo *bar"
#166: FILE: lib/librte_eal/common/include/rte_pci.h:210:
+ void* priv; /**< Private data. */
ERROR: "foo* bar" should be "foo *bar"
#195: FILE: lib/librte_eal/common/include/rte_persistent_mem.h:20:
+extern void* persistent_allocated_memory[RTE_MAX_NUMA_NODES][RTE_EAL_PERSISTENT_MEM_COUNT];
ERROR: "foo* bar" should be "foo *bar"
#302: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:44:
+static void* reserve_shared_zone(int subindex, uint32_t len, int socket_id)
ERROR: do not use C99 // comments
#307: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:49:
+ int shmget_flag = IPC_CREAT | SHM_R | SHM_W | IPC_EXCL; // | SHM_LOCKED;
WARNING: Missing a blank line after declarations
#310: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:52:
+ int err;
+ if((len / RTE_PGSIZE_4K) > 1)
ERROR: that open brace { should be on the previous line
#310: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:52:
+ if((len / RTE_PGSIZE_4K) > 1)
+ {
ERROR: space required before the open parenthesis '('
#310: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:52:
+ if((len / RTE_PGSIZE_4K) > 1)
ERROR: "foo* bar" should be "foo *bar"
#316: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:58:
+ void* addr = 0;
WARNING: Missing a blank line after declarations
#318: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:60:
+ int clear = 1;
+ if(shmid < 0)
ERROR: that open brace { should be on the previous line
#318: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:60:
+ if(shmid < 0)
+ {
ERROR: space required before the open parenthesis '('
#318: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:60:
+ if(shmid < 0)
ERROR: do not use C99 // comments
#320: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:62:
+ //Reuse existing
ERROR: that open brace { should be on the previous line
#328: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:70:
+ if(socket_id != SOCKET_ID_ANY)
+ {
ERROR: space required before the open parenthesis '('
#328: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:70:
+ if(socket_id != SOCKET_ID_ANY)
ERROR: "foo * bar" should be "foo *bar"
#330: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:72:
+ struct bitmask * mask = numa_bitmask_alloc(RTE_MAX_NUMA_NODES);
WARNING: Missing a blank line after declarations
#331: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:73:
+ struct bitmask * mask = numa_bitmask_alloc(RTE_MAX_NUMA_NODES);
+ mask = numa_bitmask_clearall(mask);
ERROR: that open brace { should be on the previous line
#336: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:78:
+ if(ret < 0)
+ {
ERROR: space required before the open parenthesis '('
#336: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:78:
+ if(ret < 0)
ERROR: that open brace { should be on the previous line
#344: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:86:
+ if(clear)
+ {
ERROR: space required before the open parenthesis '('
#344: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:86:
+ if(clear)
WARNING: Missing a blank line after declarations
#350: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:92:
+ size_t size;
+ volatile uint8_t reader = 0; //this prevents from being optimized out
ERROR: do not use C99 // comments
#350: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:92:
+ volatile uint8_t reader = 0; //this prevents from being optimized out
WARNING: Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt
#350: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:92:
+ volatile uint8_t reader = 0; //this prevents from being optimized out
ERROR: "(foo*)" should be "(foo *)"
#351: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:93:
+ volatile uint8_t* readp = (uint8_t*)addr;
ERROR: "foo* bar" should be "foo *bar"
#351: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:93:
+ volatile uint8_t* readp = (uint8_t*)addr;
WARNING: Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt
#351: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:93:
+ volatile uint8_t* readp = (uint8_t*)addr;
WARNING: Missing a blank line after declarations
#352: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:94:
+ volatile uint8_t* readp = (uint8_t*)addr;
+ for(size = 0; size < len; size++)
ERROR: that open brace { should be on the previous line
#352: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:94:
+ for(size = 0; size < len; size++)
+ {
ERROR: space required before the open parenthesis '('
#352: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:94:
+ for(size = 0; size < len; size++)
ERROR: "foo* bar" should be "foo *bar"
#364: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:106:
+void* persistent_allocated_memory[RTE_MAX_NUMA_NODES][SHM_COUNT];
ERROR: do not initialise statics to 0 or NULL
#366: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:108:
+static int numa_count = 0;
ERROR: do not use C99 // comments
#375: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:117:
+ assert(SHM_SIZE == RTE_PGSIZE_2M); //XXX considering only 2MB pages.
WARNING: Missing a blank line after declarations
#377: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:119:
+ int num_numa = numa_num_configured_nodes();
+ if(num_numa == 0)
ERROR: space required before the open parenthesis '('
#377: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:119:
+ if(num_numa == 0)
WARNING: Missing a blank line after declarations
#382: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:124:
+ int k;
+ for(node = 0; node < RTE_MAX_NUMA_NODES; node++)
ERROR: space required before the open parenthesis '('
#382: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:124:
+ for(node = 0; node < RTE_MAX_NUMA_NODES; node++)
ERROR: spaces required around that '=' (ctx:VxV)
#383: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:125:
+ for(k=0; k<SHM_COUNT; k++)
^
ERROR: spaces required around that '<' (ctx:VxV)
#383: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:125:
+ for(k=0; k<SHM_COUNT; k++)
^
ERROR: space required before the open parenthesis '('
#383: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:125:
+ for(k=0; k<SHM_COUNT; k++)
ERROR: that open brace { should be on the previous line
#386: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:128:
+ for(node = 0; node < num_numa; node++)
+ {
ERROR: space required before the open parenthesis '('
#386: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:128:
+ for(node = 0; node < num_numa; node++)
WARNING: Missing a blank line after declarations
#389: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:131:
+ int cur_socket = num_numa > 1 ? node : SOCKET_ID_ANY;
+ for(k=0; k<SHM_COUNT/num_numa; k++)
ERROR: that open brace { should be on the previous line
#389: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:131:
+ for(k=0; k<SHM_COUNT/num_numa; k++)
+ {
ERROR: spaces required around that '=' (ctx:VxV)
#389: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:131:
+ for(k=0; k<SHM_COUNT/num_numa; k++)
^
ERROR: spaces required around that '<' (ctx:VxV)
#389: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:131:
+ for(k=0; k<SHM_COUNT/num_numa; k++)
^
ERROR: space required before the open parenthesis '('
#389: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:131:
+ for(k=0; k<SHM_COUNT/num_numa; k++)
WARNING: Missing a blank line after declarations
#392: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:134:
+ int zone_index = ((SHM_COUNT/num_numa)*node + k);
+ persistent_allocated_memory[node][k] = reserve_shared_zone(zone_index,
ERROR: that open brace { should be on the previous line
#394: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:136:
+ if(persistent_allocated_memory[node][k] == 0)
+ {
ERROR: space required before the open parenthesis '('
#394: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:136:
+ if(persistent_allocated_memory[node][k] == 0)
WARNING: quoted string split across lines
#397: FILE: lib/librte_eal/linuxapp/eal/eal_persistent_mem.c:139:
+ RTE_LOG(ERR, EAL, "Cannot allocate shared zone index %d."
+ "node: %d, local index: %d\n", zone_index, node, k);
ERROR: do not initialise statics to 0 or NULL
#533: FILE: lib/librte_persistent/rte_persistent.c:26:
+static struct rte_hash* allocated_segments = 0;
ERROR: "foo* bar" should be "foo *bar"
#533: FILE: lib/librte_persistent/rte_persistent.c:26:
+static struct rte_hash* allocated_segments = 0;
ERROR: open brace '{' following struct go on the same line
#536: FILE: lib/librte_persistent/rte_persistent.c:29:
+struct alloc_info
+{
ERROR: do not use C99 // comments
#537: FILE: lib/librte_persistent/rte_persistent.c:30:
+ void* addr; //0 if not allocated
ERROR: "foo* bar" should be "foo *bar"
#537: FILE: lib/librte_persistent/rte_persistent.c:30:
+ void* addr; //0 if not allocated
ERROR: do not initialise statics to 0 or NULL
#550: FILE: lib/librte_persistent/rte_persistent.c:43:
+static int __initialized = 0;
ERROR: that open brace { should be on the previous line
#554: FILE: lib/librte_persistent/rte_persistent.c:47:
+ if(!__initialized)
+ {
ERROR: space required before the open parenthesis '('
#554: FILE: lib/librte_persistent/rte_persistent.c:47:
+ if(!__initialized)
ERROR: that open brace { should be on the previous line
#557: FILE: lib/librte_persistent/rte_persistent.c:50:
+ struct rte_hash_parameters hash_param =
+ {
ERROR: "(foo*)" should be "(foo *)"
#561: FILE: lib/librte_persistent/rte_persistent.c:54:
+ .key_len = sizeof(void*),
ERROR: do not use C99 // comments
#562: FILE: lib/librte_persistent/rte_persistent.c:55:
+ .hash_func = 0, //DEFAULT_HASH_FUNC,
WARNING: Missing a blank line after declarations
#571: FILE: lib/librte_persistent/rte_persistent.c:64:
+ int k;
+ for(k=0; k<SEGMENT_COUNT; k++)
ERROR: spaces required around that '=' (ctx:VxV)
#571: FILE: lib/librte_persistent/rte_persistent.c:64:
+ for(k=0; k<SEGMENT_COUNT; k++)
^
ERROR: spaces required around that '<' (ctx:VxV)
#571: FILE: lib/librte_persistent/rte_persistent.c:64:
+ for(k=0; k<SEGMENT_COUNT; k++)
^
ERROR: space required before the open parenthesis '('
#571: FILE: lib/librte_persistent/rte_persistent.c:64:
+ for(k=0; k<SEGMENT_COUNT; k++)
ERROR: "foo* bar" should be "foo *bar"
#588: FILE: lib/librte_persistent/rte_persistent.c:81:
+void* rte_persistent_alloc(size_t size, int socket)
WARNING: Missing a blank line after declarations
#591: FILE: lib/librte_persistent/rte_persistent.c:84:
+ int num_numa = rte_persistent_memory_num_numa();
+ if(socket == SOCKET_ID_ANY)
ERROR: that open brace { should be on the previous line
#591: FILE: lib/librte_persistent/rte_persistent.c:84:
+ if(socket == SOCKET_ID_ANY)
+ {
ERROR: space required before the open parenthesis '('
#591: FILE: lib/librte_persistent/rte_persistent.c:84:
+ if(socket == SOCKET_ID_ANY)
WARNING: Missing a blank line after declarations
#600: FILE: lib/librte_persistent/rte_persistent.c:93:
+ int num_page = (size / ALLOC_UNIT);
+ if(size % ALLOC_UNIT)
ERROR: space required before the open parenthesis '('
#600: FILE: lib/librte_persistent/rte_persistent.c:93:
+ if(size % ALLOC_UNIT)
WARNING: Missing a blank line after declarations
#605: FILE: lib/librte_persistent/rte_persistent.c:98:
+ int k;
+ for(k=0; k<num_page; k++)
ERROR: that open brace { should be on the previous line
#605: FILE: lib/librte_persistent/rte_persistent.c:98:
+ for(k=0; k<num_page; k++)
+ {
ERROR: spaces required around that '=' (ctx:VxV)
#605: FILE: lib/librte_persistent/rte_persistent.c:98:
+ for(k=0; k<num_page; k++)
^
ERROR: spaces required around that '<' (ctx:VxV)
#605: FILE: lib/librte_persistent/rte_persistent.c:98:
+ for(k=0; k<num_page; k++)
^
ERROR: space required before the open parenthesis '('
#605: FILE: lib/librte_persistent/rte_persistent.c:98:
+ for(k=0; k<num_page; k++)
ERROR: "foo* bar" should be "foo *bar"
#611: FILE: lib/librte_persistent/rte_persistent.c:104:
+ void* found_buffer = 0;
WARNING: Missing a blank line after declarations
#612: FILE: lib/librte_persistent/rte_persistent.c:105:
+ void* found_buffer = 0;
+ for(k=l_start; k<(l_start + l_range); k++)
ERROR: that open brace { should be on the previous line
#612: FILE: lib/librte_persistent/rte_persistent.c:105:
+ for(k=l_start; k<(l_start + l_range); k++)
+ {
ERROR: spaces required around that '=' (ctx:VxV)
#612: FILE: lib/librte_persistent/rte_persistent.c:105:
+ for(k=l_start; k<(l_start + l_range); k++)
^
ERROR: spaces required around that '<' (ctx:VxV)
#612: FILE: lib/librte_persistent/rte_persistent.c:105:
+ for(k=l_start; k<(l_start + l_range); k++)
^
ERROR: space required before the open parenthesis '('
#612: FILE: lib/librte_persistent/rte_persistent.c:105:
+ for(k=l_start; k<(l_start + l_range); k++)
ERROR: "foo* bar" should be "foo *bar"
#614: FILE: lib/librte_persistent/rte_persistent.c:107:
+ char* start = alloc_array[k];
ERROR: "foo* bar" should be "foo *bar"
#615: FILE: lib/librte_persistent/rte_persistent.c:108:
+ char* found = strstr(start, find_str);
ERROR: that open brace { should be on the previous line
#617: FILE: lib/librte_persistent/rte_persistent.c:110:
+ if(found)
+ {
ERROR: space required before the open parenthesis '('
#617: FILE: lib/librte_persistent/rte_persistent.c:110:
+ if(found)
WARNING: Missing a blank line after declarations
#620: FILE: lib/librte_persistent/rte_persistent.c:113:
+ int offset = found - start;
+ found_buffer = persistent_allocated_memory[socket][k];
WARNING: Missing a blank line after declarations
#624: FILE: lib/librte_persistent/rte_persistent.c:117:
+ int j;
+ for(j=0; j<num_page; j++)
ERROR: that open brace { should be on the previous line
#624: FILE: lib/librte_persistent/rte_persistent.c:117:
+ for(j=0; j<num_page; j++)
+ {
ERROR: spaces required around that '=' (ctx:VxV)
#624: FILE: lib/librte_persistent/rte_persistent.c:117:
+ for(j=0; j<num_page; j++)
^
ERROR: spaces required around that '<' (ctx:VxV)
#624: FILE: lib/librte_persistent/rte_persistent.c:117:
+ for(j=0; j<num_page; j++)
^
ERROR: space required before the open parenthesis '('
#624: FILE: lib/librte_persistent/rte_persistent.c:117:
+ for(j=0; j<num_page; j++)
WARNING: Missing a blank line after declarations
#629: FILE: lib/librte_persistent/rte_persistent.c:122:
+ int index = rte_hash_add_key(allocated_segments, &found_buffer);
+ assert(index >= 0);
ERROR: "foo* bar" should be "foo *bar"
#639: FILE: lib/librte_persistent/rte_persistent.c:132:
+ void* user = found_buffer;
WARNING: Missing a blank line after declarations
#642: FILE: lib/librte_persistent/rte_persistent.c:135:
+ size_t diff = RTE_MAX((uint64_t)user, hw) - RTE_MIN((uint64_t)user, hw);
+ for(j = 0; j < num_page; j++)
ERROR: that open brace { should be on the previous line
#642: FILE: lib/librte_persistent/rte_persistent.c:135:
+ for(j = 0; j < num_page; j++)
+ {
ERROR: space required before the open parenthesis '('
#642: FILE: lib/librte_persistent/rte_persistent.c:135:
+ for(j = 0; j < num_page; j++)
ERROR: "(foo*)" should be "(foo *)"
#645: FILE: lib/librte_persistent/rte_persistent.c:138:
+ void* cur_user = ((char*)user + shift);
ERROR: "foo* bar" should be "foo *bar"
#645: FILE: lib/librte_persistent/rte_persistent.c:138:
+ void* cur_user = ((char*)user + shift);
WARNING: line over 120 characters
#647: FILE: lib/librte_persistent/rte_persistent.c:140:
+ size_t cur_diff = RTE_MAX((uint64_t)cur_user, cur_hw) - RTE_MIN((uint64_t)cur_user, cur_hw);
ERROR: that open brace { should be on the previous line
#649: FILE: lib/librte_persistent/rte_persistent.c:142:
+ if(cur_diff != diff)
+ {
ERROR: space required before the open parenthesis '('
#649: FILE: lib/librte_persistent/rte_persistent.c:142:
+ if(cur_diff != diff)
WARNING: line over 120 characters
#651: FILE: lib/librte_persistent/rte_persistent.c:144:
+ RTE_LOG(ERR, EAL, "Hugepage is not contiguous, curdiff: %lX, expected: %lX\n", cur_diff, diff);
ERROR: space required before the open parenthesis '('
#658: FILE: lib/librte_persistent/rte_persistent.c:151:
+ if(!found_buffer)
ERROR: "foo* bar" should be "foo *bar"
#663: FILE: lib/librte_persistent/rte_persistent.c:156:
+phys_addr_t rte_persistent_hw_addr(const void* addr)
ERROR: space required before the open parenthesis '('
#665: FILE: lib/librte_persistent/rte_persistent.c:158:
+ if(addr == 0)
ERROR: "(foo*)" should be "(foo *)"
#667: FILE: lib/librte_persistent/rte_persistent.c:160:
+ int index = rte_hash_lookup(allocated_segments, (const void*)&addr);
WARNING: Missing a blank line after declarations
#668: FILE: lib/librte_persistent/rte_persistent.c:161:
+ int index = rte_hash_lookup(allocated_segments, (const void*)&addr);
+ assert(index >= 0);
ERROR: "foo* bar" should be "foo *bar"
#674: FILE: lib/librte_persistent/rte_persistent.c:167:
+size_t rte_persistent_mem_length(const void* addr)
ERROR: "(foo*)" should be "(foo *)"
#676: FILE: lib/librte_persistent/rte_persistent.c:169:
+ int index = rte_hash_lookup(allocated_segments, (const void*)&addr);
WARNING: Missing a blank line after declarations
#677: FILE: lib/librte_persistent/rte_persistent.c:170:
+ int index = rte_hash_lookup(allocated_segments, (const void*)&addr);
+ assert(index >= 0);
ERROR: "foo* bar" should be "foo *bar"
#683: FILE: lib/librte_persistent/rte_persistent.c:176:
+void rte_persistent_free(void* addr)
ERROR: "(foo*)" should be "(foo *)"
#685: FILE: lib/librte_persistent/rte_persistent.c:178:
+ int index = rte_hash_lookup(allocated_segments, (const void*)&addr);
WARNING: Missing a blank line after declarations
#686: FILE: lib/librte_persistent/rte_persistent.c:179:
+ int index = rte_hash_lookup(allocated_segments, (const void*)&addr);
+ assert(index >= 0);
ERROR: "(foo*)" should be "(foo *)"
#700: FILE: lib/librte_persistent/rte_persistent.c:193:
+ rte_hash_del_key(allocated_segments, (const void*)&addr);
WARNING: Missing a blank line after declarations
#703: FILE: lib/librte_persistent/rte_persistent.c:196:
+ int k;
+ for(k=0; k<len; k++)
ERROR: spaces required around that '=' (ctx:VxV)
#703: FILE: lib/librte_persistent/rte_persistent.c:196:
+ for(k=0; k<len; k++)
^
ERROR: spaces required around that '<' (ctx:VxV)
#703: FILE: lib/librte_persistent/rte_persistent.c:196:
+ for(k=0; k<len; k++)
^
ERROR: space required before the open parenthesis '('
#703: FILE: lib/librte_persistent/rte_persistent.c:196:
+ for(k=0; k<len; k++)
ERROR: "foo* bar" should be "foo *bar"
#726: FILE: lib/librte_persistent/rte_persistent.h:15:
+void* rte_persistent_alloc(size_t size, int socket);
ERROR: "foo* bar" should be "foo *bar"
#727: FILE: lib/librte_persistent/rte_persistent.h:16:
+phys_addr_t rte_persistent_hw_addr(const void* addr);
ERROR: "foo* bar" should be "foo *bar"
#728: FILE: lib/librte_persistent/rte_persistent.h:17:
+void rte_persistent_free(void* addr);
ERROR: "foo* bar" should be "foo *bar"
#729: FILE: lib/librte_persistent/rte_persistent.h:18:
+size_t rte_persistent_mem_length(const void* addr);
total: 96 errors, 28 warnings, 573 lines checked
/tmp/persist.patch has style problems, please review.
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-06 18:22 9% ` Neil Horman
@ 2015-07-06 21:44 9% ` Thomas Monjalon
2015-07-07 11:14 9% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-07-06 21:44 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-07-06 14:22, Neil Horman:
> On Mon, Jul 06, 2015 at 03:49:50PM +0200, Thomas Monjalon wrote:
> > 2015-07-06 09:35, Neil Horman:
> > > On Mon, Jul 06, 2015 at 03:18:51PM +0200, Thomas Monjalon wrote:
> > > > Any comment or ack?
> > > >
> > > > 2015-07-03 00:05, Thomas Monjalon:
> > > > > When a change makes really hard to keep ABI compatibility,
> > > > > instead of waiting next release to break the ABI, it is smoother
> > > > > to introduce the new code and enable it only for static libraries.
> > > > > The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> > > > > When the release is out, a dynamically linked application can use
> > > > > the new shared libraries without rebuild while developpers can prepare
> > > > > their application for the next ABI by reading the deprecation notice
> > > > > and easily testing the new code.
> > > > > When starting the next release cycle, the "ifdefs" will be removed
> > > > > and the ABI break will be marked by incrementing LIBABIVER.
> > > > >
> > > > > The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> > > > > templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> > > > > It is automatically enabled for static libraries and disabled for
> > > > > shared libraries.
> > > > > It can be forced to another value by editing the generated .config file.
> > > > > It shouldn't be enabled for shared libraries because it would break the
> > > > > ABI without changing the version number LIBABIVER. That's why a warning
> > > > > is printed in this case.
> > > > >
> > > > > The guideline is also updated to integrate this new possibility.
[...]
> I'd be ok with it iff:
>
> 1) It applies to static and shared ABI's together. That is to say that setting
> the NEXT_ABI config flag creates the same ABI changes regardless of other build
> configuration. It needs to be used in such a way that a consistent ABI is
> presented when set, otherwise it won't be useful.
Yes the option trigger exactly the same ABI for static and shared libraries.
But it's too complicated (at least for 2.1) to make LIBABIVER and version map
dependant of this build-time option.
That's why, it should not be enabled to deploy shared libraries, though it can
be used for tests and development.
As static libraries are almost never packaged, they will be built and linked
at the same time. That's why users of static libraries tend to prefer the
newest ABI, which is the default in this case.
> 2) It only applies to the next ABI. That is to say, it can't be a hodgepodge of
> the next ABI and the one after that, and the one after that, or it won't provide
> an appropriate preview for anyone.
If you mean the next ABI must be promoted as the standard ABI in the next release,
yes: ifdefs will be cleaned when starting a new release.
Thanks, I learnt the english word hodgepodge :)
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH 0/3] fix the issue sctp flow cannot be matched in FVL FDIR
@ 2015-07-07 7:58 3% Jingjing Wu
2015-07-07 9:04 0% ` Liu, Yong
0 siblings, 1 reply; 200+ results
From: Jingjing Wu @ 2015-07-07 7:58 UTC (permalink / raw)
To: dev
This patch set fixes the issue SCTP flow cannot be matched by FVL's flow
director. The issue's root cause is that due to the NIC's firmware update,
the input set of sctp flow are changed to source IP, destination IP,
source port, destination port and Verification-Tag, which are source IP,
destination IP and Verification-Tag previously.
And because this fix will affect the struct rte_eth_fdir_flow, use
RTE_NEXT_ABI to avoid ABI breaking.
Jingjing Wu (3):
ethdev: change the input set of sctp flow
i40e: make sport and dport of sctp flow involved in match
testpmd: add sport and dport configuration for sctp flow
app/test-pmd/cmdline.c | 12 ++++++++++++
drivers/net/i40e/i40e_fdir.c | 18 ++++++++++++++++++
lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
3 files changed, 38 insertions(+)
--
1.9.3
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 0/3] fix the issue sctp flow cannot be matched in FVL FDIR
2015-07-07 7:58 3% [dpdk-dev] [PATCH 0/3] fix the issue sctp flow cannot be matched in FVL FDIR Jingjing Wu
@ 2015-07-07 9:04 0% ` Liu, Yong
0 siblings, 0 replies; 200+ results
From: Liu, Yong @ 2015-07-07 9:04 UTC (permalink / raw)
To: Wu, Jingjing, dev
Hi,
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Tuesday, July 07, 2015 3:58 PM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Liu, Yong; Xu, HuilongX
> Subject: [PATCH 0/3] fix the issue sctp flow cannot be matched in FVL FDIR
>
> This patch set fixes the issue SCTP flow cannot be matched by FVL's flow
> director. The issue's root cause is that due to the NIC's firmware update,
> the input set of sctp flow are changed to source IP, destination IP,
> source port, destination port and Verification-Tag, which are source IP,
> destination IP and Verification-Tag previously.
> And because this fix will affect the struct rte_eth_fdir_flow, use
> RTE_NEXT_ABI to avoid ABI breaking.
>
> Jingjing Wu (3):
> ethdev: change the input set of sctp flow
> i40e: make sport and dport of sctp flow involved in match
> testpmd: add sport and dport configuration for sctp flow
>
> app/test-pmd/cmdline.c | 12 ++++++++++++
> drivers/net/i40e/i40e_fdir.c | 18 ++++++++++++++++++
> lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
> 3 files changed, 38 insertions(+)
>
> --
> 1.9.3
Tested-by: Marvin Liu <yong.liu@intel.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-06 21:44 9% ` Thomas Monjalon
@ 2015-07-07 11:14 9% ` Neil Horman
2015-07-07 12:46 7% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-07-07 11:14 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Mon, Jul 06, 2015 at 11:44:59PM +0200, Thomas Monjalon wrote:
> 2015-07-06 14:22, Neil Horman:
> > On Mon, Jul 06, 2015 at 03:49:50PM +0200, Thomas Monjalon wrote:
> > > 2015-07-06 09:35, Neil Horman:
> > > > On Mon, Jul 06, 2015 at 03:18:51PM +0200, Thomas Monjalon wrote:
> > > > > Any comment or ack?
> > > > >
> > > > > 2015-07-03 00:05, Thomas Monjalon:
> > > > > > When a change makes really hard to keep ABI compatibility,
> > > > > > instead of waiting next release to break the ABI, it is smoother
> > > > > > to introduce the new code and enable it only for static libraries.
> > > > > > The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> > > > > > When the release is out, a dynamically linked application can use
> > > > > > the new shared libraries without rebuild while developpers can prepare
> > > > > > their application for the next ABI by reading the deprecation notice
> > > > > > and easily testing the new code.
> > > > > > When starting the next release cycle, the "ifdefs" will be removed
> > > > > > and the ABI break will be marked by incrementing LIBABIVER.
> > > > > >
> > > > > > The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> > > > > > templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> > > > > > It is automatically enabled for static libraries and disabled for
> > > > > > shared libraries.
> > > > > > It can be forced to another value by editing the generated .config file.
> > > > > > It shouldn't be enabled for shared libraries because it would break the
> > > > > > ABI without changing the version number LIBABIVER. That's why a warning
> > > > > > is printed in this case.
> > > > > >
> > > > > > The guideline is also updated to integrate this new possibility.
> [...]
> > I'd be ok with it iff:
> >
> > 1) It applies to static and shared ABI's together. That is to say that setting
> > the NEXT_ABI config flag creates the same ABI changes regardless of other build
> > configuration. It needs to be used in such a way that a consistent ABI is
> > presented when set, otherwise it won't be useful.
>
> Yes the option trigger exactly the same ABI for static and shared libraries.
> But it's too complicated (at least for 2.1) to make LIBABIVER and version map
> dependant of this build-time option.
No, I think thats a bridge too far. I'm not sure whats difficult about
overriding LIBABIVER in lib.rte.mk and bump all numbers 1 higher (or better
still just add a .1 to the end of it), by checking CONFIG_NEXT_ABI
As for maintaining the version map, I don't see any problem with duplicating the
map files, to a -next variant, and changing the CPU_LDFLAGS in rte.lib.mk based
on the NEXT_ABI config option again.
In fact, if this is a thing that people want, that might be beneficial, as
something else occurs to me. I think you're going to want this to be a mandated
piece of the update process. That is to say, if someone wants to deprecate an
aspect of the ABI, or change it, I think you'll want to mandate that they submit
the change at the same time they submit the deprecation notice, and simply
protect it with this NEXT_ABI config option. That provides several advantages:
1) It ensures that the notice is submitted at the same time as the actual change
2) It ensures that the NEXT_ABI provides a complete view of what the next ABI
version looks like, not just a partial view of it
Adding a *-version-next.map file for each library makes adhering to the above
easier, and allows for an easy converstion, in that when its time to officially
update the ABI, fixing the version map is a matter of copying
<library>-version-next.map to <library>-version.map.
The use case that I'm thinking of here is as such:
Consider two ABI modifying updates, A and B.
The author of A writes his changes, submits them with appropriate ifdefs for
CONFIG_NEXT_ABI, along with a deprecation notice.
The author of B writes his changes, but doesn't submit them, instead submitting
only a deprecation notice, with plans to post the actuall patches after the
deprecation notice is shipped in a release
After the release CONFIG_NEXT_ABI exposes the ABI changes made by A, but not by
B (because they don't yet exist in the code). I think to give users a complete
view of the NEXT_ABI, changes to the ABI, should be done by submitting the patch
(gated on the NEXT_ABI config option), along with the deprecation notice, at the
same time. That way the ABI view is complete and consistent. And if you do the
above bits with the cloned version map and LIBABIVER bump, its also consistent
between shared and static libraries.
> That's why, it should not be enabled to deploy shared libraries, though it can
> be used for tests and development.
> As static libraries are almost never packaged, they will be built and linked
> at the same time. That's why users of static libraries tend to prefer the
> newest ABI, which is the default in this case.
>
> > 2) It only applies to the next ABI. That is to say, it can't be a hodgepodge of
> > the next ABI and the one after that, and the one after that, or it won't provide
> > an appropriate preview for anyone.
>
> If you mean the next ABI must be promoted as the standard ABI in the next release,
> yes: ifdefs will be cleaned when starting a new release.
> Thanks, I learnt the english word hodgepodge :)
>
Je-mexcuse, une meli-melo? :)
I mean't what you indicate yes, and in addition to that, I just wanted to
clarify that this option could strictly _only_ apply to the very next ABI. That
is to say, someone can't use this without also posting an ABI deprecation
notice, or we would find ourselves in a situation where something would only be
available in NEXT_ABI for more than one release, which would be unacceptable.
But I think we're saying the same thing.
>
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-07 11:14 9% ` Neil Horman
@ 2015-07-07 12:46 7% ` Thomas Monjalon
2015-07-07 13:11 4% ` Neil Horman
2015-07-07 13:44 8% ` Neil Horman
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2015-07-07 12:46 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
Thanks Neil, we are making good progress.
2015-07-07 07:14, Neil Horman:
> On Mon, Jul 06, 2015 at 11:44:59PM +0200, Thomas Monjalon wrote:
> > 2015-07-06 14:22, Neil Horman:
> > > On Mon, Jul 06, 2015 at 03:49:50PM +0200, Thomas Monjalon wrote:
> > > > 2015-07-06 09:35, Neil Horman:
> > > > > On Mon, Jul 06, 2015 at 03:18:51PM +0200, Thomas Monjalon wrote:
> > > > > > Any comment or ack?
> > > > > >
> > > > > > 2015-07-03 00:05, Thomas Monjalon:
> > > > > > > When a change makes really hard to keep ABI compatibility,
> > > > > > > instead of waiting next release to break the ABI, it is smoother
> > > > > > > to introduce the new code and enable it only for static libraries.
> > > > > > > The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> > > > > > > When the release is out, a dynamically linked application can use
> > > > > > > the new shared libraries without rebuild while developpers can prepare
> > > > > > > their application for the next ABI by reading the deprecation notice
> > > > > > > and easily testing the new code.
> > > > > > > When starting the next release cycle, the "ifdefs" will be removed
> > > > > > > and the ABI break will be marked by incrementing LIBABIVER.
> > > > > > >
> > > > > > > The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> > > > > > > templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> > > > > > > It is automatically enabled for static libraries and disabled for
> > > > > > > shared libraries.
> > > > > > > It can be forced to another value by editing the generated .config file.
> > > > > > > It shouldn't be enabled for shared libraries because it would break the
> > > > > > > ABI without changing the version number LIBABIVER. That's why a warning
> > > > > > > is printed in this case.
> > > > > > >
> > > > > > > The guideline is also updated to integrate this new possibility.
> > [...]
> > > I'd be ok with it iff:
> > >
> > > 1) It applies to static and shared ABI's together. That is to say that setting
> > > the NEXT_ABI config flag creates the same ABI changes regardless of other build
> > > configuration. It needs to be used in such a way that a consistent ABI is
> > > presented when set, otherwise it won't be useful.
> >
> > Yes the option trigger exactly the same ABI for static and shared libraries.
> > But it's too complicated (at least for 2.1) to make LIBABIVER and version map
> > dependant of this build-time option.
>
> No, I think thats a bridge too far. I'm not sure whats difficult about
> overriding LIBABIVER in lib.rte.mk and bump all numbers 1 higher (or better
> still just add a .1 to the end of it), by checking CONFIG_NEXT_ABI
Good idea, I will submit a v2 which adds .1.
> As for maintaining the version map, I don't see any problem with duplicating the
> map files, to a -next variant, and changing the CPU_LDFLAGS in rte.lib.mk based
> on the NEXT_ABI config option again.
OK
> In fact, if this is a thing that people want, that might be beneficial, as
> something else occurs to me. I think you're going to want this to be a mandated
> piece of the update process. That is to say, if someone wants to deprecate an
> aspect of the ABI, or change it, I think you'll want to mandate that they submit
> the change at the same time they submit the deprecation notice, and simply
> protect it with this NEXT_ABI config option. That provides several advantages:
For the release 2.1, we have some deprecation notices without code. It was
the policy agreed in 2.0 release.
Maybe we can force code to be submitted with deprecation notices, starting
with release 2.2.
It needs to be amended in v2 of this patch.
> 1) It ensures that the notice is submitted at the same time as the actual change
> 2) It ensures that the NEXT_ABI provides a complete view of what the next ABI
> version looks like, not just a partial view of it
Yes it would be probably useful.
> Adding a *-version-next.map file for each library makes adhering to the above
> easier, and allows for an easy converstion, in that when its time to officially
> update the ABI, fixing the version map is a matter of copying
> <library>-version-next.map to <library>-version.map.
OK
[...]
> > That's why, it should not be enabled to deploy shared libraries, though it can
> > be used for tests and development.
> > As static libraries are almost never packaged, they will be built and linked
> > at the same time. That's why users of static libraries tend to prefer the
> > newest ABI, which is the default in this case.
> >
> > > 2) It only applies to the next ABI. That is to say, it can't be a hodgepodge of
> > > the next ABI and the one after that, and the one after that, or it won't provide
> > > an appropriate preview for anyone.
> >
> > If you mean the next ABI must be promoted as the standard ABI in the next release,
> > yes: ifdefs will be cleaned when starting a new release.
> > Thanks, I learnt the english word hodgepodge :)
> >
> Je-mexcuse, une meli-melo? :)
Oui un meli-melo, un ramassis. un beau bordel en somme.
> I mean't what you indicate yes, and in addition to that, I just wanted to
> clarify that this option could strictly _only_ apply to the very next ABI. That
> is to say, someone can't use this without also posting an ABI deprecation
> notice, or we would find ourselves in a situation where something would only be
> available in NEXT_ABI for more than one release, which would be unacceptable.
> But I think we're saying the same thing.
Yes. I'll try to make it clear in v2.
Neil, in the meantime, could you please help to check ABI breakage in the HEAD?
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-07 12:46 7% ` Thomas Monjalon
@ 2015-07-07 13:11 4% ` Neil Horman
2015-07-07 13:44 8% ` Neil Horman
1 sibling, 0 replies; 200+ results
From: Neil Horman @ 2015-07-07 13:11 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Tue, Jul 07, 2015 at 05:46:08AM -0700, Thomas Monjalon wrote:
> Thanks Neil, we are making good progress.
>
> 2015-07-07 07:14, Neil Horman:
> > On Mon, Jul 06, 2015 at 11:44:59PM +0200, Thomas Monjalon wrote:
> > > 2015-07-06 14:22, Neil Horman:
> > > > On Mon, Jul 06, 2015 at 03:49:50PM +0200, Thomas Monjalon wrote:
> > > > > 2015-07-06 09:35, Neil Horman:
> > > > > > On Mon, Jul 06, 2015 at 03:18:51PM +0200, Thomas Monjalon wrote:
> > > > > > > Any comment or ack?
> > > > > > >
> > > > > > > 2015-07-03 00:05, Thomas Monjalon:
> > > > > > > > When a change makes really hard to keep ABI compatibility,
> > > > > > > > instead of waiting next release to break the ABI, it is smoother
> > > > > > > > to introduce the new code and enable it only for static libraries.
> > > > > > > > The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> > > > > > > > When the release is out, a dynamically linked application can use
> > > > > > > > the new shared libraries without rebuild while developpers can prepare
> > > > > > > > their application for the next ABI by reading the deprecation notice
> > > > > > > > and easily testing the new code.
> > > > > > > > When starting the next release cycle, the "ifdefs" will be removed
> > > > > > > > and the ABI break will be marked by incrementing LIBABIVER.
> > > > > > > >
> > > > > > > > The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> > > > > > > > templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> > > > > > > > It is automatically enabled for static libraries and disabled for
> > > > > > > > shared libraries.
> > > > > > > > It can be forced to another value by editing the generated .config file.
> > > > > > > > It shouldn't be enabled for shared libraries because it would break the
> > > > > > > > ABI without changing the version number LIBABIVER. That's why a warning
> > > > > > > > is printed in this case.
> > > > > > > >
> > > > > > > > The guideline is also updated to integrate this new possibility.
> > > [...]
> > > > I'd be ok with it iff:
> > > >
> > > > 1) It applies to static and shared ABI's together. That is to say that setting
> > > > the NEXT_ABI config flag creates the same ABI changes regardless of other build
> > > > configuration. It needs to be used in such a way that a consistent ABI is
> > > > presented when set, otherwise it won't be useful.
> > >
> > > Yes the option trigger exactly the same ABI for static and shared libraries.
> > > But it's too complicated (at least for 2.1) to make LIBABIVER and version map
> > > dependant of this build-time option.
> >
> > No, I think thats a bridge too far. I'm not sure whats difficult about
> > overriding LIBABIVER in lib.rte.mk and bump all numbers 1 higher (or better
> > still just add a .1 to the end of it), by checking CONFIG_NEXT_ABI
>
> Good idea, I will submit a v2 which adds .1.
>
> > As for maintaining the version map, I don't see any problem with duplicating the
> > map files, to a -next variant, and changing the CPU_LDFLAGS in rte.lib.mk based
> > on the NEXT_ABI config option again.
>
> OK
>
> > In fact, if this is a thing that people want, that might be beneficial, as
> > something else occurs to me. I think you're going to want this to be a mandated
> > piece of the update process. That is to say, if someone wants to deprecate an
> > aspect of the ABI, or change it, I think you'll want to mandate that they submit
> > the change at the same time they submit the deprecation notice, and simply
> > protect it with this NEXT_ABI config option. That provides several advantages:
>
> For the release 2.1, we have some deprecation notices without code. It was
> the policy agreed in 2.0 release.
Right, we're stuck with that for the next release, but this idea of yours I
think will help make sure we get both together in the future.
> Maybe we can force code to be submitted with deprecation notices, starting
> with release 2.2.
> It needs to be amended in v2 of this patch.
Yes, I think that makes sense
>
> > 1) It ensures that the notice is submitted at the same time as the actual change
> > 2) It ensures that the NEXT_ABI provides a complete view of what the next ABI
> > version looks like, not just a partial view of it
>
> Yes it would be probably useful.
>
> > Adding a *-version-next.map file for each library makes adhering to the above
> > easier, and allows for an easy converstion, in that when its time to officially
> > update the ABI, fixing the version map is a matter of copying
> > <library>-version-next.map to <library>-version.map.
>
> OK
>
> [...]
> > > That's why, it should not be enabled to deploy shared libraries, though it can
> > > be used for tests and development.
> > > As static libraries are almost never packaged, they will be built and linked
> > > at the same time. That's why users of static libraries tend to prefer the
> > > newest ABI, which is the default in this case.
> > >
> > > > 2) It only applies to the next ABI. That is to say, it can't be a hodgepodge of
> > > > the next ABI and the one after that, and the one after that, or it won't provide
> > > > an appropriate preview for anyone.
> > >
> > > If you mean the next ABI must be promoted as the standard ABI in the next release,
> > > yes: ifdefs will be cleaned when starting a new release.
> > > Thanks, I learnt the english word hodgepodge :)
> > >
> > Je-mexcuse, une meli-melo? :)
>
> Oui un meli-melo, un ramassis. un beau bordel en somme.
>
exactement! :)
> > I mean't what you indicate yes, and in addition to that, I just wanted to
> > clarify that this option could strictly _only_ apply to the very next ABI. That
> > is to say, someone can't use this without also posting an ABI deprecation
> > notice, or we would find ourselves in a situation where something would only be
> > available in NEXT_ABI for more than one release, which would be unacceptable.
> > But I think we're saying the same thing.
>
> Yes. I'll try to make it clear in v2.
>
> Neil, in the meantime, could you please help to check ABI breakage in the HEAD?
I'll try to take a look today
Neil
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] mk: enable next abi in static libs
2015-07-07 12:46 7% ` Thomas Monjalon
2015-07-07 13:11 4% ` Neil Horman
@ 2015-07-07 13:44 8% ` Neil Horman
1 sibling, 0 replies; 200+ results
From: Neil Horman @ 2015-07-07 13:44 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Tue, Jul 07, 2015 at 05:46:08AM -0700, Thomas Monjalon wrote:
> Thanks Neil, we are making good progress.
>
> 2015-07-07 07:14, Neil Horman:
> > On Mon, Jul 06, 2015 at 11:44:59PM +0200, Thomas Monjalon wrote:
> > > 2015-07-06 14:22, Neil Horman:
> > > > On Mon, Jul 06, 2015 at 03:49:50PM +0200, Thomas Monjalon wrote:
> > > > > 2015-07-06 09:35, Neil Horman:
> > > > > > On Mon, Jul 06, 2015 at 03:18:51PM +0200, Thomas Monjalon wrote:
> > > > > > > Any comment or ack?
> > > > > > >
> > > > > > > 2015-07-03 00:05, Thomas Monjalon:
> > > > > > > > When a change makes really hard to keep ABI compatibility,
> > > > > > > > instead of waiting next release to break the ABI, it is smoother
> > > > > > > > to introduce the new code and enable it only for static libraries.
> > > > > > > > The flag RTE_NEXT_ABI may be used to "ifdef" the new code.
> > > > > > > > When the release is out, a dynamically linked application can use
> > > > > > > > the new shared libraries without rebuild while developpers can prepare
> > > > > > > > their application for the next ABI by reading the deprecation notice
> > > > > > > > and easily testing the new code.
> > > > > > > > When starting the next release cycle, the "ifdefs" will be removed
> > > > > > > > and the ABI break will be marked by incrementing LIBABIVER.
> > > > > > > >
> > > > > > > > The new option CONFIG_RTE_NEXT_ABI is not defined in the configuration
> > > > > > > > templates because it is deduced from CONFIG_RTE_BUILD_SHARED_LIB.
> > > > > > > > It is automatically enabled for static libraries and disabled for
> > > > > > > > shared libraries.
> > > > > > > > It can be forced to another value by editing the generated .config file.
> > > > > > > > It shouldn't be enabled for shared libraries because it would break the
> > > > > > > > ABI without changing the version number LIBABIVER. That's why a warning
> > > > > > > > is printed in this case.
> > > > > > > >
> > > > > > > > The guideline is also updated to integrate this new possibility.
> > > [...]
> > > > I'd be ok with it iff:
> > > >
> > > > 1) It applies to static and shared ABI's together. That is to say that setting
> > > > the NEXT_ABI config flag creates the same ABI changes regardless of other build
> > > > configuration. It needs to be used in such a way that a consistent ABI is
> > > > presented when set, otherwise it won't be useful.
> > >
> > > Yes the option trigger exactly the same ABI for static and shared libraries.
> > > But it's too complicated (at least for 2.1) to make LIBABIVER and version map
> > > dependant of this build-time option.
> >
> > No, I think thats a bridge too far. I'm not sure whats difficult about
> > overriding LIBABIVER in lib.rte.mk and bump all numbers 1 higher (or better
> > still just add a .1 to the end of it), by checking CONFIG_NEXT_ABI
>
> Good idea, I will submit a v2 which adds .1.
>
> > As for maintaining the version map, I don't see any problem with duplicating the
> > map files, to a -next variant, and changing the CPU_LDFLAGS in rte.lib.mk based
> > on the NEXT_ABI config option again.
>
> OK
>
> > In fact, if this is a thing that people want, that might be beneficial, as
> > something else occurs to me. I think you're going to want this to be a mandated
> > piece of the update process. That is to say, if someone wants to deprecate an
> > aspect of the ABI, or change it, I think you'll want to mandate that they submit
> > the change at the same time they submit the deprecation notice, and simply
> > protect it with this NEXT_ABI config option. That provides several advantages:
>
> For the release 2.1, we have some deprecation notices without code. It was
> the policy agreed in 2.0 release.
> Maybe we can force code to be submitted with deprecation notices, starting
> with release 2.2.
> It needs to be amended in v2 of this patch.
>
> > 1) It ensures that the notice is submitted at the same time as the actual change
> > 2) It ensures that the NEXT_ABI provides a complete view of what the next ABI
> > version looks like, not just a partial view of it
>
> Yes it would be probably useful.
>
> > Adding a *-version-next.map file for each library makes adhering to the above
> > easier, and allows for an easy converstion, in that when its time to officially
> > update the ABI, fixing the version map is a matter of copying
> > <library>-version-next.map to <library>-version.map.
>
> OK
>
> [...]
> > > That's why, it should not be enabled to deploy shared libraries, though it can
> > > be used for tests and development.
> > > As static libraries are almost never packaged, they will be built and linked
> > > at the same time. That's why users of static libraries tend to prefer the
> > > newest ABI, which is the default in this case.
> > >
> > > > 2) It only applies to the next ABI. That is to say, it can't be a hodgepodge of
> > > > the next ABI and the one after that, and the one after that, or it won't provide
> > > > an appropriate preview for anyone.
> > >
> > > If you mean the next ABI must be promoted as the standard ABI in the next release,
> > > yes: ifdefs will be cleaned when starting a new release.
> > > Thanks, I learnt the english word hodgepodge :)
> > >
> > Je-mexcuse, une meli-melo? :)
>
> Oui un meli-melo, un ramassis. un beau bordel en somme.
>
> > I mean't what you indicate yes, and in addition to that, I just wanted to
> > clarify that this option could strictly _only_ apply to the very next ABI. That
> > is to say, someone can't use this without also posting an ABI deprecation
> > notice, or we would find ourselves in a situation where something would only be
> > available in NEXT_ABI for more than one release, which would be unacceptable.
> > But I think we're saying the same thing.
>
> Yes. I'll try to make it clear in v2.
>
> Neil, in the meantime, could you please help to check ABI breakage in the HEAD?
>
Took a look, the only ABI break I see that we need to worry about is the one
introduced in commit 8eecb3295aed0a979def52245564d03be172a83c. It adds a
bitfield called lro into the existing uint8_t there, but does so in the middle
of the set, which pushes the other bits around, breaking ABI. It should have
been added to the end.
Neil
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v3 0/7] support i40e QinQ stripping and insertion
@ 2015-07-07 14:43 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-07 14:43 UTC (permalink / raw)
To: Zhang, Helin; +Cc: dev
> > As i40e hardware can be reconfigured to support QinQ stripping and insertion,
> > this patch set is to enable that together with using the reserved 16 bits in
> > 'struct rte_mbuf' for the second vlan tag. Corresponding command is added
> > in testpmd for testing.
> > Note that no need to rework vPMD, as nothings used in it changed.
> >
> > v2 changes:
> > * Added more commit logs of which commit it fix for.
> > * Fixed a typo.
> > * Kept the original RX/TX offload flags as they were, added new
> > flags after with new bit masks, for ABI compatibility.
> > * Supported double vlan stripping/insertion in examples/ipv4_multicast.
> >
> > v3 changes:
> > * update documentation (Testpmd Application User Guide).
> >
> > Helin Zhang (7):
> > ixgbe: remove a discarded source line
> > mbuf: use the reserved 16 bits for double vlan
> > i40e: support double vlan stripping and insertion
> > i40evf: add supported offload capability flags
> > app/testpmd: add test cases for qinq stripping and insertion
> > examples/ipv4_multicast: support double vlan stripping and insertion
> > doc: update testpmd command
>
> Acked-by: Jingjing Wu <jingjing.wu@intel.com>
Applied, thanks
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf
2015-06-26 7:03 5% ` Wu, Jingjing
2015-07-06 1:27 0% ` Wu, Jingjing
@ 2015-07-07 14:51 4% ` Thomas Monjalon
2015-07-08 0:58 0% ` Wu, Jingjing
2015-07-08 10:31 5% ` Mcnamara, John
1 sibling, 2 replies; 200+ results
From: Thomas Monjalon @ 2015-07-07 14:51 UTC (permalink / raw)
To: Wu, Jingjing; +Cc: dev
2015-06-26 07:03, Wu, Jingjing:
> Hi, Neil
>
> About this patch I have an ABI concern about it.
> This patch just renamed a struct rte_eth_vmdq_mirror_conf to
> rte_eth_mirror_conf, the size and its elements don't change.
> As my understanding, it will not break the ABI. And I also tested it.
> But when I use the script ./scripts/validate-abi.sh to check.
> A low severity problem is reported in symbol "rte_eth_mirror_rule_set"
> - Change: "Base type of 2nd parameter mirror_conf has been changed
> from struct rte_eth_vmdq_mirror_conf to struct rte_eth_mirror_conf."
> - Effect: "Replacement of parameter base type may indicate a change
> in its semantic meaning."
>
> So, I'm not sure whether this patch meet the ABI policy?
I think it's OK.
> Additional, about the validate-abi.sh, does it mean we need to fix
> all the problems it reports? Or we can decide case by case.
> Can a Low Severity problem be acceptable?
We have to decide case by case.
It makes ABI checking impossible to automate.
That's why any help is welcome to check the git HEAD for ABI violation.
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3] doc: announce ABI changes planned for unified packet type
2015-07-03 8:49 21% ` [dpdk-dev] [PATCH v2] " Helin Zhang
@ 2015-07-07 17:45 21% ` Helin Zhang
2015-07-08 15:58 4% ` Zhang, Helin
0 siblings, 1 reply; 200+ results
From: Helin Zhang @ 2015-07-07 17:45 UTC (permalink / raw)
To: dev
The significant ABI changes of all shared libraries are planned to
support unified packet type which will be taken effect from
release 2.2. Here announces that ABI changes in detail.
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
doc/guides/rel_notes/abi.rst | 1 +
1 file changed, 1 insertion(+)
v2 changes:
* Added 'struct rte_kni_mbuf' to the ABI change announcement.
v3 changes:
* Re-worded the ABI change announcement, as the ABI changes will be
taken effect from release 2.1 for static libraries, and from
release 2.2 for shared libraries.
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index 110c486..9f8a9b3 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -12,3 +12,4 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* Significant ABI changes are planned for struct rte_mbuf, struct rte_kni_mbuf, and several PKT_RX_ flags will be removed, to support unified packet type from release 2.1. The upcoming release 2.1 will have those changes for static libraries only, while have no change for shared libraries by default. Those changes will be taken effect for shared libraries from release 2.2. There is no backward compatibility planned from release 2.2. All binaries will need to be rebuilt from release 2.2.
--
1.9.3
^ permalink raw reply [relevance 21%]
* Re: [dpdk-dev] [PATCH v2 0/4] extend flow director to support L2_paylod type
2015-06-26 3:14 0% ` Zhang, Helin
@ 2015-07-07 21:24 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-07 21:24 UTC (permalink / raw)
To: Wu, Jingjing; +Cc: dev
> > This patch set extends flow director to support L2_paylod type in i40e driver.
> >
> > v2 change:
> > - remove the flow director VF filtering from this patch to avoid breaking ABI.
> >
> > Jingjing Wu (4):
> > ethdev: add struct rte_eth_l2_flow to support l2_payload flow type
> > i40e: extend flow diretcor to support l2_payload flow type
> > testpmd: extend commands
> > doc: extend commands in testpmd
>
> Acked-by: Helin Zhang <helin.zhang@intel.com>
Applied, thanks
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf
2015-07-07 14:51 4% ` Thomas Monjalon
@ 2015-07-08 0:58 0% ` Wu, Jingjing
2015-07-08 10:31 5% ` Mcnamara, John
1 sibling, 0 replies; 200+ results
From: Wu, Jingjing @ 2015-07-08 0:58 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
Thanks for the clarification.
Jingjing
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Tuesday, July 07, 2015 10:51 PM
> To: Wu, Jingjing
> Cc: dev@dpdk.org; nhorman@tuxdriver.com
> Subject: Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename
> rte_eth_vmdq_mirror_conf
>
> 2015-06-26 07:03, Wu, Jingjing:
> > Hi, Neil
> >
> > About this patch I have an ABI concern about it.
> > This patch just renamed a struct rte_eth_vmdq_mirror_conf to
> > rte_eth_mirror_conf, the size and its elements don't change.
> > As my understanding, it will not break the ABI. And I also tested it.
> > But when I use the script ./scripts/validate-abi.sh to check.
> > A low severity problem is reported in symbol "rte_eth_mirror_rule_set"
> > - Change: "Base type of 2nd parameter mirror_conf has been changed
> > from struct rte_eth_vmdq_mirror_conf to struct rte_eth_mirror_conf."
> > - Effect: "Replacement of parameter base type may indicate a change
> > in its semantic meaning."
> >
> > So, I'm not sure whether this patch meet the ABI policy?
>
> I think it's OK.
>
> > Additional, about the validate-abi.sh, does it mean we need to fix all
> > the problems it reports? Or we can decide case by case.
> > Can a Low Severity problem be acceptable?
>
> We have to decide case by case.
> It makes ABI checking impossible to automate.
> That's why any help is welcome to check the git HEAD for ABI violation.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] config: revert the CONFIG_RTE_MAX_QUEUES_PER_PORT to 256
@ 2015-07-08 1:24 3% Jijiang Liu
0 siblings, 0 replies; 200+ results
From: Jijiang Liu @ 2015-07-08 1:24 UTC (permalink / raw)
To: dev
Revert the CONFIG_RTE_MAX_QUEUES_PER_PORT to 256.
The previous commit changed the size and the offsets of struct rte_eth_dev,
so it is an ABI breakage. I revert it, and will send a deprecation notice for this.
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
---
config/common_linuxapp | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/config/common_linuxapp b/config/common_linuxapp
index f5646e0..e883f69 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -139,7 +139,7 @@ CONFIG_RTE_LIBRTE_KVARGS=y
CONFIG_RTE_LIBRTE_ETHER=y
CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
CONFIG_RTE_MAX_ETHPORTS=32
-CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
+CONFIG_RTE_MAX_QUEUES_PER_PORT=256
CONFIG_RTE_LIBRTE_IEEE1588=n
CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
--
1.7.7.6
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 0/7] ethdev: add support for ieee1588 timestamping
2015-07-02 15:16 4% ` [dpdk-dev] [PATCH v3 " John McNamara
2015-07-02 15:16 14% ` [dpdk-dev] [PATCH v3 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
2015-07-03 8:22 0% ` [dpdk-dev] [PATCH v3 0/7] ethdev: add support for ieee1588 timestamping Lu, Wenzhuo
@ 2015-07-08 1:59 0% ` Fu, JingguoX
2 siblings, 0 replies; 200+ results
From: Fu, JingguoX @ 2015-07-08 1:59 UTC (permalink / raw)
To: dev
Tested-by: Jingguo Fu <jingguox.fu@intel.com>
- Test Commit: 82be8d544253a4b5c49b778babf717e5e63f3dc1
- OS: Ubuntu 14.04
- GCC: gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
- CPU: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz
- NIC: Intel Corporation Device [8086:1563]
- Total 1 case, 1 passed, 0 failed.
Test Case : test_ieee1588_disable
====================================================================
1. set CONFIG_RTE_LIBRTE_IEEE1588=y, rebuild the DPDK code.
2.mount hugetlbfs
3. insmod igb_uio and bind the two ports to igb_uio driver
4. startup testpmd
testpmd -c 0x6 -n 4 -- -i --txqflags 0x0
5. set ieee1588 fwd mode and start it:
set fwd ieee1588
start
6. send a packet to the receive port and check the output and send port status:
a: "IEEE1588 PTP V2 SYNC" in pmd output
b: "RX timestamp value ([0-9a-fA-F]+)" in pmd output
c: "TX timestamp value ([0-9a-fA-F]+)" in pmd output
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of John McNamara
> Sent: Thursday, July 02, 2015 23:16
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 0/7] ethdev: add support for ieee1588
> timestamping
>
> This patchset adds ethdev API to enable and read IEEE1588/802.1AS PTP
> timestamps from devices that support it. The following functions are added:
>
> rte_eth_timesync_enable()
> rte_eth_timesync_disable()
> rte_eth_timesync_read_rx_timestamp()
> rte_eth_timesync_read_tx_timestamp()
>
> The "ieee1588" forwarding mode in testpmd is also refactored to
> demonstrate the new API and to clean up the code.
>
> Adds support for igb, ixgbe and i40e.
>
> V3:
> * Fixed issued with version.map.
>
> V2:
> * Added i40e support.
>
> * Renamed ethdev functions from rte_eth_ieee15888_*() to
> rte_eth_timesync_*()
> since 802.1AS can be supported through the same interfaces.
>
> V1:
> * Initial version for
>
>
> John McNamara (7):
> ethdev: add support for ieee1588 timestamping
> e1000: add support for ieee1588 timestamping
> ixgbe: add support for ieee1588 timestamping
> i40e: add support for ieee1588 timestamping
> app/testpmd: refactor ieee1588 forwarding
> doc: document ieee1588 forwarding mode
> abi: announce mbuf addition for ieee1588 in DPDK 2.2
>
> app/test-pmd/ieee1588fwd.c | 466 ++--------------------------
> doc/guides/rel_notes/abi.rst | 5 +
> doc/guides/testpmd_app_ug/run_app.rst | 2 +-
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +
> drivers/net/e1000/igb_ethdev.c | 115 +++++++
> drivers/net/i40e/i40e_ethdev.c | 143 +++++++++
> drivers/net/i40e/i40e_rxtx.c | 39 ++-
> drivers/net/ixgbe/ixgbe_ethdev.c | 122 ++++++++
> lib/librte_ether/rte_ethdev.c | 70 ++++-
> lib/librte_ether/rte_ethdev.h | 90 +++++-
> lib/librte_ether/rte_ether_version.map | 4 +
> 11 files changed, 615 insertions(+), 443 deletions(-)
>
> --
> 1.8.1.4
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] doc:announce ABI changes planned for struct rte_eth_dev to support up to 1024 queues per port
@ 2015-07-08 2:08 20% Jijiang Liu
2015-07-08 11:07 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Jijiang Liu @ 2015-07-08 2:08 UTC (permalink / raw)
To: dev
The significant ABI change of all shared libraries is planned for struct rte_eth_dev to support up to 1024 queues per port which will be taken effect from release 2.2.
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
---
doc/guides/rel_notes/abi.rst | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
index 110c486..ff4a810 100644
--- a/doc/guides/rel_notes/abi.rst
+++ b/doc/guides/rel_notes/abi.rst
@@ -12,3 +12,4 @@ Examples of Deprecation Notices
Deprecation Notices
-------------------
+* Significant ABI changes are planned for struct rte_eth_dev to support up to 1024 queues per port. This change will be taken effect for shared libraries from release 2.2. There is no backward compatibility planned from release 2.2. All binaries will need to be rebuilt from release 2.2.
--
1.7.7.6
^ permalink raw reply [relevance 20%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf
2015-07-07 14:51 4% ` Thomas Monjalon
2015-07-08 0:58 0% ` Wu, Jingjing
@ 2015-07-08 10:31 5% ` Mcnamara, John
2015-07-08 10:35 0% ` Bruce Richardson
1 sibling, 1 reply; 200+ results
From: Mcnamara, John @ 2015-07-08 10:31 UTC (permalink / raw)
To: Thomas Monjalon, Wu, Jingjing; +Cc: dev
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Tuesday, July 7, 2015 3:51 PM
> To: Wu, Jingjing
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename
> rte_eth_vmdq_mirror_conf
>
> > Additional, about the validate-abi.sh, does it mean we need to fix all
> > the problems it reports? Or we can decide case by case.
> > Can a Low Severity problem be acceptable?
>
> We have to decide case by case.
> It makes ABI checking impossible to automate.
> That's why any help is welcome to check the git HEAD for ABI violation.
Hi,
Automated testing for ABI breaks is tricky since it requires some interpretation of the errors and the severity level.
However, each report file contains a 2 line summary at the top that can be read and parsed. For example (with long lines wrapped):
head -2 compat_reports/librte_mbuf.so/v2.0.0_to_ABI_CHECK/compat_report.html
<!-- kind:binary;verdict:compatible;affected:0;added:1;removed:0;
type_problems_high:0;type_problems_medium:0;type_problems_low:0;
interface_problems_high:0;interface_problems_medium:0;
interface_problems_low:0;changed_constants:0;tool_version:1.99.8.5 -->
<!-- kind:source;verdict:compatible;affected:0;added:1;removed:0;
type_problems_high:0;type_problems_medium:0;type_problems_low:0;
interface_problems_high:0;interface_problems_medium:0;
interface_problems_low:0;changed_constants:0;tool_version:1.99.8.5 -->
This still requires interpretation but it can be used to search for categories of incompatibility.
To test if a patchset breaks the API it is possible to do something like the following. Say, for example that you have committed 3 commits to your local master, you could tag and run the checker like this:
git checkout master
git tag -f ABI_CHECK_AFTER
git tag -f ABI_CHECK_BEFORE HEAD~3
./scripts/validate-abi.sh ABI_CHECK_BEFORE ABI_CHECK_AFTER x86_64-native-linuxapp-gcc
grep -lr "kind:binary;verdict:incompatible" compat_reports/
The grep could be extended to match other categories that you are interested in. However, it is still probably better to examine the reports manually.
You can also use something this to run a git bisect to find a commit that introduced an ABI incompatibility:
# Tag the head and some known good point in the history.
git checkout master
git tag -f ABI_CHECK_END
git tag -f ABI_CHECK_START v2.0.0
# Start git bisect with bad and good.
git bisect start ABI_CHECK_END ABI_CHECK_START
# Run bisect with a script.
git bisect run ~/abi_bisect.sh
Where the ~/abi_bisect.sh script that searches for ABI incompatibilities looks like this:
#!/bin/sh
git tag -f ABI_CHECK_END
rm -rf compat_reports/
./scripts/validate-abi.sh ABI_CHECK_START ABI_CHECK_END x86_64-native-linuxapp-gcc
! grep -lr "kind:binary;verdict:incompatible" compat_reports/
John.
--
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf
2015-07-08 10:31 5% ` Mcnamara, John
@ 2015-07-08 10:35 0% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2015-07-08 10:35 UTC (permalink / raw)
To: Mcnamara, John; +Cc: dev
On Wed, Jul 08, 2015 at 10:31:15AM +0000, Mcnamara, John wrote:
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> > Sent: Tuesday, July 7, 2015 3:51 PM
> > To: Wu, Jingjing
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v4 1/4] ethdev: rename
> > rte_eth_vmdq_mirror_conf
> >
> > > Additional, about the validate-abi.sh, does it mean we need to fix all
> > > the problems it reports? Or we can decide case by case.
> > > Can a Low Severity problem be acceptable?
> >
> > We have to decide case by case.
> > It makes ABI checking impossible to automate.
> > That's why any help is welcome to check the git HEAD for ABI violation.
>
> Hi,
>
> Automated testing for ABI breaks is tricky since it requires some interpretation of the errors and the severity level.
>
> However, each report file contains a 2 line summary at the top that can be read and parsed. For example (with long lines wrapped):
>
> head -2 compat_reports/librte_mbuf.so/v2.0.0_to_ABI_CHECK/compat_report.html
>
> <!-- kind:binary;verdict:compatible;affected:0;added:1;removed:0;
> type_problems_high:0;type_problems_medium:0;type_problems_low:0;
> interface_problems_high:0;interface_problems_medium:0;
> interface_problems_low:0;changed_constants:0;tool_version:1.99.8.5 -->
> <!-- kind:source;verdict:compatible;affected:0;added:1;removed:0;
> type_problems_high:0;type_problems_medium:0;type_problems_low:0;
> interface_problems_high:0;interface_problems_medium:0;
> interface_problems_low:0;changed_constants:0;tool_version:1.99.8.5 -->
>
> This still requires interpretation but it can be used to search for categories of incompatibility.
>
> To test if a patchset breaks the API it is possible to do something like the following. Say, for example that you have committed 3 commits to your local master, you could tag and run the checker like this:
>
> git checkout master
>
> git tag -f ABI_CHECK_AFTER
> git tag -f ABI_CHECK_BEFORE HEAD~3
>
> ./scripts/validate-abi.sh ABI_CHECK_BEFORE ABI_CHECK_AFTER x86_64-native-linuxapp-gcc
>
> grep -lr "kind:binary;verdict:incompatible" compat_reports/
>
> The grep could be extended to match other categories that you are interested in. However, it is still probably better to examine the reports manually.
>
> You can also use something this to run a git bisect to find a commit that introduced an ABI incompatibility:
>
> # Tag the head and some known good point in the history.
> git checkout master
> git tag -f ABI_CHECK_END
> git tag -f ABI_CHECK_START v2.0.0
>
> # Start git bisect with bad and good.
> git bisect start ABI_CHECK_END ABI_CHECK_START
>
> # Run bisect with a script.
> git bisect run ~/abi_bisect.sh
>
> Where the ~/abi_bisect.sh script that searches for ABI incompatibilities looks like this:
>
> #!/bin/sh
>
> git tag -f ABI_CHECK_END
>
> rm -rf compat_reports/
>
> ./scripts/validate-abi.sh ABI_CHECK_START ABI_CHECK_END x86_64-native-linuxapp-gcc
>
> ! grep -lr "kind:binary;verdict:incompatible" compat_reports/
>
> John.
> --
I'd mod this post up as "+1 informative", except that this isn't slashdot. :-)
Very helpful, John. Thanks.
/Bruce
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] doc:announce ABI changes planned for struct rte_eth_dev to support up to 1024 queues per port
2015-07-08 2:08 20% [dpdk-dev] [PATCH] doc:announce ABI changes planned for struct rte_eth_dev to support up to 1024 queues per port Jijiang Liu
@ 2015-07-08 11:07 4% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2015-07-08 11:07 UTC (permalink / raw)
To: Jijiang Liu; +Cc: dev
On Wed, Jul 08, 2015 at 10:08:25AM +0800, Jijiang Liu wrote:
> The significant ABI change of all shared libraries is planned for struct rte_eth_dev to support up to 1024 queues per port which will be taken effect from release 2.2.
>
> Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
> ---
> doc/guides/rel_notes/abi.rst | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst
> index 110c486..ff4a810 100644
> --- a/doc/guides/rel_notes/abi.rst
> +++ b/doc/guides/rel_notes/abi.rst
> @@ -12,3 +12,4 @@ Examples of Deprecation Notices
>
> Deprecation Notices
> -------------------
> +* Significant ABI changes are planned for struct rte_eth_dev to support up to 1024 queues per port. This change will be taken effect for shared libraries from release 2.2. There is no backward compatibility planned from release 2.2. All binaries will need to be rebuilt from release 2.2.
> --
> 1.7.7.6
>
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2
2015-07-06 13:16 4% ` Thomas Monjalon
@ 2015-07-08 13:10 7% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2015-07-08 13:10 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Mon, Jul 06, 2015 at 03:16:01PM +0200, Thomas Monjalon wrote:
> 2015-07-02 16:16, John McNamara:
> > --- a/doc/guides/rel_notes/abi.rst
> > +++ b/doc/guides/rel_notes/abi.rst
> > Deprecation Notices
> > -------------------
> > +
> > +* In DPDK 2.1 the IEEE1588/802.1AS support in the i40e driver makes use of the
> > + ``udata64`` field in the mbuf to pass the timesync register index to the
> > + user. In DPDK 2.2 this will be moved to a new field in the mbuf.
>
> We need more acknowledgements for this decision, as stated here:
> http://dpdk.org/browse/dpdk/tree/doc/guides/guidelines/versioning.rst#n51
Why can't this new field just be added at the end of cache line 1 (the second
cache line) of the mbuf? That would avoid any ABI breakage and would mean we
can just put the change in in this release, instead of waiting.
/Bruce
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH] hash: move rte_hash structure to C file and make it internal
@ 2015-07-08 13:21 3% ` Bruce Richardson
2015-07-08 16:57 0% ` Matthew Hall
0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2015-07-08 13:21 UTC (permalink / raw)
To: Pablo de Lara; +Cc: dev
On Wed, Jul 08, 2015 at 12:27:34PM +0100, Pablo de Lara wrote:
> rte_hash structure should not be a public structure,
> and therefore it should be moved to the C file and be declared
> as internal. rte_hash_hash implementation is also moved
> to the C file, as it uses the structure.
>
> This patch also removes part of a unit test that was checking
> a field of the structure.
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Irrespective of whether or not we change the underlying hash table implementation
this looks a good change to me. The rte_hash structure should not be used directly
by any applications - the APIs all take pointers to the structure,
so there should be no ABI breakage from this, I think.
Therefore:
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2 0/2] next abi option
2015-07-02 22:05 20% [dpdk-dev] [PATCH] mk: enable next abi in static libs Thomas Monjalon
2015-07-06 13:18 4% ` Thomas Monjalon
@ 2015-07-08 14:55 8% ` Thomas Monjalon
2015-07-08 14:55 4% ` [dpdk-dev] [PATCH v2 1/2] mk: remove variables identical to config ones Thomas Monjalon
` (2 more replies)
1 sibling, 3 replies; 200+ results
From: Thomas Monjalon @ 2015-07-08 14:55 UTC (permalink / raw)
To: nhorman; +Cc: dev
This is the second version of the NEXT_ABI policy.
It can now be used for shared and static libraries.
While updating rte.lib.mk, it appeared that some useless
(and not consistent) variables were used for some config
options. The first patch clean them.
Thomas Monjalon (2):
mk: remove variables identical to config ones
mk: enable next abi preview
config/common_bsdapp | 5 +++++
config/common_linuxapp | 5 +++++
doc/guides/guidelines/versioning.rst | 12 +++++++++---
mk/exec-env/bsdapp/rte.vars.mk | 4 ++--
mk/exec-env/linuxapp/rte.vars.mk | 4 ++--
mk/rte.lib.mk | 16 +++++++++-------
mk/rte.sdkbuild.mk | 2 +-
mk/rte.sharelib.mk | 8 ++++----
mk/rte.vars.mk | 8 --------
pkg/dpdk.spec | 1 +
scripts/validate-abi.sh | 2 ++
11 files changed, 40 insertions(+), 27 deletions(-)
--
2.4.2
^ permalink raw reply [relevance 8%]
* [dpdk-dev] [PATCH v2 1/2] mk: remove variables identical to config ones
2015-07-08 14:55 8% ` [dpdk-dev] [PATCH v2 0/2] next abi option Thomas Monjalon
@ 2015-07-08 14:55 4% ` Thomas Monjalon
2015-07-08 14:55 34% ` [dpdk-dev] [PATCH v2 2/2] mk: enable next abi preview Thomas Monjalon
2015-07-08 16:50 4% ` [dpdk-dev] [PATCH v2 0/2] next abi option Neil Horman
2 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-08 14:55 UTC (permalink / raw)
To: nhorman; +Cc: dev
CONFIG_RTE_BUILD_SHARED_LIB and CONFIG_RTE_BUILD_COMBINE_LIBS does not
have quotes in their values (only y or n). That's why the variables
RTE_BUILD_SHARED_LIB and RTE_BUILD_COMBINE_LIBS are always identical to
their CONFIG_ counterpart, and are useless.
In order to have consistent naming of config options in the makefiles,
these options are removed and the "CONFIG_ prefixed" variables are used.
Fixes: e25e4d7ef16b ("mk: shared libraries")
Fixes: 4d3d79e7a5c6 ("mk: combined library")
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
mk/exec-env/bsdapp/rte.vars.mk | 4 ++--
mk/exec-env/linuxapp/rte.vars.mk | 4 ++--
mk/rte.lib.mk | 12 ++++++------
mk/rte.sdkbuild.mk | 2 +-
mk/rte.sharelib.mk | 8 ++++----
mk/rte.vars.mk | 8 --------
6 files changed, 15 insertions(+), 23 deletions(-)
diff --git a/mk/exec-env/bsdapp/rte.vars.mk b/mk/exec-env/bsdapp/rte.vars.mk
index aed0e18..47a673e 100644
--- a/mk/exec-env/bsdapp/rte.vars.mk
+++ b/mk/exec-env/bsdapp/rte.vars.mk
@@ -39,7 +39,7 @@
#
# examples for RTE_EXEC_ENV: linuxapp, bsdapp
#
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
EXECENV_CFLAGS = -pthread -fPIC
else
EXECENV_CFLAGS = -pthread
@@ -49,7 +49,7 @@ EXECENV_LDFLAGS =
EXECENV_LDLIBS = -lexecinfo
EXECENV_ASFLAGS =
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
EXECENV_LDLIBS += -lgcc_s
endif
diff --git a/mk/exec-env/linuxapp/rte.vars.mk b/mk/exec-env/linuxapp/rte.vars.mk
index e5af318..5fd7d85 100644
--- a/mk/exec-env/linuxapp/rte.vars.mk
+++ b/mk/exec-env/linuxapp/rte.vars.mk
@@ -39,7 +39,7 @@
#
# examples for RTE_EXEC_ENV: linuxapp, bsdapp
#
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
EXECENV_CFLAGS = -pthread -fPIC
else
EXECENV_CFLAGS = -pthread
@@ -51,7 +51,7 @@ EXECENV_LDFLAGS = --no-as-needed
EXECENV_LDLIBS = -lrt -lm
EXECENV_ASFLAGS =
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
EXECENV_LDLIBS += -lgcc_s
endif
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 25aa989..fff62a7 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -37,7 +37,7 @@ include $(RTE_SDK)/mk/internal/rte.depdirs-pre.mk
# VPATH contains at least SRCDIR
VPATH += $(SRCDIR)
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB))
CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP)
@@ -87,7 +87,7 @@ O_TO_S_DO = @set -e; \
$(O_TO_S) && \
echo $(O_TO_S_CMD) > $(call exe2cmd,$(@))
-ifeq ($(RTE_BUILD_SHARED_LIB),n)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
O_TO_C = $(AR) crus $(LIB_ONE) $(OBJS-y)
O_TO_C_STR = $(subst ','\'',$(O_TO_C)) #'# fix syntax highlight
O_TO_C_DISP = $(if $(V),"$(O_TO_C_STR)"," AR_C $(@)")
@@ -110,7 +110,7 @@ lib_dir = [ -d $(RTE_OUTPUT)/lib ] || mkdir -p $(RTE_OUTPUT)/lib;
#
# Archive objects in .a file if needed
#
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
$(LIB): $(OBJS-y) $(DEP_$(LIB)) FORCE
ifeq ($(LIBABIVER),)
@echo "Must Specify a $(LIB) ABI version"
@@ -130,7 +130,7 @@ endif
$(depfile_newer)),\
$(O_TO_S_DO))
-ifeq ($(RTE_BUILD_COMBINE_LIBS),y)
+ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),y)
$(if $(or \
$(file_missing),\
$(call cmdline_changed,$(O_TO_C_STR)),\
@@ -153,7 +153,7 @@ $(LIB): $(OBJS-y) $(DEP_$(LIB)) FORCE
$(depfile_missing),\
$(depfile_newer)),\
$(O_TO_A_DO))
-ifeq ($(RTE_BUILD_COMBINE_LIBS),y)
+ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),y)
$(if $(or \
$(file_missing),\
$(call cmdline_changed,$(O_TO_C_STR)),\
@@ -171,7 +171,7 @@ $(RTE_OUTPUT)/lib/$(LIB): $(LIB)
@echo " INSTALL-LIB $(LIB)"
@[ -d $(RTE_OUTPUT)/lib ] || mkdir -p $(RTE_OUTPUT)/lib
$(Q)cp -f $(LIB) $(RTE_OUTPUT)/lib
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
$(Q)ln -s -f $< $(RTE_OUTPUT)/lib/$(LIBSONAME)
endif
diff --git a/mk/rte.sdkbuild.mk b/mk/rte.sdkbuild.mk
index 352f738..38ec7bd 100644
--- a/mk/rte.sdkbuild.mk
+++ b/mk/rte.sdkbuild.mk
@@ -93,7 +93,7 @@ $(ROOTDIRS-y):
@[ -d $(BUILDDIR)/$@ ] || mkdir -p $(BUILDDIR)/$@
@echo "== Build $@"
$(Q)$(MAKE) S=$@ -f $(RTE_SRCDIR)/$@/Makefile -C $(BUILDDIR)/$@ all
- @if [ $@ = drivers -a $(RTE_BUILD_COMBINE_LIBS) = y ]; then \
+ @if [ $@ = drivers -a $(CONFIG_RTE_BUILD_COMBINE_LIBS) = y ]; then \
$(MAKE) -f $(RTE_SDK)/lib/Makefile sharelib; \
fi
diff --git a/mk/rte.sharelib.mk b/mk/rte.sharelib.mk
index de53558..7bb7219 100644
--- a/mk/rte.sharelib.mk
+++ b/mk/rte.sharelib.mk
@@ -34,8 +34,8 @@ include $(RTE_SDK)/mk/internal/rte.build-pre.mk
# VPATH contains at least SRCDIR
VPATH += $(SRCDIR)
-ifeq ($(RTE_BUILD_COMBINE_LIBS),y)
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
LIB_ONE := lib$(RTE_LIBNAME).so
else
LIB_ONE := lib$(RTE_LIBNAME).a
@@ -75,8 +75,8 @@ O_TO_A_DO = @set -e; \
# Archive objects to share library
#
-ifeq ($(RTE_BUILD_COMBINE_LIBS),y)
-ifeq ($(RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
$(LIB_ONE): FORCE
@[ -d $(dir $@) ] || mkdir -p $(dir $@)
$(O_TO_S_DO)
diff --git a/mk/rte.vars.mk b/mk/rte.vars.mk
index d2f01b6..0469064 100644
--- a/mk/rte.vars.mk
+++ b/mk/rte.vars.mk
@@ -63,14 +63,6 @@ ifneq ($(BUILDING_RTE_SDK),)
RTE_TOOLCHAIN := $(CONFIG_RTE_TOOLCHAIN:"%"=%)
RTE_TARGET := $(RTE_ARCH)-$(RTE_MACHINE)-$(RTE_EXEC_ENV)-$(RTE_TOOLCHAIN)
RTE_SDK_BIN := $(RTE_OUTPUT)
- RTE_BUILD_SHARED_LIB := $(CONFIG_RTE_BUILD_SHARED_LIB:"%"=%)
- ifeq ($(RTE_BUILD_SHARED_LIB),)
- RTE_BUILD_SHARED_LIB := n
- endif
- RTE_BUILD_COMBINE_LIBS := $(CONFIG_RTE_BUILD_COMBINE_LIBS:"%"=%)
- ifeq ($(RTE_BUILD_COMBINE_LIBS),)
- RTE_BUILD_COMBINE_LIBS := n
- endif
endif
RTE_LIBNAME := $(CONFIG_RTE_LIBNAME:"%"=%)
--
2.4.2
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 2/2] mk: enable next abi preview
2015-07-08 14:55 8% ` [dpdk-dev] [PATCH v2 0/2] next abi option Thomas Monjalon
2015-07-08 14:55 4% ` [dpdk-dev] [PATCH v2 1/2] mk: remove variables identical to config ones Thomas Monjalon
@ 2015-07-08 14:55 34% ` Thomas Monjalon
2015-07-08 16:44 33% ` [dpdk-dev] [PATCH v3] " Thomas Monjalon
2015-07-08 16:50 4% ` [dpdk-dev] [PATCH v2 0/2] next abi option Neil Horman
2 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2015-07-08 14:55 UTC (permalink / raw)
To: nhorman; +Cc: dev
When a change makes really hard to keep ABI compatibility,
instead of waiting next release to break the ABI, it is smoother
to introduce the new code as a preview and disable it when packaging.
The flag RTE_NEXT_ABI must be used to "ifdef" the new code.
When the release is out, a dynamically linked application can use
the new shared libraries with the old ABI while developpers can prepare
their application for the next ABI by reading the deprecation notice
and easily testing the new code.
When starting the next release cycle, the "ifdefs" will be removed
and the ABI break will be marked by incrementing LIBABIVER. The map
files will also be updated.
The default value is enabled to be developer compliant.
The packagers must disable it as done in pkg/dpdk.spec.
When enabled, all shared library numbers are incremented by appending
a minor .1 to the old ABI number. In the next release, only impacted
libraries will have a major +1 increment.
The impacted libraries must provide an alternative map file to use
with this option.
The ABI policy is updated.
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
config/common_bsdapp | 5 +++++
config/common_linuxapp | 5 +++++
doc/guides/guidelines/versioning.rst | 12 +++++++++---
mk/rte.lib.mk | 6 ++++--
pkg/dpdk.spec | 1 +
scripts/validate-abi.sh | 2 ++
6 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/config/common_bsdapp b/config/common_bsdapp
index 78754b2..a4e3262 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -90,6 +90,11 @@ CONFIG_RTE_BUILD_COMBINE_LIBS=n
CONFIG_RTE_LIBNAME=intel_dpdk
#
+# Use newest code breaking previous ABI
+#
+CONFIG_RTE_NEXT_ABI=y
+
+#
# Compile Environment Abstraction Layer
#
CONFIG_RTE_LIBRTE_EAL=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index f5646e0..050bf35 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -90,6 +90,11 @@ CONFIG_RTE_BUILD_COMBINE_LIBS=n
CONFIG_RTE_LIBNAME="intel_dpdk"
#
+# Use newest code breaking previous ABI
+#
+CONFIG_RTE_NEXT_ABI=y
+
+#
# Compile Environment Abstraction Layer
#
CONFIG_RTE_LIBRTE_EAL=y
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
index ea789cb..8a739dd 100644
--- a/doc/guides/guidelines/versioning.rst
+++ b/doc/guides/guidelines/versioning.rst
@@ -55,12 +55,18 @@ being provided. The requirements for doing so are:
#. At least 3 acknowledgments of the need to do so must be made on the
dpdk.org mailing list.
+#. The changes (including an alternative map file) must be gated with
+ the ``RTE_NEXT_ABI`` option, and provided with a deprecation notice at the
+ same time.
+ It will become the default ABI in the next release.
+
#. A full deprecation cycle, as explained above, must be made to offer
downstream consumers sufficient warning of the change.
-#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
- incorporated must be incremented in parallel with the ABI changes
- themselves.
+#. At the beginning of the next release cycle, every ``RTE_NEXT_ABI``
+ conditions will be removed, the ``LIBABIVER`` variable in the makefile(s)
+ where the ABI is changed will be incremented, and the map files will
+ be updated.
Note that the above process for ABI deprecation should not be undertaken
lightly. ABI stability is extremely important for downstream consumers of the
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index fff62a7..0ad32cb 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -37,11 +37,13 @@ include $(RTE_SDK)/mk/internal/rte.depdirs-pre.mk
# VPATH contains at least SRCDIR
VPATH += $(SRCDIR)
-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB))
+ifeq ($(CONFIG_RTE_NEXT_ABI),y)
+LIB := $(LIB).1
+endif
CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP)
-
endif
diff --git a/pkg/dpdk.spec b/pkg/dpdk.spec
index 5f6ec6a..fb71ccc 100644
--- a/pkg/dpdk.spec
+++ b/pkg/dpdk.spec
@@ -82,6 +82,7 @@ make O=%{target} T=%{target} config
sed -ri 's,(RTE_MACHINE=).*,\1%{machine},' %{target}/.config
sed -ri 's,(RTE_APP_TEST=).*,\1n,' %{target}/.config
sed -ri 's,(RTE_BUILD_SHARED_LIB=).*,\1y,' %{target}/.config
+sed -ri 's,(RTE_NEXT_ABI=).*,\1n,' %{target}/.config
sed -ri 's,(LIBRTE_VHOST=).*,\1y,' %{target}/.config
sed -ri 's,(LIBRTE_PMD_PCAP=).*,\1y,' %{target}/.config
sed -ri 's,(LIBRTE_PMD_XENVIRT=).*,\1y,' %{target}/.config
diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
index 1747b8b..4476433 100755
--- a/scripts/validate-abi.sh
+++ b/scripts/validate-abi.sh
@@ -157,6 +157,7 @@ git checkout $TAG1
# Make sure we configure SHARED libraries
# Also turn off IGB and KNI as those require kernel headers to build
sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
+sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
@@ -198,6 +199,7 @@ git checkout $TAG2
# Make sure we configure SHARED libraries
# Also turn off IGB and KNI as those require kernel headers to build
sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
+sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
--
2.4.2
^ permalink raw reply [relevance 34%]
* Re: [dpdk-dev] [PATCH v3] doc: announce ABI changes planned for unified packet type
2015-07-07 17:45 21% ` [dpdk-dev] [PATCH v3] " Helin Zhang
@ 2015-07-08 15:58 4% ` Zhang, Helin
0 siblings, 0 replies; 200+ results
From: Zhang, Helin @ 2015-07-08 15:58 UTC (permalink / raw)
To: nhorman; +Cc: dev
Hi Neil
Please review it and ack it, if no objections! Thank you very much in advance!
- Helin
> -----Original Message-----
> From: Zhang, Helin
> Sent: Tuesday, July 7, 2015 10:45 AM
> To: dev@dpdk.org
> Cc: Liu, Jijiang; Wu, Jingjing; nhorman@tuxdriver.com; Zhang, Helin
> Subject: [PATCH v3] doc: announce ABI changes planned for unified packet type
>
> The significant ABI changes of all shared libraries are planned to support unified
> packet type which will be taken effect from release 2.2. Here announces that ABI
> changes in detail.
>
> Signed-off-by: Helin Zhang <helin.zhang@intel.com>
> ---
> doc/guides/rel_notes/abi.rst | 1 +
> 1 file changed, 1 insertion(+)
>
> v2 changes:
> * Added 'struct rte_kni_mbuf' to the ABI change announcement.
>
> v3 changes:
> * Re-worded the ABI change announcement, as the ABI changes will be
> taken effect from release 2.1 for static libraries, and from
> release 2.2 for shared libraries.
>
> diff --git a/doc/guides/rel_notes/abi.rst b/doc/guides/rel_notes/abi.rst index
> 110c486..9f8a9b3 100644
> --- a/doc/guides/rel_notes/abi.rst
> +++ b/doc/guides/rel_notes/abi.rst
> @@ -12,3 +12,4 @@ Examples of Deprecation Notices
>
> Deprecation Notices
> -------------------
> +* Significant ABI changes are planned for struct rte_mbuf, struct rte_kni_mbuf,
> and several PKT_RX_ flags will be removed, to support unified packet type from
> release 2.1. The upcoming release 2.1 will have those changes for static libraries
> only, while have no change for shared libraries by default. Those changes will be
> taken effect for shared libraries from release 2.2. There is no backward
> compatibility planned from release 2.2. All binaries will need to be rebuilt from
> release 2.2.
> --
> 1.9.3
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 1/4] eal: provide functions to access PCI config
[not found] ` <d35efa226d95495e804181b2246063d2@HQ1WP-EXMB11.corp.brocade.com>
@ 2015-07-08 16:11 3% ` Stephen Hemminger
2015-07-08 16:34 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2015-07-08 16:11 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Stephen Hemminger
On Wed, 8 Jul 2015 15:04:16 +0000
Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
> 2015-07-07 17:08, Stephen Hemminger:
> > --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > @@ -98,3 +98,8 @@ DPDK_2.0 {
> >
> > local: *;
> > };
> > +
> > +DPDK_2.1 {
> > + rte_eal_pci_read_config;
> > + rte_eal_pci_write_config;
> > +};
>
> DPDK_2.0 is missing to make 2.1 node inheriting from 2.0 one.
Do you mean that it is ok to add functions but keep same ABI version?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/4] eal: provide functions to access PCI config
2015-07-08 16:11 3% ` Stephen Hemminger
@ 2015-07-08 16:34 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-08 16:34 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, Stephen Hemminger
2015-07-08 09:11, Stephen Hemminger:
> On Wed, 8 Jul 2015 15:04:16 +0000
> Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
>
> > 2015-07-07 17:08, Stephen Hemminger:
> > > --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > > +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > > @@ -98,3 +98,8 @@ DPDK_2.0 {
> > >
> > > local: *;
> > > };
> > > +
> > > +DPDK_2.1 {
> > > + rte_eal_pci_read_config;
> > > + rte_eal_pci_write_config;
> > > +};
> >
> > DPDK_2.0 is missing to make 2.1 node inheriting from 2.0 one.
>
> Do you mean that it is ok to add functions but keep same ABI version?
No. It's explained there:
http://dpdk.org/browse/dpdk/tree/doc/guides/guidelines/versioning.rst#n209
"
DPDK_2.1 {
global:
rte_acl_create;
} DPDK_2.0;
The addition of the new block tells the linker that a new version node is
available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
symbols from the DPDK_2.0 node.
"
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3] mk: enable next abi preview
2015-07-08 14:55 34% ` [dpdk-dev] [PATCH v2 2/2] mk: enable next abi preview Thomas Monjalon
@ 2015-07-08 16:44 33% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-08 16:44 UTC (permalink / raw)
To: nhorman; +Cc: dev
When a change makes really hard to keep ABI compatibility,
instead of waiting next release to break the ABI, it is smoother
to introduce the new code as a preview and disable it when packaging.
The flag RTE_NEXT_ABI must be used to "ifdef" the new code.
When the release is out, a dynamically linked application can use
the new shared libraries with the old ABI while developpers can prepare
their application for the next ABI by reading the deprecation notice
and easily testing the new code.
When starting the next release cycle, the "ifdefs" will be removed
and the ABI break will be marked by incrementing LIBABIVER. The map
files will also be updated.
The default value is enabled to be developer compliant.
The packagers must disable it as done in pkg/dpdk.spec.
When enabled, all shared library numbers are incremented by appending
a minor .1 to the old ABI number. In the next release, only impacted
libraries will have a major +1 increment.
The impacted libraries must provide an alternative map file to use
with this option.
The ABI policy is updated.
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
v3 change:
- fix .so symbolic link to .so.x.1
config/common_bsdapp | 5 +++++
config/common_linuxapp | 5 +++++
doc/guides/guidelines/versioning.rst | 12 +++++++++---
mk/rte.lib.mk | 9 +++++----
pkg/dpdk.spec | 1 +
scripts/validate-abi.sh | 2 ++
6 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/config/common_bsdapp b/config/common_bsdapp
index 78754b2..a4e3262 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -90,6 +90,11 @@ CONFIG_RTE_BUILD_COMBINE_LIBS=n
CONFIG_RTE_LIBNAME=intel_dpdk
#
+# Use newest code breaking previous ABI
+#
+CONFIG_RTE_NEXT_ABI=y
+
+#
# Compile Environment Abstraction Layer
#
CONFIG_RTE_LIBRTE_EAL=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index f5646e0..050bf35 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -90,6 +90,11 @@ CONFIG_RTE_BUILD_COMBINE_LIBS=n
CONFIG_RTE_LIBNAME="intel_dpdk"
#
+# Use newest code breaking previous ABI
+#
+CONFIG_RTE_NEXT_ABI=y
+
+#
# Compile Environment Abstraction Layer
#
CONFIG_RTE_LIBRTE_EAL=y
diff --git a/doc/guides/guidelines/versioning.rst b/doc/guides/guidelines/versioning.rst
index ea789cb..8a739dd 100644
--- a/doc/guides/guidelines/versioning.rst
+++ b/doc/guides/guidelines/versioning.rst
@@ -55,12 +55,18 @@ being provided. The requirements for doing so are:
#. At least 3 acknowledgments of the need to do so must be made on the
dpdk.org mailing list.
+#. The changes (including an alternative map file) must be gated with
+ the ``RTE_NEXT_ABI`` option, and provided with a deprecation notice at the
+ same time.
+ It will become the default ABI in the next release.
+
#. A full deprecation cycle, as explained above, must be made to offer
downstream consumers sufficient warning of the change.
-#. The ``LIBABIVER`` variable in the makefile(s) where the ABI changes are
- incorporated must be incremented in parallel with the ABI changes
- themselves.
+#. At the beginning of the next release cycle, every ``RTE_NEXT_ABI``
+ conditions will be removed, the ``LIBABIVER`` variable in the makefile(s)
+ where the ABI is changed will be incremented, and the map files will
+ be updated.
Note that the above process for ABI deprecation should not be undertaken
lightly. ABI stability is extremely important for downstream consumers of the
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index fff62a7..f15de9b 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -37,11 +37,13 @@ include $(RTE_SDK)/mk/internal/rte.depdirs-pre.mk
# VPATH contains at least SRCDIR
VPATH += $(SRCDIR)
-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB))
+ifeq ($(CONFIG_RTE_NEXT_ABI),y)
+LIB := $(LIB).1
+endif
CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP)
-
endif
@@ -167,12 +169,11 @@ endif
# install lib in $(RTE_OUTPUT)/lib
#
$(RTE_OUTPUT)/lib/$(LIB): $(LIB)
- $(eval LIBSONAME := $(basename $(LIB)))
@echo " INSTALL-LIB $(LIB)"
@[ -d $(RTE_OUTPUT)/lib ] || mkdir -p $(RTE_OUTPUT)/lib
$(Q)cp -f $(LIB) $(RTE_OUTPUT)/lib
ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
- $(Q)ln -s -f $< $(RTE_OUTPUT)/lib/$(LIBSONAME)
+ $(Q)ln -s -f $< $(basename $(basename $@))
endif
#
diff --git a/pkg/dpdk.spec b/pkg/dpdk.spec
index 5f6ec6a..fb71ccc 100644
--- a/pkg/dpdk.spec
+++ b/pkg/dpdk.spec
@@ -82,6 +82,7 @@ make O=%{target} T=%{target} config
sed -ri 's,(RTE_MACHINE=).*,\1%{machine},' %{target}/.config
sed -ri 's,(RTE_APP_TEST=).*,\1n,' %{target}/.config
sed -ri 's,(RTE_BUILD_SHARED_LIB=).*,\1y,' %{target}/.config
+sed -ri 's,(RTE_NEXT_ABI=).*,\1n,' %{target}/.config
sed -ri 's,(LIBRTE_VHOST=).*,\1y,' %{target}/.config
sed -ri 's,(LIBRTE_PMD_PCAP=).*,\1y,' %{target}/.config
sed -ri 's,(LIBRTE_PMD_XENVIRT=).*,\1y,' %{target}/.config
diff --git a/scripts/validate-abi.sh b/scripts/validate-abi.sh
index 1747b8b..4476433 100755
--- a/scripts/validate-abi.sh
+++ b/scripts/validate-abi.sh
@@ -157,6 +157,7 @@ git checkout $TAG1
# Make sure we configure SHARED libraries
# Also turn off IGB and KNI as those require kernel headers to build
sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
+sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
@@ -198,6 +199,7 @@ git checkout $TAG2
# Make sure we configure SHARED libraries
# Also turn off IGB and KNI as those require kernel headers to build
sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
+sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
--
2.4.2
^ permalink raw reply [relevance 33%]
* Re: [dpdk-dev] [PATCH v2 0/2] next abi option
2015-07-08 14:55 8% ` [dpdk-dev] [PATCH v2 0/2] next abi option Thomas Monjalon
2015-07-08 14:55 4% ` [dpdk-dev] [PATCH v2 1/2] mk: remove variables identical to config ones Thomas Monjalon
2015-07-08 14:55 34% ` [dpdk-dev] [PATCH v2 2/2] mk: enable next abi preview Thomas Monjalon
@ 2015-07-08 16:50 4% ` Neil Horman
2015-07-08 22:58 4% ` Thomas Monjalon
2 siblings, 1 reply; 200+ results
From: Neil Horman @ 2015-07-08 16:50 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Wed, Jul 08, 2015 at 04:55:21PM +0200, Thomas Monjalon wrote:
> This is the second version of the NEXT_ABI policy.
> It can now be used for shared and static libraries.
>
> While updating rte.lib.mk, it appeared that some useless
> (and not consistent) variables were used for some config
> options. The first patch clean them.
>
> Thomas Monjalon (2):
> mk: remove variables identical to config ones
> mk: enable next abi preview
>
> config/common_bsdapp | 5 +++++
> config/common_linuxapp | 5 +++++
> doc/guides/guidelines/versioning.rst | 12 +++++++++---
> mk/exec-env/bsdapp/rte.vars.mk | 4 ++--
> mk/exec-env/linuxapp/rte.vars.mk | 4 ++--
> mk/rte.lib.mk | 16 +++++++++-------
> mk/rte.sdkbuild.mk | 2 +-
> mk/rte.sharelib.mk | 8 ++++----
> mk/rte.vars.mk | 8 --------
> pkg/dpdk.spec | 1 +
> scripts/validate-abi.sh | 2 ++
> 11 files changed, 40 insertions(+), 27 deletions(-)
>
> --
> 2.4.2
>
>
For the series
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] hash: move rte_hash structure to C file and make it internal
2015-07-08 13:21 3% ` Bruce Richardson
@ 2015-07-08 16:57 0% ` Matthew Hall
0 siblings, 0 replies; 200+ results
From: Matthew Hall @ 2015-07-08 16:57 UTC (permalink / raw)
To: Bruce Richardson; +Cc: dev
On Wed, Jul 08, 2015 at 02:21:42PM +0100, Bruce Richardson wrote:
> Irrespective of whether or not we change the underlying hash table implementation
> this looks a good change to me. The rte_hash structure should not be used directly
> by any applications - the APIs all take pointers to the structure,
> so there should be no ABI breakage from this, I think.
>
> Therefore:
>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
Hi guys,
There are places where this will be annoying on the app side.
A lot of rte_hash, rte_lpm*, rte_table, etc. don't provide methods to iterate
whole structures with a callback function that includes the current structure
node, and a user-data pointer.
This can make it real unpleasant when you want to walk through the structure
and free a bunch of items it points to and so forth.
So if you're going to obfuscate things by censoring the structure contents
then we'd really like to be sure they have a full set of CRUD operations and
iteration support so one could manage the nodes individually and in bulk.
Matthew.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 0/2] next abi option
2015-07-08 16:50 4% ` [dpdk-dev] [PATCH v2 0/2] next abi option Neil Horman
@ 2015-07-08 22:58 4% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-08 22:58 UTC (permalink / raw)
To: Neil Horman; +Cc: dev
2015-07-08 12:50, Neil Horman:
> On Wed, Jul 08, 2015 at 04:55:21PM +0200, Thomas Monjalon wrote:
> > This is the second version of the NEXT_ABI policy.
> > It can now be used for shared and static libraries.
> >
> > While updating rte.lib.mk, it appeared that some useless
> > (and not consistent) variables were used for some config
> > options. The first patch clean them.
> >
> > Thomas Monjalon (2):
> > mk: remove variables identical to config ones
> > mk: enable next abi preview
>
> For the series
> Acked-by: Neil Horman <nhorman@tuxdriver.com>
Applied, thanks Neil for your help
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 0/6] query hash key size in byte
@ 2015-07-08 23:17 3% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-08 23:17 UTC (permalink / raw)
To: Zhang, Helin; +Cc: dev
> > As different hardware has different hash key sizes, querying it (in byte)
> > per port was asked by users. Otherwise there is no convenient way to know
> > the size of hash key which should be prepared.
> >
> > v2 changes:
> > * Disabled the code changes by default, to avoid breaking ABI compatibility.
> >
> > v3 changes:
> > * Moved the newly added element right after 'uint16_t reta_size', where it
> > was a padding. So it will not break any ABI compatibility, and no need to
> > disable the code changes by default.
> >
> > Helin Zhang (6):
> > ethdev: add an field for querying hash key size
> > e1000: fill the hash key size
> > fm10k: fill the hash key size
> > i40e: fill the hash key size
> > ixgbe: fill the hash key size
> > app/testpmd: show the hash key size
>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Applied, thanks
It is assumed that inserting a new field in a padding alignment won't break
the ABI.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 00/11] Cuckoo hash
2015-06-28 22:25 4% ` [dpdk-dev] [PATCH v3 00/11] Cuckoo hash Pablo de Lara
2015-06-28 22:25 14% ` [dpdk-dev] [PATCH v3 10/11] doc: announce ABI change of librte_hash Pablo de Lara
@ 2015-07-08 23:23 0% ` Thomas Monjalon
1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2015-07-08 23:23 UTC (permalink / raw)
To: bruce.richardson; +Cc: dev
Bruce, what is the status of this series?
2015-06-28 23:25, Pablo de Lara:
> This patchset is to replace the existing hash library with
> a more efficient and functional approach, using the Cuckoo hash
> method to deal with collisions. This method is based on using
> two different hash functions to have two possible locations
> in the hash table where an entry can be.
> So, if a bucket is full, a new entry can push one of the items
> in that bucket to its alternative location, making space for itself.
>
> Advantages
> ~~~~~~
> - Offers the option to store more entries when the target bucket is full
> (unlike the previous implementation)
> - Memory efficient: for storing those entries, it is not necessary to
> request new memory, as the entries will be stored in the same table
> - Constant worst lookup time: in worst case scenario, it always takes
> the same time to look up an entry, as there are only two possible locations
> where an entry can be.
> - Storing data: user can store data in the hash table, unlike the
> previous implementation, but he can still use the old API
>
> This implementation tipically offers over 90% utilization.
> Notice that API has been extended, but old API remains. The main
> change in ABI is that rte_hash structure is now private and the
> deprecation of two macros.
>
> Changes in v3:
>
> - Now user can store variable size data, instead of 32 or 64-bit size data,
> using the new parameter "data_len" in rte_hash_parameters
> - Add lookup_bulk_with_hash function in performance unit tests
> - Add new functions that handle data in performance unit tests
> - Remove duplicates in performance unit tests
> - Fix rte_hash_reset, which was not reseting the last entry
[...]
> Pablo de Lara (11):
> eal: add const in prefetch functions
> hash: move rte_hash structure to C file and make it internal
> test/hash: enhance hash unit tests
> test/hash: rename new hash perf unit test back to original name
> hash: replace existing hash library with cuckoo hash implementation
> hash: add new lookup_bulk_with_hash function
> hash: add new function rte_hash_reset
> hash: add new functionality to store data in hash table
> MAINTAINERS: claim responsability for hash library
> doc: announce ABI change of librte_hash
> doc: update hash documentation
^ permalink raw reply [relevance 0%]
Results 601-800 of ~18000 next (newer) | prev (older) | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2015-05-11 3:46 [dpdk-dev] [PATCH 0/6] extend flow director to support L2_paylod type and VF filtering in i40e driver Jingjing Wu
2015-06-16 3:43 ` [dpdk-dev] [PATCH v2 0/4] extend flow director to support L2_paylod type Jingjing Wu
2015-06-26 2:26 0% ` Xu, HuilongX
2015-06-26 3:14 0% ` Zhang, Helin
2015-07-07 21:24 0% ` Thomas Monjalon
2015-05-26 15:41 [dpdk-dev] [PATCH v4 0/4] bonding corrections and additions Eric Kinzie
2015-05-26 15:41 ` [dpdk-dev] [PATCH v4 3/4] bond mode 4: allow external state machine Eric Kinzie
2015-07-02 13:30 4% ` Declan Doherty
2015-05-30 0:37 [dpdk-dev] [PATCH 0/2] User-space Ethtool Liang-Min Larry Wang
2015-06-17 22:22 ` [dpdk-dev] [PATCH v7 0/4] " Liang-Min Larry Wang
2015-06-18 2:04 ` Stephen Hemminger
2015-06-18 12:47 ` Wang, Liang-min
2015-06-23 15:19 0% ` Wang, Liang-min
2015-06-01 7:33 [dpdk-dev] [PATCH v6 00/18] unified packet type Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 " Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 02/18] ixgbe: support unified packet type in vectorized PMD Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 03/18] mbuf: add definitions of unified packet types Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 04/18] e1000: replace bit mask based packet type with unified packet type Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 05/18] ixgbe: " Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 06/18] i40e: " Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 07/18] enic: " Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 08/18] vmxnet3: " Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 09/18] fm10k: " Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 10/18] app/test-pipeline: " Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 11/18] app/testpmd: " Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 12/18] app/test: Remove useless code Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 13/18] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 14/18] examples/ip_reassembly: " Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 15/18] examples/l3fwd-acl: " Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 16/18] examples/l3fwd-power: " Helin Zhang
2015-06-19 8:14 3% ` [dpdk-dev] [PATCH v7 17/18] examples/l3fwd: " Helin Zhang
2015-06-19 8:14 4% ` [dpdk-dev] [PATCH v7 18/18] mbuf: remove old packet type bit masks Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 01/18] mbuf: redefine packet_type in rte_mbuf Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 02/18] ixgbe: support unified packet type in vectorized PMD Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 03/18] mbuf: add definitions of unified packet types Helin Zhang
2015-06-30 8:43 0% ` Olivier MATZ
2015-07-02 1:30 0% ` Zhang, Helin
2015-07-02 9:31 0% ` Olivier MATZ
2015-07-03 1:30 0% ` Zhang, Helin
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 04/18] e1000: replace bit mask based packet type with unified packet type Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 05/18] ixgbe: " Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 06/18] i40e: " Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 07/18] enic: " Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 08/18] vmxnet3: " Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 09/18] fm10k: " Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 10/18] app/test-pipeline: " Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 11/18] app/testpmd: " Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 12/18] app/test: Remove useless code Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 13/18] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 14/18] examples/ip_reassembly: " Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 15/18] examples/l3fwd-acl: " Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 16/18] examples/l3fwd-power: " Helin Zhang
2015-06-23 1:50 3% ` [dpdk-dev] [PATCH v8 17/18] examples/l3fwd: " Helin Zhang
2015-06-23 1:50 4% ` [dpdk-dev] [PATCH v8 18/18] mbuf: remove old packet type bit masks Helin Zhang
2015-06-23 16:13 0% ` [dpdk-dev] [PATCH v8 00/18] unified packet type Ananyev, Konstantin
2015-07-02 8:45 0% ` Liu, Yong
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 00/19] " Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 01/19] mbuf: redefine packet_type in rte_mbuf Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 02/19] mbuf: add definitions of unified packet types Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 03/19] e1000: replace bit mask based packet type with unified packet type Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 04/19] ixgbe: " Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 05/19] i40e: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 06/19] enic: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 07/19] vmxnet3: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 08/19] fm10k: " Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 09/19] cxgbe: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 10/19] app/test-pipeline: " Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 11/19] app/testpmd: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 12/19] app/test: Remove useless code Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 13/19] examples/ip_fragmentation: replace bit mask based packet type with unified packet type Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 14/19] examples/ip_reassembly: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 15/19] examples/l3fwd-acl: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 16/19] examples/l3fwd-power: " Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 17/19] examples/l3fwd: " Helin Zhang
2015-07-03 8:32 3% ` [dpdk-dev] [PATCH v9 18/19] examples/tep_termination: " Helin Zhang
2015-07-03 8:32 4% ` [dpdk-dev] [PATCH v9 19/19] mbuf: remove old packet type bit masks Helin Zhang
2015-06-02 3:16 [dpdk-dev] [PATCH v2 0/6] support i40e QinQ stripping and insertion Helin Zhang
2015-06-11 7:03 ` [dpdk-dev] [PATCH v3 0/7] " Helin Zhang
2015-06-11 7:03 ` [dpdk-dev] [PATCH v3 2/7] mbuf: use the reserved 16 bits for double vlan Helin Zhang
2015-06-25 8:31 3% ` Zhang, Helin
2015-06-28 20:36 0% ` Thomas Monjalon
2015-06-30 7:33 3% ` Olivier MATZ
2015-06-11 7:25 ` [dpdk-dev] [PATCH v3 0/7] support i40e QinQ stripping and insertion Wu, Jingjing
2015-07-07 14:43 0% ` Thomas Monjalon
2015-06-04 7:33 [dpdk-dev] [PATCH v2 0/6] query hash key size in byte Helin Zhang
2015-06-12 7:33 ` [dpdk-dev] [PATCH v3 " Helin Zhang
2015-06-12 9:31 ` Ananyev, Konstantin
2015-07-08 23:17 3% ` Thomas Monjalon
2015-06-05 8:16 [dpdk-dev] [PATCH v3 0/4] enable mirror functionality in i40e driver Jingjing Wu
2015-06-10 6:24 ` [dpdk-dev] [PATCH v4 " Jingjing Wu
2015-06-10 6:24 ` [dpdk-dev] [PATCH v4 1/4] ethdev: rename rte_eth_vmdq_mirror_conf Jingjing Wu
2015-06-26 7:03 5% ` Wu, Jingjing
2015-07-06 1:27 0% ` Wu, Jingjing
2015-07-07 14:51 4% ` Thomas Monjalon
2015-07-08 0:58 0% ` Wu, Jingjing
2015-07-08 10:31 5% ` Mcnamara, John
2015-07-08 10:35 0% ` Bruce Richardson
2015-06-05 14:33 [dpdk-dev] [PATCH 0/6] Cuckoo hash Pablo de Lara
2015-06-25 22:05 4% ` [dpdk-dev] [PATCH v2 00/11] " Pablo de Lara
2015-06-25 22:05 ` [dpdk-dev] [PATCH v2 08/11] hash: add new functionality to store data in hash table Pablo de Lara
2015-06-26 16:49 ` Stephen Hemminger
2015-06-28 22:23 ` De Lara Guarch, Pablo
2015-06-30 7:36 3% ` Stephen Hemminger
2015-06-25 22:05 14% ` [dpdk-dev] [PATCH v2 10/11] doc: announce ABI change of librte_hash Pablo de Lara
2015-06-28 22:25 4% ` [dpdk-dev] [PATCH v3 00/11] Cuckoo hash Pablo de Lara
2015-06-28 22:25 14% ` [dpdk-dev] [PATCH v3 10/11] doc: announce ABI change of librte_hash Pablo de Lara
2015-07-08 23:23 0% ` [dpdk-dev] [PATCH v3 00/11] Cuckoo hash Thomas Monjalon
2015-06-05 14:55 [dpdk-dev] [PATCH] lib: fix RTE_MBUF_METADATA macros Daniel Mrzyglod
2015-06-05 15:31 ` Dumitrescu, Cristian
2015-06-22 20:16 0% ` Thomas Monjalon
2015-06-22 20:23 0% ` Cyril Chemparathy
2015-06-22 20:34 0% ` Cyril Chemparathy
2015-06-06 10:32 [dpdk-dev] [PATCH v2 0/7] dynamic memzone Sergio Gonzalez Monroy
2015-06-19 17:21 4% ` [dpdk-dev] [PATCH v3 0/9] Dynamic memzone Sergio Gonzalez Monroy
2015-06-19 17:21 1% ` [dpdk-dev] [PATCH v3 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-06-19 17:21 14% ` [dpdk-dev] [PATCH v3 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
2015-06-25 14:05 4% ` [dpdk-dev] [PATCH v4 0/9] Dynamic memzone Sergio Gonzalez Monroy
2015-06-25 14:05 1% ` [dpdk-dev] [PATCH v4 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-06-25 14:05 14% ` [dpdk-dev] [PATCH v4 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
2015-06-26 11:32 4% ` [dpdk-dev] [PATCH v5 0/9] Dynamic memzones Sergio Gonzalez Monroy
2015-06-26 11:32 1% ` [dpdk-dev] [PATCH v5 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-06-26 11:32 14% ` [dpdk-dev] [PATCH v5 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
2015-06-26 15:29 4% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Sergio Gonzalez Monroy
2015-06-26 15:29 1% ` [dpdk-dev] [PATCH v6 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-06-26 15:29 14% ` [dpdk-dev] [PATCH v6 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
2015-06-26 16:13 0% ` [dpdk-dev] [PATCH v6 0/9] Dynamic memzones Ananyev, Konstantin
2015-07-03 9:55 4% ` [dpdk-dev] [PATCH v7 " Sergio Gonzalez Monroy
2015-07-03 9:55 1% ` [dpdk-dev] [PATCH v7 2/9] eal: memzone allocated by malloc Sergio Gonzalez Monroy
2015-07-03 9:55 14% ` [dpdk-dev] [PATCH v7 8/9] doc: announce ABI change of librte_malloc Sergio Gonzalez Monroy
2015-06-12 11:28 [dpdk-dev] [PATCH 0/4] ethdev: Add checks for function support in driver Bruce Richardson
2015-06-12 17:32 ` [dpdk-dev] [PATCH 4/4] ethdev: check support for rx_queue_count and descriptor_done fns Roger B. Melton
2015-06-15 10:14 ` Bruce Richardson
2015-07-06 15:11 3% ` Thomas Monjalon
2015-06-16 23:29 [dpdk-dev] [dpdk-announce] important design choices - statistics - ABI Thomas Monjalon
2015-06-17 10:35 ` Neil Horman
2015-06-17 11:06 ` Richardson, Bruce
2015-06-19 11:08 7% ` Mcnamara, John
2015-06-18 16:55 ` O'Driscoll, Tim
2015-06-19 10:26 9% ` Neil Horman
2015-06-19 12:32 9% ` Thomas Monjalon
2015-06-19 13:02 9% ` Neil Horman
2015-06-19 13:16 4% ` Thomas Monjalon
2015-06-19 15:27 9% ` Neil Horman
2015-06-19 15:51 9% ` Thomas Monjalon
2015-06-19 16:13 9% ` Thomas F Herbert
2015-06-19 17:02 8% ` Thomas Monjalon
2015-06-19 17:57 9% ` Thomas F Herbert
2015-06-17 5:48 [dpdk-dev] [PATCH] doc: announce ABI changes planned for unified packet type Helin Zhang
2015-07-03 8:49 21% ` [dpdk-dev] [PATCH v2] " Helin Zhang
2015-07-07 17:45 21% ` [dpdk-dev] [PATCH v3] " Helin Zhang
2015-07-08 15:58 4% ` Zhang, Helin
2015-06-19 3:37 [dpdk-dev] clang build failing in v2.0.0 from poisoned symbols Matthew Hall
2015-06-19 4:31 ` Matthew Hall
2015-06-19 10:15 ` Bruce Richardson
2015-06-21 2:37 ` [dpdk-dev] DPDK v2.0.0 has different rte_eal_pci_probe() behavior Matthew Hall
[not found] ` <CAO1kT8_C2QJUrNk-fqOQd=WmOkpvNw5jCvxEhfPdHwyCwBuyKA@mail.gmail.com>
2015-06-22 0:32 4% ` Matthew Hall
2015-06-19 9:41 [dpdk-dev] [PATCH v5 00/13] port: added port statistics Maciej Gajdzica
2015-06-19 9:41 ` [dpdk-dev] [PATCH v5 01/13] port: added structures for port stats and config option Maciej Gajdzica
2015-06-23 13:55 3% ` Thomas Monjalon
2015-06-23 14:30 3% ` Dumitrescu, Cristian
2015-06-23 14:54 0% ` Thomas Monjalon
2015-06-23 15:21 0% ` Dumitrescu, Cristian
2015-06-23 15:16 3% ` Neil Horman
[not found] <1434999524-26528-1-git-send-email-cchemparathy@ezchip.com>
2015-06-22 18:58 ` [dpdk-dev] [PATCH v2 08/12] mempool: allow config override on element alignment Cyril Chemparathy
2015-06-23 0:31 3% ` Ananyev, Konstantin
2015-06-23 20:43 4% ` Cyril Chemparathy
2015-06-23 21:21 0% ` Ananyev, Konstantin
2015-06-23 19:33 [dpdk-dev] [PATCH 1/2] rte_compat.h : Clean up some typos Neil Horman
2015-06-23 19:33 14% ` [dpdk-dev] [PATCH 2/2] ABI: Add some documentation Neil Horman
2015-06-24 11:21 4% ` Mcnamara, John
2015-06-24 18:34 ` [dpdk-dev] [PATCHv2 1/2] rte_compat.h : Clean up some typos Neil Horman
2015-06-24 18:34 14% ` [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation Neil Horman
2015-06-24 21:09 9% ` Thomas Monjalon
2015-06-25 11:35 9% ` Neil Horman
2015-06-25 13:22 7% ` Thomas Monjalon
2015-06-25 7:19 4% ` Zhang, Helin
2015-06-25 7:42 4% ` Gonzalez Monroy, Sergio
2015-06-25 8:00 4% ` Gonzalez Monroy, Sergio
2015-06-25 12:25 4% ` Neil Horman
2015-06-25 14:35 ` [dpdk-dev] [PATCHv3 1/3] rte_compat.h : Clean up some typos Neil Horman
2015-06-25 14:35 ` [dpdk-dev] [PATCHv3 2/3] rte_compat: Add MAP_STATIC_SYMBOL macro Neil Horman
2015-06-26 12:52 ` Thomas Monjalon
2015-06-26 14:30 3% ` Neil Horman
2015-06-28 20:13 0% ` Thomas Monjalon
2015-06-29 13:44 0% ` Neil Horman
2015-06-25 14:35 28% ` [dpdk-dev] [PATCHv3 3/3] ABI: Add some documentation Neil Horman
2015-06-26 13:00 4% ` Thomas Monjalon
2015-06-26 14:54 4% ` Neil Horman
2015-06-28 20:24 8% ` Thomas Monjalon
2015-06-29 13:53 4% ` Neil Horman
2015-06-29 13:59 ` [dpdk-dev] [PATCHv4 1/4] rte_compat.h : Clean up some typos Neil Horman
2015-06-29 13:59 28% ` [dpdk-dev] [PATCHv4 4/4] ABI: Add some documentation Neil Horman
2015-06-29 15:07 7% ` Thomas Monjalon
2015-06-26 12:59 3% [dpdk-dev] [PATCH v3 0/7] Expose IXGBE extended stats to DPDK apps Maryam Tahhan
2015-06-26 12:59 9% ` [dpdk-dev] [PATCH v3 4/7] ethdev: remove HW specific stats in stats structs Maryam Tahhan
2015-06-26 14:03 0% ` Kyle Larose
2015-06-26 14:30 11% ` Tahhan, Maryam
2015-06-26 14:37 0% ` Kyle Larose
2015-07-01 14:27 0% ` [dpdk-dev] [PATCH v3 0/7] Expose IXGBE extended stats to DPDK apps Tahhan, Maryam
2015-06-29 13:42 4% [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping John McNamara
2015-06-29 13:42 14% ` [dpdk-dev] [PATCH v2 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
2015-07-02 1:24 0% ` [dpdk-dev] [PATCH v2 0/7] ethdev: add support for ieee1588 timestamping Lu, Wenzhuo
2015-07-02 15:16 4% ` [dpdk-dev] [PATCH v3 " John McNamara
2015-07-02 15:16 14% ` [dpdk-dev] [PATCH v3 7/7] abi: announce mbuf addition for ieee1588 in DPDK 2.2 John McNamara
2015-07-06 13:16 4% ` Thomas Monjalon
2015-07-08 13:10 7% ` Bruce Richardson
2015-07-03 8:22 0% ` [dpdk-dev] [PATCH v3 0/7] ethdev: add support for ieee1588 timestamping Lu, Wenzhuo
2015-07-08 1:59 0% ` Fu, JingguoX
2015-07-01 6:18 3% [dpdk-dev] rte_lpm4 with expanded next hop support now available Matthew Hall
2015-07-01 11:20 4% ` Bruce Richardson
2015-07-01 15:59 0% ` Matthew Hall
2015-07-02 11:52 9% [dpdk-dev] [PATCH] doc: fix minor sphinx build warning John McNamara
2015-07-02 12:18 3% ` Thomas Monjalon
2015-07-02 13:28 0% ` Mcnamara, John
2015-07-02 13:50 [dpdk-dev] [PATCH 0/3] doc: added guidelines on dpdk documentation John McNamara
2015-07-02 13:50 3% ` [dpdk-dev] [PATCH 2/3] " John McNamara
2015-07-02 16:20 0% ` Thomas Monjalon
2015-07-02 14:15 8% [dpdk-dev] [PATCH v2] doc: fix minor sphinx build warning John McNamara
2015-07-06 14:55 0% ` Thomas Monjalon
2015-07-02 22:05 20% [dpdk-dev] [PATCH] mk: enable next abi in static libs Thomas Monjalon
2015-07-06 13:18 4% ` Thomas Monjalon
2015-07-06 13:35 9% ` Neil Horman
2015-07-06 13:49 8% ` Thomas Monjalon
2015-07-06 18:22 9% ` Neil Horman
2015-07-06 21:44 9% ` Thomas Monjalon
2015-07-07 11:14 9% ` Neil Horman
2015-07-07 12:46 7% ` Thomas Monjalon
2015-07-07 13:11 4% ` Neil Horman
2015-07-07 13:44 8% ` Neil Horman
2015-07-08 14:55 8% ` [dpdk-dev] [PATCH v2 0/2] next abi option Thomas Monjalon
2015-07-08 14:55 4% ` [dpdk-dev] [PATCH v2 1/2] mk: remove variables identical to config ones Thomas Monjalon
2015-07-08 14:55 34% ` [dpdk-dev] [PATCH v2 2/2] mk: enable next abi preview Thomas Monjalon
2015-07-08 16:44 33% ` [dpdk-dev] [PATCH v3] " Thomas Monjalon
2015-07-08 16:50 4% ` [dpdk-dev] [PATCH v2 0/2] next abi option Neil Horman
2015-07-08 22:58 4% ` Thomas Monjalon
2015-07-05 17:39 3% [dpdk-dev] [PATCH v4 0/8] Expose IXGBE extended stats to DPDK apps Maryam Tahhan
2015-07-05 17:39 9% ` [dpdk-dev] [PATCH v4 4/8] ethdev: remove HW specific stats in stats structs Maryam Tahhan
2015-07-06 13:28 [dpdk-dev] [PATCH 0/2] Native uio-based PMD for Mellanox ConnectX-3 devices leeopop
2015-07-06 13:28 ` [dpdk-dev] [PATCH 1/2] eal/persistent: new library to hold memory region after program exit leeopop
2015-07-06 19:19 1% ` Stephen Hemminger
2015-07-07 7:58 3% [dpdk-dev] [PATCH 0/3] fix the issue sctp flow cannot be matched in FVL FDIR Jingjing Wu
2015-07-07 9:04 0% ` Liu, Yong
2015-07-08 0:08 [dpdk-dev] [PATCH v3 0/4] bnx2x: poll mode driver Stephen Hemminger
2015-07-08 0:08 ` [dpdk-dev] [PATCH 1/4] eal: provide functions to access PCI config Stephen Hemminger
[not found] ` <d35efa226d95495e804181b2246063d2@HQ1WP-EXMB11.corp.brocade.com>
2015-07-08 16:11 3% ` Stephen Hemminger
2015-07-08 16:34 0% ` Thomas Monjalon
2015-07-08 1:24 3% [dpdk-dev] [PATCH] config: revert the CONFIG_RTE_MAX_QUEUES_PER_PORT to 256 Jijiang Liu
2015-07-08 2:08 20% [dpdk-dev] [PATCH] doc:announce ABI changes planned for struct rte_eth_dev to support up to 1024 queues per port Jijiang Liu
2015-07-08 11:07 4% ` Neil Horman
2015-07-08 11:27 [dpdk-dev] [PATCH] Make rte_hash struct internal - Cuckoo hash part 1 Pablo de Lara
2015-07-08 11:27 ` [dpdk-dev] [PATCH] hash: move rte_hash structure to C file and make it internal Pablo de Lara
2015-07-08 13:21 3% ` Bruce Richardson
2015-07-08 16:57 0% ` Matthew Hall
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).