* [PATCH v2 5/5] maintainers: claim i40e vector PMD on ARM
From: Jianbo Liu @ 2016-10-14 4:00 UTC (permalink / raw)
To: helin.zhang, jingjing.wu, jerin.jacob, dev, qi.z.zhang; +Cc: Jianbo Liu
In-Reply-To: <1476417604-22400-1-git-send-email-jianbo.liu@linaro.org>
Signed-off-by: Jianbo Liu <jianbo.liu@linaro.org>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f5fa82..621bda6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -151,6 +151,7 @@ F: lib/librte_acl/acl_run_neon.*
F: lib/librte_lpm/rte_lpm_neon.h
F: lib/librte_hash/rte*_arm64.h
F: drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
+F: drivers/net/i40e/i40e_rxtx_vec_neon.c
F: drivers/net/virtio/virtio_rxtx_simple_neon.c
EZchip TILE-Gx
--
2.4.11
^ permalink raw reply related
* [PATCH v2 4/5] i40e: make vector driver filenames consistent
From: Jianbo Liu @ 2016-10-14 4:00 UTC (permalink / raw)
To: helin.zhang, jingjing.wu, jerin.jacob, dev, qi.z.zhang; +Cc: Jianbo Liu
In-Reply-To: <1476417604-22400-1-git-send-email-jianbo.liu@linaro.org>
To be consistent with the naming for ARM NEON implementation,
i40e_rxtx_vec.c is renamed to i40e_rxtx_vec_sse.c.
Signed-off-by: Jianbo Liu <jianbo.liu@linaro.org>
---
drivers/net/i40e/Makefile | 4 ++--
drivers/net/i40e/{i40e_rxtx_vec.c => i40e_rxtx_vec_sse.c} | 0
2 files changed, 2 insertions(+), 2 deletions(-)
rename drivers/net/i40e/{i40e_rxtx_vec.c => i40e_rxtx_vec_sse.c} (100%)
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 9e92b38..13085fb 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -100,7 +100,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_rxtx.c
ifeq ($(CONFIG_RTE_ARCH_ARM64),y)
SRCS-$(CONFIG_RTE_LIBRTE_I40E_INC_VECTOR) += i40e_rxtx_vec_neon.c
else
-SRCS-$(CONFIG_RTE_LIBRTE_I40E_INC_VECTOR) += i40e_rxtx_vec.c
+SRCS-$(CONFIG_RTE_LIBRTE_I40E_INC_VECTOR) += i40e_rxtx_vec_sse.c
endif
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev_vf.c
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_pf.c
@@ -108,7 +108,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_fdir.c
# vector PMD driver needs SSE4.1 support
ifeq ($(findstring RTE_MACHINE_CPUFLAG_SSE4_1,$(CFLAGS)),)
-CFLAGS_i40e_rxtx_vec.o += -msse4.1
+CFLAGS_i40e_rxtx_vec_sse.o += -msse4.1
endif
diff --git a/drivers/net/i40e/i40e_rxtx_vec.c b/drivers/net/i40e/i40e_rxtx_vec_sse.c
similarity index 100%
rename from drivers/net/i40e/i40e_rxtx_vec.c
rename to drivers/net/i40e/i40e_rxtx_vec_sse.c
--
2.4.11
^ permalink raw reply related
* [PATCH v2 3/5] i40e: enable i40e vector PMD on ARMv8a platform
From: Jianbo Liu @ 2016-10-14 4:00 UTC (permalink / raw)
To: helin.zhang, jingjing.wu, jerin.jacob, dev, qi.z.zhang; +Cc: Jianbo Liu
In-Reply-To: <1476417604-22400-1-git-send-email-jianbo.liu@linaro.org>
Signed-off-by: Jianbo Liu <jianbo.liu@linaro.org>
---
config/defconfig_arm64-armv8a-linuxapp-gcc | 1 -
doc/guides/nics/features/i40e_vec.ini | 1 +
doc/guides/nics/features/i40e_vf_vec.ini | 1 +
3 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/config/defconfig_arm64-armv8a-linuxapp-gcc b/config/defconfig_arm64-armv8a-linuxapp-gcc
index a0f4473..6321884 100644
--- a/config/defconfig_arm64-armv8a-linuxapp-gcc
+++ b/config/defconfig_arm64-armv8a-linuxapp-gcc
@@ -45,6 +45,5 @@ CONFIG_RTE_TOOLCHAIN_GCC=y
CONFIG_RTE_EAL_IGB_UIO=n
CONFIG_RTE_LIBRTE_FM10K_PMD=n
-CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
CONFIG_RTE_SCHED_VECTOR=n
diff --git a/doc/guides/nics/features/i40e_vec.ini b/doc/guides/nics/features/i40e_vec.ini
index 0953d84..edd6b71 100644
--- a/doc/guides/nics/features/i40e_vec.ini
+++ b/doc/guides/nics/features/i40e_vec.ini
@@ -37,3 +37,4 @@ Linux UIO = Y
Linux VFIO = Y
x86-32 = Y
x86-64 = Y
+ARMv8 = Y
diff --git a/doc/guides/nics/features/i40e_vf_vec.ini b/doc/guides/nics/features/i40e_vf_vec.ini
index 2a44bf6..d6674f7 100644
--- a/doc/guides/nics/features/i40e_vf_vec.ini
+++ b/doc/guides/nics/features/i40e_vf_vec.ini
@@ -26,3 +26,4 @@ Linux UIO = Y
Linux VFIO = Y
x86-32 = Y
x86-64 = Y
+ARMv8 = Y
--
2.4.11
^ permalink raw reply related
* [PATCH v2 2/5] i40e: implement vector PMD for ARM architecture
From: Jianbo Liu @ 2016-10-14 4:00 UTC (permalink / raw)
To: helin.zhang, jingjing.wu, jerin.jacob, dev, qi.z.zhang; +Cc: Jianbo Liu
In-Reply-To: <1476417604-22400-1-git-send-email-jianbo.liu@linaro.org>
Use ARM NEON intrinsic to implement i40e vPMD
Signed-off-by: Jianbo Liu <jianbo.liu@linaro.org>
---
drivers/net/i40e/Makefile | 4 +
drivers/net/i40e/i40e_rxtx_vec_neon.c | 614 ++++++++++++++++++++++++++++++++++
2 files changed, 618 insertions(+)
create mode 100644 drivers/net/i40e/i40e_rxtx_vec_neon.c
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 53fe145..9e92b38 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -97,7 +97,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_dcb.c
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_rxtx.c
+ifeq ($(CONFIG_RTE_ARCH_ARM64),y)
+SRCS-$(CONFIG_RTE_LIBRTE_I40E_INC_VECTOR) += i40e_rxtx_vec_neon.c
+else
SRCS-$(CONFIG_RTE_LIBRTE_I40E_INC_VECTOR) += i40e_rxtx_vec.c
+endif
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev_vf.c
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_pf.c
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_fdir.c
diff --git a/drivers/net/i40e/i40e_rxtx_vec_neon.c b/drivers/net/i40e/i40e_rxtx_vec_neon.c
new file mode 100644
index 0000000..011c54e
--- /dev/null
+++ b/drivers/net/i40e/i40e_rxtx_vec_neon.c
@@ -0,0 +1,614 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+
+#include "base/i40e_prototype.h"
+#include "base/i40e_type.h"
+#include "i40e_ethdev.h"
+#include "i40e_rxtx.h"
+#include "i40e_rxtx_vec_common.h"
+
+#include <arm_neon.h>
+
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+static inline void
+i40e_rxq_rearm(struct i40e_rx_queue *rxq)
+{
+ int i;
+ uint16_t rx_id;
+ volatile union i40e_rx_desc *rxdp;
+ struct i40e_rx_entry *rxep = &rxq->sw_ring[rxq->rxrearm_start];
+ struct rte_mbuf *mb0, *mb1;
+ uint64x2_t dma_addr0, dma_addr1;
+ uint64x2_t zero = vdupq_n_u64(0);
+ uint64_t paddr;
+ uint8x8_t p;
+
+ rxdp = rxq->rx_ring + rxq->rxrearm_start;
+
+ /* Pull 'n' more MBUFs into the software ring */
+ if (unlikely(rte_mempool_get_bulk(rxq->mp,
+ (void *)rxep,
+ RTE_I40E_RXQ_REARM_THRESH) < 0)) {
+ if (rxq->rxrearm_nb + RTE_I40E_RXQ_REARM_THRESH >=
+ rxq->nb_rx_desc) {
+ for (i = 0; i < RTE_I40E_DESCS_PER_LOOP; i++) {
+ rxep[i].mbuf = &rxq->fake_mbuf;
+ vst1q_u64((uint64_t *)&rxdp[i].read, zero);
+ }
+ }
+ rte_eth_devices[rxq->port_id].data->rx_mbuf_alloc_failed +=
+ RTE_I40E_RXQ_REARM_THRESH;
+ return;
+ }
+
+ p = vld1_u8((uint8_t *)&rxq->mbuf_initializer);
+
+ /* Initialize the mbufs in vector, process 2 mbufs in one loop */
+ for (i = 0; i < RTE_I40E_RXQ_REARM_THRESH; i += 2, rxep += 2) {
+ mb0 = rxep[0].mbuf;
+ mb1 = rxep[1].mbuf;
+
+ /* Flush mbuf with pkt template.
+ * Data to be rearmed is 6 bytes long.
+ * Though, RX will overwrite ol_flags that are coming next
+ * anyway. So overwrite whole 8 bytes with one load:
+ * 6 bytes of rearm_data plus first 2 bytes of ol_flags.
+ */
+ vst1_u8((uint8_t *)&mb0->rearm_data, p);
+ paddr = mb0->buf_physaddr + RTE_PKTMBUF_HEADROOM;
+ dma_addr0 = vdupq_n_u64(paddr);
+
+ /* flush desc with pa dma_addr */
+ vst1q_u64((uint64_t *)&rxdp++->read, dma_addr0);
+
+ vst1_u8((uint8_t *)&mb1->rearm_data, p);
+ paddr = mb1->buf_physaddr + RTE_PKTMBUF_HEADROOM;
+ dma_addr1 = vdupq_n_u64(paddr);
+ vst1q_u64((uint64_t *)&rxdp++->read, dma_addr1);
+ }
+
+ rxq->rxrearm_start += RTE_I40E_RXQ_REARM_THRESH;
+ if (rxq->rxrearm_start >= rxq->nb_rx_desc)
+ rxq->rxrearm_start = 0;
+
+ rxq->rxrearm_nb -= RTE_I40E_RXQ_REARM_THRESH;
+
+ rx_id = (uint16_t)((rxq->rxrearm_start == 0) ?
+ (rxq->nb_rx_desc - 1) : (rxq->rxrearm_start - 1));
+
+ /* Update the tail pointer on the NIC */
+ I40E_PCI_REG_WRITE(rxq->qrx_tail, rx_id);
+}
+
+/* Handling the offload flags (olflags) field takes computation
+ * time when receiving packets. Therefore we provide a flag to disable
+ * the processing of the olflags field when they are not needed. This
+ * gives improved performance, at the cost of losing the offload info
+ * in the received packet
+ */
+#ifdef RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE
+
+static inline void
+desc_to_olflags_v(uint64x2_t descs[4], struct rte_mbuf **rx_pkts)
+{
+ uint32x4_t vlan0, vlan1, rss, l3_l4e;
+
+ /* mask everything except RSS, flow director and VLAN flags
+ * bit2 is for VLAN tag, bit11 for flow director indication
+ * bit13:12 for RSS indication.
+ */
+ const uint32x4_t rss_vlan_msk = {
+ 0x1c03804, 0x1c03804, 0x1c03804, 0x1c03804};
+
+ /* map rss and vlan type to rss hash and vlan flag */
+ const uint8x16_t vlan_flags = {
+ 0, 0, 0, 0,
+ PKT_RX_VLAN_PKT | PKT_RX_VLAN_STRIPPED, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0};
+
+ const uint8x16_t rss_flags = {
+ 0, PKT_RX_FDIR, 0, 0,
+ 0, 0, PKT_RX_RSS_HASH, PKT_RX_RSS_HASH | PKT_RX_FDIR,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0};
+
+ const uint8x16_t l3_l4e_flags = {
+ 0,
+ PKT_RX_IP_CKSUM_BAD,
+ PKT_RX_L4_CKSUM_BAD,
+ PKT_RX_L4_CKSUM_BAD | PKT_RX_IP_CKSUM_BAD,
+ PKT_RX_EIP_CKSUM_BAD,
+ PKT_RX_EIP_CKSUM_BAD | PKT_RX_IP_CKSUM_BAD,
+ PKT_RX_EIP_CKSUM_BAD | PKT_RX_L4_CKSUM_BAD,
+ PKT_RX_EIP_CKSUM_BAD | PKT_RX_L4_CKSUM_BAD | PKT_RX_IP_CKSUM_BAD,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+
+ vlan0 = vzipq_u32(vreinterpretq_u32_u64(descs[0]),
+ vreinterpretq_u32_u64(descs[2])).val[1];
+ vlan1 = vzipq_u32(vreinterpretq_u32_u64(descs[1]),
+ vreinterpretq_u32_u64(descs[3])).val[1];
+ vlan0 = vzipq_u32(vlan0, vlan1).val[0];
+
+ vlan1 = vandq_u32(vlan0, rss_vlan_msk);
+ vlan0 = vreinterpretq_u32_u8(vqtbl1q_u8(vlan_flags,
+ vreinterpretq_u8_u32(vlan1)));
+
+ rss = vshrq_n_u32(vlan1, 11);
+ rss = vreinterpretq_u32_u8(vqtbl1q_u8(rss_flags,
+ vreinterpretq_u8_u32(rss)));
+
+ l3_l4e = vshrq_n_u32(vlan1, 22);
+ l3_l4e = vreinterpretq_u32_u8(vqtbl1q_u8(l3_l4e_flags,
+ vreinterpretq_u8_u32(l3_l4e)));
+
+
+ vlan0 = vorrq_u32(vlan0, rss);
+ vlan0 = vorrq_u32(vlan0, l3_l4e);
+
+ rx_pkts[0]->ol_flags = vgetq_lane_u32(vlan0, 0);
+ rx_pkts[1]->ol_flags = vgetq_lane_u32(vlan0, 1);
+ rx_pkts[2]->ol_flags = vgetq_lane_u32(vlan0, 2);
+ rx_pkts[3]->ol_flags = vgetq_lane_u32(vlan0, 3);
+}
+#else
+#define desc_to_olflags_v(descs, rx_pkts) do {} while (0)
+#endif
+
+#define PKTLEN_SHIFT 10
+
+#define I40E_VPMD_DESC_DD_MASK 0x0001000100010001ULL
+
+static inline void
+desc_to_ptype_v(uint64x2_t descs[4], struct rte_mbuf **rx_pkts)
+{
+ int i;
+ uint8_t ptype;
+ uint8x16_t tmp;
+
+ for (i = 0; i < 4; i++) {
+ tmp = vreinterpretq_u8_u64(vshrq_n_u64(descs[i], 30));
+ ptype = vgetq_lane_u8(tmp, 8);
+ rx_pkts[0]->packet_type = i40e_rxd_pkt_type_mapping(ptype);
+ }
+
+}
+
+ /*
+ * Notice:
+ * - nb_pkts < RTE_I40E_DESCS_PER_LOOP, just return no packet
+ * - nb_pkts > RTE_I40E_VPMD_RX_BURST, only scan RTE_I40E_VPMD_RX_BURST
+ * numbers of DD bits
+ */
+static inline uint16_t
+_recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts, uint8_t *split_packet)
+{
+ volatile union i40e_rx_desc *rxdp;
+ struct i40e_rx_entry *sw_ring;
+ uint16_t nb_pkts_recd;
+ int pos;
+ uint64_t var;
+
+ /* mask to shuffle from desc. to mbuf */
+ uint8x16_t shuf_msk = {
+ 0xFF, 0xFF, /* pkt_type set as unknown */
+ 0xFF, 0xFF, /* pkt_type set as unknown */
+ 14, 15, /* octet 15~14, low 16 bits pkt_len */
+ 0xFF, 0xFF, /* skip high 16 bits pkt_len, zero out */
+ 14, 15, /* octet 15~14, 16 bits data_len */
+ 2, 3, /* octet 2~3, low 16 bits vlan_macip */
+ 4, 5, 6, 7 /* octet 4~7, 32bits rss */
+ };
+
+ uint8x16_t eop_check = {
+ 0x02, 0x00, 0x02, 0x00,
+ 0x02, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+ uint16x8_t crc_adjust = {
+ 0, 0, /* ignore pkt_type field */
+ rxq->crc_len, /* sub crc on pkt_len */
+ 0, /* ignore high-16bits of pkt_len */
+ rxq->crc_len, /* sub crc on data_len */
+ 0, 0, 0 /* ignore non-length fields */
+ };
+
+ /* nb_pkts shall be less equal than RTE_I40E_MAX_RX_BURST */
+ nb_pkts = RTE_MIN(nb_pkts, RTE_I40E_MAX_RX_BURST);
+
+ /* nb_pkts has to be floor-aligned to RTE_I40E_DESCS_PER_LOOP */
+ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_I40E_DESCS_PER_LOOP);
+
+ /* Just the act of getting into the function from the application is
+ * going to cost about 7 cycles
+ */
+ rxdp = rxq->rx_ring + rxq->rx_tail;
+
+ rte_prefetch_non_temporal(rxdp);
+
+ /* See if we need to rearm the RX queue - gives the prefetch a bit
+ * of time to act
+ */
+ if (rxq->rxrearm_nb > RTE_I40E_RXQ_REARM_THRESH)
+ i40e_rxq_rearm(rxq);
+
+ /* Before we start moving massive data around, check to see if
+ * there is actually a packet available
+ */
+ if (!(rxdp->wb.qword1.status_error_len &
+ rte_cpu_to_le_32(1 << I40E_RX_DESC_STATUS_DD_SHIFT)))
+ return 0;
+
+ /* 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
+ * [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
+ */
+
+ for (pos = 0, nb_pkts_recd = 0; pos < nb_pkts;
+ pos += RTE_I40E_DESCS_PER_LOOP,
+ rxdp += RTE_I40E_DESCS_PER_LOOP) {
+ uint64x2_t descs[RTE_I40E_DESCS_PER_LOOP];
+ uint8x16_t pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
+ uint16x8x2_t sterr_tmp1, sterr_tmp2;
+ uint64x2_t mbp1, mbp2;
+ uint16x8_t staterr;
+ uint16x8_t tmp;
+ uint64_t stat;
+
+ int32x4_t len_shl = {0, 0, 0, PKTLEN_SHIFT};
+
+ /* B.1 load 1 mbuf point */
+ mbp1 = vld1q_u64((uint64_t *)&sw_ring[pos]);
+ /* Read desc statuses backwards to avoid race condition */
+ /* A.1 load 4 pkts desc */
+ descs[3] = vld1q_u64((uint64_t *)(rxdp + 3));
+ rte_rmb();
+
+ /* B.2 copy 2 mbuf point into rx_pkts */
+ vst1q_u64((uint64_t *)&rx_pkts[pos], mbp1);
+
+ /* B.1 load 1 mbuf point */
+ mbp2 = vld1q_u64((uint64_t *)&sw_ring[pos + 2]);
+
+ descs[2] = vld1q_u64((uint64_t *)(rxdp + 2));
+ /* B.1 load 2 mbuf point */
+ descs[1] = vld1q_u64((uint64_t *)(rxdp + 1));
+ descs[0] = vld1q_u64((uint64_t *)(rxdp));
+
+ /* B.2 copy 2 mbuf point into rx_pkts */
+ vst1q_u64((uint64_t *)&rx_pkts[pos + 2], mbp2);
+
+ if (split_packet) {
+ rte_mbuf_prefetch_part2(rx_pkts[pos]);
+ rte_mbuf_prefetch_part2(rx_pkts[pos + 1]);
+ rte_mbuf_prefetch_part2(rx_pkts[pos + 2]);
+ rte_mbuf_prefetch_part2(rx_pkts[pos + 3]);
+ }
+
+ /* avoid compiler reorder optimization */
+ rte_compiler_barrier();
+
+ /* pkt 3,4 shift the pktlen field to be 16-bit aligned*/
+ uint32x4_t len3 = vshlq_u32(vreinterpretq_u32_u64(descs[3]),
+ len_shl);
+ descs[3] = vreinterpretq_u64_u32(len3);
+ uint32x4_t len2 = vshlq_u32(vreinterpretq_u32_u64(descs[2]),
+ len_shl);
+ descs[2] = vreinterpretq_u64_u32(len2);
+
+ /* D.1 pkt 3,4 convert format from desc to pktmbuf */
+ pkt_mb4 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[3]), shuf_msk);
+ pkt_mb3 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[2]), shuf_msk);
+
+ /* C.1 4=>2 filter staterr info only */
+ sterr_tmp2 = vzipq_u16(vreinterpretq_u16_u64(descs[1]),
+ vreinterpretq_u16_u64(descs[3]));
+ /* C.1 4=>2 filter staterr info only */
+ sterr_tmp1 = vzipq_u16(vreinterpretq_u16_u64(descs[0]),
+ vreinterpretq_u16_u64(descs[2]));
+
+ /* C.2 get 4 pkts staterr value */
+ staterr = vzipq_u16(sterr_tmp1.val[1],
+ sterr_tmp2.val[1]).val[0];
+ stat = vgetq_lane_u64(vreinterpretq_u64_u16(staterr), 0);
+
+ desc_to_olflags_v(descs, &rx_pkts[pos]);
+
+ /* D.2 pkt 3,4 set in_port/nb_seg and remove crc */
+ tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb4), crc_adjust);
+ pkt_mb4 = vreinterpretq_u8_u16(tmp);
+ tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb3), crc_adjust);
+ pkt_mb3 = vreinterpretq_u8_u16(tmp);
+
+ /* pkt 1,2 shift the pktlen field to be 16-bit aligned*/
+ uint32x4_t len1 = vshlq_u32(vreinterpretq_u32_u64(descs[1]),
+ len_shl);
+ descs[1] = vreinterpretq_u64_u32(len1);
+ uint32x4_t len0 = vshlq_u32(vreinterpretq_u32_u64(descs[0]),
+ len_shl);
+ descs[0] = vreinterpretq_u64_u32(len0);
+
+ /* D.1 pkt 1,2 convert format from desc to pktmbuf */
+ pkt_mb2 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[1]), shuf_msk);
+ pkt_mb1 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[0]), shuf_msk);
+
+ /* D.3 copy final 3,4 data to rx_pkts */
+ vst1q_u8((void *)&rx_pkts[pos + 3]->rx_descriptor_fields1,
+ pkt_mb4);
+ vst1q_u8((void *)&rx_pkts[pos + 2]->rx_descriptor_fields1,
+ pkt_mb3);
+
+ /* D.2 pkt 1,2 set in_port/nb_seg and remove crc */
+ tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb2), crc_adjust);
+ pkt_mb2 = vreinterpretq_u8_u16(tmp);
+ tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb1), crc_adjust);
+ pkt_mb1 = vreinterpretq_u8_u16(tmp);
+
+ /* C* extract and record EOP bit */
+ if (split_packet) {
+ uint8x16_t eop_shuf_mask = {
+ 0x00, 0x02, 0x04, 0x06,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF};
+ uint8x16_t eop_bits;
+
+ /* and with mask to extract bits, flipping 1-0 */
+ eop_bits = vmvnq_u8(vreinterpretq_u8_u16(staterr));
+ eop_bits = vandq_u8(eop_bits, eop_check);
+ /* the staterr values are not in order, as the count
+ * count of dd bits doesn't care. However, for end of
+ * packet tracking, we do care, so shuffle. This also
+ * compresses the 32-bit values to 8-bit
+ */
+ eop_bits = vqtbl1q_u8(eop_bits, eop_shuf_mask);
+
+ /* store the resulting 32-bit value */
+ vst1q_lane_u32((uint32_t *)split_packet,
+ vreinterpretq_u32_u8(eop_bits), 0);
+ split_packet += RTE_I40E_DESCS_PER_LOOP;
+
+ /* zero-out next pointers */
+ rx_pkts[pos]->next = NULL;
+ rx_pkts[pos + 1]->next = NULL;
+ rx_pkts[pos + 2]->next = NULL;
+ rx_pkts[pos + 3]->next = NULL;
+ }
+
+ rte_prefetch_non_temporal(rxdp + RTE_I40E_DESCS_PER_LOOP);
+
+ /* D.3 copy final 1,2 data to rx_pkts */
+ vst1q_u8((void *)&rx_pkts[pos + 1]->rx_descriptor_fields1,
+ pkt_mb2);
+ vst1q_u8((void *)&rx_pkts[pos]->rx_descriptor_fields1,
+ pkt_mb1);
+ desc_to_ptype_v(descs, &rx_pkts[pos]);
+ /* C.4 calc avaialbe number of desc */
+ var = __builtin_popcountll(stat & I40E_VPMD_DESC_DD_MASK);
+ nb_pkts_recd += var;
+ if (likely(var != RTE_I40E_DESCS_PER_LOOP))
+ break;
+ }
+
+ /* Update our internal tail pointer */
+ rxq->rx_tail = (uint16_t)(rxq->rx_tail + nb_pkts_recd);
+ rxq->rx_tail = (uint16_t)(rxq->rx_tail & (rxq->nb_rx_desc - 1));
+ rxq->rxrearm_nb = (uint16_t)(rxq->rxrearm_nb + nb_pkts_recd);
+
+ return nb_pkts_recd;
+}
+
+ /*
+ * Notice:
+ * - nb_pkts < RTE_I40E_DESCS_PER_LOOP, just return no packet
+ * - nb_pkts > RTE_I40E_VPMD_RX_BURST, only scan RTE_I40E_VPMD_RX_BURST
+ * numbers of DD bits
+ */
+uint16_t
+i40e_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+ return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL);
+}
+
+ /* vPMD receive routine that reassembles scattered packets
+ * Notice:
+ * - nb_pkts < RTE_I40E_DESCS_PER_LOOP, just return no packet
+ * - nb_pkts > RTE_I40E_VPMD_RX_BURST, only scan RTE_I40E_VPMD_RX_BURST
+ * numbers of DD bits
+ */
+uint16_t
+i40e_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+
+ struct i40e_rx_queue *rxq = rx_queue;
+ uint8_t split_flags[RTE_I40E_VPMD_RX_BURST] = {0};
+
+ /* get some new buffers */
+ uint16_t nb_bufs = _recv_raw_pkts_vec(rxq, rx_pkts, nb_pkts,
+ split_flags);
+ if (nb_bufs == 0)
+ return 0;
+
+ /* happy day case, full burst + no packets to be joined */
+ const uint64_t *split_fl64 = (uint64_t *)split_flags;
+
+ if (rxq->pkt_first_seg == NULL &&
+ split_fl64[0] == 0 && split_fl64[1] == 0 &&
+ split_fl64[2] == 0 && split_fl64[3] == 0)
+ return nb_bufs;
+
+ /* reassemble any packets that need reassembly*/
+ unsigned i = 0;
+
+ if (rxq->pkt_first_seg == NULL) {
+ /* find the first split flag, and only reassemble then*/
+ while (i < nb_bufs && !split_flags[i])
+ i++;
+ if (i == nb_bufs)
+ return nb_bufs;
+ }
+ return i + reassemble_packets(rxq, &rx_pkts[i], nb_bufs - i,
+ &split_flags[i]);
+}
+
+static inline void
+vtx1(volatile struct i40e_tx_desc *txdp,
+ struct rte_mbuf *pkt, uint64_t flags)
+{
+ uint64_t high_qw = (I40E_TX_DESC_DTYPE_DATA |
+ ((uint64_t)flags << I40E_TXD_QW1_CMD_SHIFT) |
+ ((uint64_t)pkt->data_len << I40E_TXD_QW1_TX_BUF_SZ_SHIFT));
+
+ uint64x2_t descriptor = {pkt->buf_physaddr + pkt->data_off, high_qw};
+ vst1q_u64((uint64_t *)txdp, descriptor);
+}
+
+static inline void
+vtx(volatile struct i40e_tx_desc *txdp,
+ struct rte_mbuf **pkt, uint16_t nb_pkts, uint64_t flags)
+{
+ int i;
+
+ for (i = 0; i < nb_pkts; ++i, ++txdp, ++pkt)
+ vtx1(txdp, *pkt, flags);
+}
+
+uint16_t
+i40e_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ struct i40e_tx_queue *txq = (struct i40e_tx_queue *)tx_queue;
+ volatile struct i40e_tx_desc *txdp;
+ struct i40e_tx_entry *txep;
+ uint16_t n, nb_commit, tx_id;
+ uint64_t flags = I40E_TD_CMD;
+ uint64_t rs = I40E_TX_DESC_CMD_RS | I40E_TD_CMD;
+ int i;
+
+ /* cross rx_thresh boundary is not allowed */
+ nb_pkts = RTE_MIN(nb_pkts, txq->tx_rs_thresh);
+
+ if (txq->nb_tx_free < txq->tx_free_thresh)
+ i40e_tx_free_bufs(txq);
+
+ nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_tx_free, nb_pkts);
+ if (unlikely(nb_pkts == 0))
+ return 0;
+
+ tx_id = txq->tx_tail;
+ txdp = &txq->tx_ring[tx_id];
+ txep = &txq->sw_ring[tx_id];
+
+ txq->nb_tx_free = (uint16_t)(txq->nb_tx_free - nb_pkts);
+
+ n = (uint16_t)(txq->nb_tx_desc - tx_id);
+ if (nb_commit >= n) {
+ tx_backlog_entry(txep, tx_pkts, n);
+
+ for (i = 0; i < n - 1; ++i, ++tx_pkts, ++txdp)
+ vtx1(txdp, *tx_pkts, flags);
+
+ vtx1(txdp, *tx_pkts++, rs);
+
+ nb_commit = (uint16_t)(nb_commit - n);
+
+ tx_id = 0;
+ txq->tx_next_rs = (uint16_t)(txq->tx_rs_thresh - 1);
+
+ /* avoid reach the end of ring */
+ txdp = &txq->tx_ring[tx_id];
+ txep = &txq->sw_ring[tx_id];
+ }
+
+ tx_backlog_entry(txep, tx_pkts, nb_commit);
+
+ vtx(txdp, tx_pkts, nb_commit, flags);
+
+ tx_id = (uint16_t)(tx_id + nb_commit);
+ if (tx_id > txq->tx_next_rs) {
+ txq->tx_ring[txq->tx_next_rs].cmd_type_offset_bsz |=
+ rte_cpu_to_le_64(((uint64_t)I40E_TX_DESC_CMD_RS) <<
+ I40E_TXD_QW1_CMD_SHIFT);
+ txq->tx_next_rs =
+ (uint16_t)(txq->tx_next_rs + txq->tx_rs_thresh);
+ }
+
+ txq->tx_tail = tx_id;
+
+ I40E_PCI_REG_WRITE(txq->qtx_tail, txq->tx_tail);
+
+ return nb_pkts;
+}
+
+void __attribute__((cold))
+i40e_rx_queue_release_mbufs_vec(struct i40e_rx_queue *rxq)
+{
+ _i40e_rx_queue_release_mbufs_vec(rxq);
+}
+
+int __attribute__((cold))
+i40e_rxq_vec_setup(struct i40e_rx_queue *rxq)
+{
+ return i40e_rxq_vec_setup_default(rxq);
+}
+
+int __attribute__((cold))
+i40e_txq_vec_setup(struct i40e_tx_queue __rte_unused *txq)
+{
+ return 0;
+}
+
+int __attribute__((cold))
+i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
+{
+ return i40e_rx_vec_dev_conf_condition_check_default(dev);
+}
--
2.4.11
^ permalink raw reply related
* [PATCH v2 1/5] i40e: extract non-x86 specific code from vector driver
From: Jianbo Liu @ 2016-10-14 4:00 UTC (permalink / raw)
To: helin.zhang, jingjing.wu, jerin.jacob, dev, qi.z.zhang; +Cc: Jianbo Liu
In-Reply-To: <1476417604-22400-1-git-send-email-jianbo.liu@linaro.org>
move scalar code which does not use x86 intrinsic functions to new file
"i40e_rxtx_vec_common.h", while keeping x86 code in i40e_rxtx_vec.c.
This allows the scalar code to to be shared among vector drivers for
different platforms.
Signed-off-by: Jianbo Liu <jianbo.liu@linaro.org>
---
drivers/net/i40e/i40e_rxtx_vec.c | 196 +------------------------
drivers/net/i40e/i40e_rxtx_vec_common.h | 251 ++++++++++++++++++++++++++++++++
2 files changed, 255 insertions(+), 192 deletions(-)
create mode 100644 drivers/net/i40e/i40e_rxtx_vec_common.h
diff --git a/drivers/net/i40e/i40e_rxtx_vec.c b/drivers/net/i40e/i40e_rxtx_vec.c
index 0ee0241..3607312 100644
--- a/drivers/net/i40e/i40e_rxtx_vec.c
+++ b/drivers/net/i40e/i40e_rxtx_vec.c
@@ -39,6 +39,7 @@
#include "base/i40e_type.h"
#include "i40e_ethdev.h"
#include "i40e_rxtx.h"
+#include "i40e_rxtx_vec_common.h"
#include <tmmintrin.h>
@@ -445,68 +446,6 @@ i40e_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL);
}
-static inline uint16_t
-reassemble_packets(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_bufs,
- uint16_t nb_bufs, uint8_t *split_flags)
-{
- struct rte_mbuf *pkts[RTE_I40E_VPMD_RX_BURST]; /*finished pkts*/
- struct rte_mbuf *start = rxq->pkt_first_seg;
- struct rte_mbuf *end = rxq->pkt_last_seg;
- unsigned pkt_idx, buf_idx;
-
- for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) {
- if (end != NULL) {
- /* processing a split packet */
- end->next = rx_bufs[buf_idx];
- rx_bufs[buf_idx]->data_len += rxq->crc_len;
-
- start->nb_segs++;
- start->pkt_len += rx_bufs[buf_idx]->data_len;
- end = end->next;
-
- if (!split_flags[buf_idx]) {
- /* it's the last packet of the set */
- start->hash = end->hash;
- start->ol_flags = end->ol_flags;
- /* we need to strip crc for the whole packet */
- start->pkt_len -= rxq->crc_len;
- if (end->data_len > rxq->crc_len) {
- end->data_len -= rxq->crc_len;
- } else {
- /* free up last mbuf */
- struct rte_mbuf *secondlast = start;
-
- while (secondlast->next != end)
- secondlast = secondlast->next;
- secondlast->data_len -= (rxq->crc_len -
- end->data_len);
- secondlast->next = NULL;
- rte_pktmbuf_free_seg(end);
- end = secondlast;
- }
- pkts[pkt_idx++] = start;
- start = end = NULL;
- }
- } else {
- /* not processing a split packet */
- if (!split_flags[buf_idx]) {
- /* not a split packet, save and skip */
- pkts[pkt_idx++] = rx_bufs[buf_idx];
- continue;
- }
- end = start = rx_bufs[buf_idx];
- rx_bufs[buf_idx]->data_len += rxq->crc_len;
- rx_bufs[buf_idx]->pkt_len += rxq->crc_len;
- }
- }
-
- /* save the partial packet for next time */
- rxq->pkt_first_seg = start;
- rxq->pkt_last_seg = end;
- memcpy(rx_bufs, pkts, pkt_idx * (sizeof(*pkts)));
- return pkt_idx;
-}
-
/* vPMD receive routine that reassembles scattered packets
* Notice:
* - nb_pkts < RTE_I40E_DESCS_PER_LOOP, just return no packet
@@ -572,73 +511,6 @@ vtx(volatile struct i40e_tx_desc *txdp,
vtx1(txdp, *pkt, flags);
}
-static inline int __attribute__((always_inline))
-i40e_tx_free_bufs(struct i40e_tx_queue *txq)
-{
- struct i40e_tx_entry *txep;
- uint32_t n;
- uint32_t i;
- int nb_free = 0;
- struct rte_mbuf *m, *free[RTE_I40E_TX_MAX_FREE_BUF_SZ];
-
- /* check DD bits on threshold descriptor */
- if ((txq->tx_ring[txq->tx_next_dd].cmd_type_offset_bsz &
- rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) !=
- rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE))
- return 0;
-
- n = txq->tx_rs_thresh;
-
- /* first buffer to free from S/W ring is at index
- * tx_next_dd - (tx_rs_thresh-1)
- */
- txep = &txq->sw_ring[txq->tx_next_dd - (n - 1)];
- m = __rte_pktmbuf_prefree_seg(txep[0].mbuf);
- if (likely(m != NULL)) {
- free[0] = m;
- nb_free = 1;
- for (i = 1; i < n; i++) {
- m = __rte_pktmbuf_prefree_seg(txep[i].mbuf);
- if (likely(m != NULL)) {
- if (likely(m->pool == free[0]->pool)) {
- free[nb_free++] = m;
- } else {
- rte_mempool_put_bulk(free[0]->pool,
- (void *)free,
- nb_free);
- free[0] = m;
- nb_free = 1;
- }
- }
- }
- rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
- } else {
- for (i = 1; i < n; i++) {
- m = __rte_pktmbuf_prefree_seg(txep[i].mbuf);
- if (m != NULL)
- rte_mempool_put(m->pool, m);
- }
- }
-
- /* buffers were freed, update counters */
- txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + txq->tx_rs_thresh);
- txq->tx_next_dd = (uint16_t)(txq->tx_next_dd + txq->tx_rs_thresh);
- if (txq->tx_next_dd >= txq->nb_tx_desc)
- txq->tx_next_dd = (uint16_t)(txq->tx_rs_thresh - 1);
-
- return txq->tx_rs_thresh;
-}
-
-static inline void __attribute__((always_inline))
-tx_backlog_entry(struct i40e_tx_entry *txep,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
- int i;
-
- for (i = 0; i < (int)nb_pkts; ++i)
- txep[i].mbuf = tx_pkts[i];
-}
-
uint16_t
i40e_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
@@ -709,49 +581,13 @@ i40e_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
void __attribute__((cold))
i40e_rx_queue_release_mbufs_vec(struct i40e_rx_queue *rxq)
{
- const unsigned mask = rxq->nb_rx_desc - 1;
- unsigned i;
-
- if (rxq->sw_ring == NULL || rxq->rxrearm_nb >= rxq->nb_rx_desc)
- return;
-
- /* free all mbufs that are valid in the ring */
- if (rxq->rxrearm_nb == 0) {
- for (i = 0; i < rxq->nb_rx_desc; i++) {
- if (rxq->sw_ring[i].mbuf != NULL)
- rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
- }
- } else {
- for (i = rxq->rx_tail;
- i != rxq->rxrearm_start;
- i = (i + 1) & mask) {
- if (rxq->sw_ring[i].mbuf != NULL)
- rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
- }
- }
-
- rxq->rxrearm_nb = rxq->nb_rx_desc;
-
- /* set all entries to NULL */
- memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc);
+ _i40e_rx_queue_release_mbufs_vec(rxq);
}
int __attribute__((cold))
i40e_rxq_vec_setup(struct i40e_rx_queue *rxq)
{
- uintptr_t p;
- struct rte_mbuf mb_def = { .buf_addr = 0 }; /* zeroed mbuf */
-
- mb_def.nb_segs = 1;
- mb_def.data_off = RTE_PKTMBUF_HEADROOM;
- mb_def.port = rxq->port_id;
- rte_mbuf_refcnt_set(&mb_def, 1);
-
- /* prevent compiler reordering: rearm_data covers previous fields */
- rte_compiler_barrier();
- p = (uintptr_t)&mb_def.rearm_data;
- rxq->mbuf_initializer = *(uint64_t *)p;
- return 0;
+ return i40e_rxq_vec_setup_default(rxq);
}
int __attribute__((cold))
@@ -764,34 +600,10 @@ int __attribute__((cold))
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
#ifndef RTE_LIBRTE_IEEE1588
- struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
- struct rte_fdir_conf *fconf = &dev->data->dev_conf.fdir_conf;
-
/* need SSE4.1 support */
if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE4_1))
return -1;
-
-#ifndef RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE
- /* whithout rx ol_flags, no VP flag report */
- if (rxmode->hw_vlan_strip != 0 ||
- rxmode->hw_vlan_extend != 0 ||
- rxmode->hw_ip_checksum != 0)
- return -1;
#endif
- /* no fdir support */
- if (fconf->mode != RTE_FDIR_MODE_NONE)
- return -1;
-
- /* - no csum error report support
- * - no header split support
- */
- if (rxmode->header_split == 1)
- return -1;
-
- return 0;
-#else
- RTE_SET_USED(dev);
- return -1;
-#endif
+ return i40e_rx_vec_dev_conf_condition_check_default(dev);
}
diff --git a/drivers/net/i40e/i40e_rxtx_vec_common.h b/drivers/net/i40e/i40e_rxtx_vec_common.h
new file mode 100644
index 0000000..6cb5dce
--- /dev/null
+++ b/drivers/net/i40e/i40e_rxtx_vec_common.h
@@ -0,0 +1,251 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _I40E_RXTX_VEC_COMMON_H_
+#define _I40E_RXTX_VEC_COMMON_H_
+#include <stdint.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+
+#include "i40e_ethdev.h"
+#include "i40e_rxtx.h"
+
+static inline uint16_t
+reassemble_packets(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_bufs,
+ uint16_t nb_bufs, uint8_t *split_flags)
+{
+ struct rte_mbuf *pkts[RTE_I40E_VPMD_RX_BURST]; /*finished pkts*/
+ struct rte_mbuf *start = rxq->pkt_first_seg;
+ struct rte_mbuf *end = rxq->pkt_last_seg;
+ unsigned pkt_idx, buf_idx;
+
+ for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) {
+ if (end != NULL) {
+ /* processing a split packet */
+ end->next = rx_bufs[buf_idx];
+ rx_bufs[buf_idx]->data_len += rxq->crc_len;
+
+ start->nb_segs++;
+ start->pkt_len += rx_bufs[buf_idx]->data_len;
+ end = end->next;
+
+ if (!split_flags[buf_idx]) {
+ /* it's the last packet of the set */
+ start->hash = end->hash;
+ start->ol_flags = end->ol_flags;
+ /* we need to strip crc for the whole packet */
+ start->pkt_len -= rxq->crc_len;
+ if (end->data_len > rxq->crc_len) {
+ end->data_len -= rxq->crc_len;
+ } else {
+ /* free up last mbuf */
+ struct rte_mbuf *secondlast = start;
+
+ while (secondlast->next != end)
+ secondlast = secondlast->next;
+ secondlast->data_len -= (rxq->crc_len -
+ end->data_len);
+ secondlast->next = NULL;
+ rte_pktmbuf_free_seg(end);
+ end = secondlast;
+ }
+ pkts[pkt_idx++] = start;
+ start = end = NULL;
+ }
+ } else {
+ /* not processing a split packet */
+ if (!split_flags[buf_idx]) {
+ /* not a split packet, save and skip */
+ pkts[pkt_idx++] = rx_bufs[buf_idx];
+ continue;
+ }
+ end = start = rx_bufs[buf_idx];
+ rx_bufs[buf_idx]->data_len += rxq->crc_len;
+ rx_bufs[buf_idx]->pkt_len += rxq->crc_len;
+ }
+ }
+
+ /* save the partial packet for next time */
+ rxq->pkt_first_seg = start;
+ rxq->pkt_last_seg = end;
+ memcpy(rx_bufs, pkts, pkt_idx * (sizeof(*pkts)));
+ return pkt_idx;
+}
+
+static inline int __attribute__((always_inline))
+i40e_tx_free_bufs(struct i40e_tx_queue *txq)
+{
+ struct i40e_tx_entry *txep;
+ uint32_t n;
+ uint32_t i;
+ int nb_free = 0;
+ struct rte_mbuf *m, *free[RTE_I40E_TX_MAX_FREE_BUF_SZ];
+
+ /* check DD bits on threshold descriptor */
+ if ((txq->tx_ring[txq->tx_next_dd].cmd_type_offset_bsz &
+ rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) !=
+ rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE))
+ return 0;
+
+ n = txq->tx_rs_thresh;
+
+ /* first buffer to free from S/W ring is at index
+ * tx_next_dd - (tx_rs_thresh-1)
+ */
+ txep = &txq->sw_ring[txq->tx_next_dd - (n - 1)];
+ m = __rte_pktmbuf_prefree_seg(txep[0].mbuf);
+ if (likely(m != NULL)) {
+ free[0] = m;
+ nb_free = 1;
+ for (i = 1; i < n; i++) {
+ m = __rte_pktmbuf_prefree_seg(txep[i].mbuf);
+ if (likely(m != NULL)) {
+ if (likely(m->pool == free[0]->pool)) {
+ free[nb_free++] = m;
+ } else {
+ rte_mempool_put_bulk(free[0]->pool,
+ (void *)free,
+ nb_free);
+ free[0] = m;
+ nb_free = 1;
+ }
+ }
+ }
+ rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
+ } else {
+ for (i = 1; i < n; i++) {
+ m = __rte_pktmbuf_prefree_seg(txep[i].mbuf);
+ if (m != NULL)
+ rte_mempool_put(m->pool, m);
+ }
+ }
+
+ /* buffers were freed, update counters */
+ txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + txq->tx_rs_thresh);
+ txq->tx_next_dd = (uint16_t)(txq->tx_next_dd + txq->tx_rs_thresh);
+ if (txq->tx_next_dd >= txq->nb_tx_desc)
+ txq->tx_next_dd = (uint16_t)(txq->tx_rs_thresh - 1);
+
+ return txq->tx_rs_thresh;
+}
+
+static inline void __attribute__((always_inline))
+tx_backlog_entry(struct i40e_tx_entry *txep,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+ int i;
+
+ for (i = 0; i < (int)nb_pkts; ++i)
+ txep[i].mbuf = tx_pkts[i];
+}
+
+static inline void
+_i40e_rx_queue_release_mbufs_vec(struct i40e_rx_queue *rxq)
+{
+ const unsigned mask = rxq->nb_rx_desc - 1;
+ unsigned i;
+
+ if (rxq->sw_ring == NULL || rxq->rxrearm_nb >= rxq->nb_rx_desc)
+ return;
+
+ /* free all mbufs that are valid in the ring */
+ if (rxq->rxrearm_nb == 0) {
+ for (i = 0; i < rxq->nb_rx_desc; i++) {
+ if (rxq->sw_ring[i].mbuf != NULL)
+ rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
+ }
+ } else {
+ for (i = rxq->rx_tail;
+ i != rxq->rxrearm_start;
+ i = (i + 1) & mask) {
+ if (rxq->sw_ring[i].mbuf != NULL)
+ rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
+ }
+ }
+
+ rxq->rxrearm_nb = rxq->nb_rx_desc;
+
+ /* set all entries to NULL */
+ memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc);
+}
+
+static inline int
+i40e_rxq_vec_setup_default(struct i40e_rx_queue *rxq)
+{
+ uintptr_t p;
+ struct rte_mbuf mb_def = { .buf_addr = 0 }; /* zeroed mbuf */
+
+ mb_def.nb_segs = 1;
+ mb_def.data_off = RTE_PKTMBUF_HEADROOM;
+ mb_def.port = rxq->port_id;
+ rte_mbuf_refcnt_set(&mb_def, 1);
+
+ /* prevent compiler reordering: rearm_data covers previous fields */
+ rte_compiler_barrier();
+ p = (uintptr_t)&mb_def.rearm_data;
+ rxq->mbuf_initializer = *(uint64_t *)p;
+ return 0;
+}
+
+static inline int
+i40e_rx_vec_dev_conf_condition_check_default(struct rte_eth_dev *dev)
+{
+#ifndef RTE_LIBRTE_IEEE1588
+ struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+ struct rte_fdir_conf *fconf = &dev->data->dev_conf.fdir_conf;
+
+#ifndef RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE
+ /* whithout rx ol_flags, no VP flag report */
+ if (rxmode->hw_vlan_strip != 0 ||
+ rxmode->hw_vlan_extend != 0 ||
+ rxmode->hw_ip_checksum != 0)
+ return -1;
+#endif
+
+ /* no fdir support */
+ if (fconf->mode != RTE_FDIR_MODE_NONE)
+ return -1;
+
+ /* - no csum error report support
+ * - no header split support
+ */
+ if (rxmode->header_split == 1)
+ return -1;
+
+ return 0;
+#else
+ RTE_SET_USED(dev);
+ return -1;
+#endif
+}
+#endif
--
2.4.11
^ permalink raw reply related
* [PATCH v2 0/5] i40e: vector poll-mode driver on ARM64
From: Jianbo Liu @ 2016-10-14 3:59 UTC (permalink / raw)
To: helin.zhang, jingjing.wu, jerin.jacob, dev, qi.z.zhang; +Cc: Jianbo Liu
In-Reply-To: <1472032425-16136-1-git-send-email-jianbo.liu@linaro.org>
This patch set is to implement i40e vector PMD on ARM64.
For x86, vPMD is only reorganized, there should be no performance loss.
v1 -> v2
- rebase to dpdk-next-net/rel_16_11
Jianbo Liu (5):
i40e: extract non-x86 specific code from vector driver
i40e: implement vector PMD for ARM architecture
i40e: enable i40e vector PMD on ARMv8a platform
i40e: make vector driver filenames consistent
maintainers: claim i40e vector PMD on ARM
MAINTAINERS | 1 +
config/defconfig_arm64-armv8a-linuxapp-gcc | 1 -
doc/guides/nics/features/i40e_vec.ini | 1 +
doc/guides/nics/features/i40e_vf_vec.ini | 1 +
drivers/net/i40e/Makefile | 8 +-
drivers/net/i40e/i40e_rxtx_vec_common.h | 251 +++++++++
drivers/net/i40e/i40e_rxtx_vec_neon.c | 614 +++++++++++++++++++++
.../i40e/{i40e_rxtx_vec.c => i40e_rxtx_vec_sse.c} | 196 +------
8 files changed, 878 insertions(+), 195 deletions(-)
create mode 100644 drivers/net/i40e/i40e_rxtx_vec_common.h
create mode 100644 drivers/net/i40e/i40e_rxtx_vec_neon.c
rename drivers/net/i40e/{i40e_rxtx_vec.c => i40e_rxtx_vec_sse.c} (78%)
--
2.4.11
^ permalink raw reply
* [dpdk-announce] release candidate 16.11-rc1
From: Thomas Monjalon @ 2016-10-14 1:08 UTC (permalink / raw)
To: announce
A new DPDK release candidate is ready for testing:
http://dpdk.org/browse/dpdk/tag/?id=v16.11-rc1
It is the first release candidate for DPDK 16.11.
It happens a bit late, though there are still some features missing.
This version must be released before mid-November.
Therefore we have 3 weeks to make the validation, fixes and decide
which remaining features can enter without hurting the validation process.
The easy decision would be to stop accepting large patches and new features.
The release notes shall be completed:
http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/release_16_11.rst
Some highlights:
- EAL device object rework
- more offloads
- improved vhost
- virtio for NEON
- new crypto libraries
- usual updates of drivers
- ivshmem library removal
Please start now discussing the changes you plan to do for
the next release cycle (17.02).
Thank you everyone
^ permalink raw reply
* Re: [PATCH v8 0/2] modify callback for VF management
From: Thomas Monjalon @ 2016-10-14 0:07 UTC (permalink / raw)
To: Bernard Iremonger; +Cc: dev, rahul.r.shah, wenzhuo.lu, az5157
In-Reply-To: <1476110055-29331-1-git-send-email-bernard.iremonger@intel.com>
2016-10-10 15:34, Bernard Iremonger:
> This patchset modifies the callback function for VF management.
>
> A third parameter has been added to the _rte_eth_dev_callback_process
> function. All references to this function have been updated.
> Changes have been made to the ixgbe_rcv_msg_from_vf function to
> use the new callback parameter.
Applied, thanks
^ permalink raw reply
* Re: [PATCH v3] drivers: prefix driver REGISTER macro with RTE PMD
From: Thomas Monjalon @ 2016-10-13 23:45 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: david.marchand, dev, nhorman
In-Reply-To: <1476078195-29985-1-git-send-email-shreyansh.jain@nxp.com>
2016-10-10 11:13, Shreyansh Jain:
> All macros related to driver registeration renamed from DRIVER_*
> to RTE_PMD_*
>
> This includes:
>
> DRIVER_REGISTER_PCI -> RTE_PMD_REGISTER_PCI
> DRIVER_REGISTER_PCI_TABLE -> RTE_PMD_REGISTER_PCI_TABLE
> DRIVER_REGISTER_VDEV -> RTE_PMD_REGISTER_VDEV
> DRIVER_REGISTER_PARAM_STRING -> RTE_PMD_REGISTER_PARAM_STRING
> DRIVER_EXPORT_* -> RTE_PMD_EXPORT_*
>
> Fix PMDINFOGEN tool to look for matches of RTE_PMD_REGISTER_*.
>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Applied, thanks
^ permalink raw reply
* Re: [PATCH v2 0/5] implement new Rx checksum flag
From: Thomas Monjalon @ 2016-10-13 23:37 UTC (permalink / raw)
To: Wang, Xiao W; +Cc: dev, Chen, Jing D, olivier.matz
In-Reply-To: <4341B239C0EFF9468EE453F9E9F4604D3A2EA632@shsmsx102.ccr.corp.intel.com>
> > Xiao Wang (5):
> > net/fm10k: fix Rx checksum flags
> > net/fm10k: implement new Rx checksum flag
> > net/e1000: implement new Rx checksum flag
> > net/ixgbe: implement new Rx checksum flag
> > net/i40e: implement new Rx checksum flag
>
> Acked-by : Jing Chen <jing.d.chen@intel.com>
Applied directly in mainline on Ferruh's advice
^ permalink raw reply
* Re: [PATCH] Revert "bonding: use existing enslaved device queues"
From: Eric Kinzie @ 2016-10-13 23:37 UTC (permalink / raw)
To: Bruce Richardson
Cc: Ilya Maximets, dev, Declan Doherty, Heetae Ahn, Yuanhan Liu,
Bernard Iremonger, stable, Thomas Monjalon
In-Reply-To: <20161012152421.GC104428@bricha3-MOBL3>
On Wed Oct 12 16:24:21 +0100 2016, Bruce Richardson wrote:
> On Wed, Oct 12, 2016 at 04:24:54PM +0300, Ilya Maximets wrote:
> > On 07.10.2016 05:02, Eric Kinzie wrote:
> > > On Wed Sep 07 15:28:10 +0300 2016, Ilya Maximets wrote:
> > >> This reverts commit 5b7bb2bda5519b7800f814df64d4e015282140e5.
> > >>
> > >> It is necessary to reconfigure all queues every time because configuration
> > >> can be changed.
> > >>
> > >> For example, if we're reconfiguring bonding device with new memory pool,
> > >> already configured queues will still use the old one. And if the old
> > >> mempool be freed, application likely will panic in attempt to use
> > >> freed mempool.
> > >>
> > >> This happens when we use the bonding device with OVS 2.6 while MTU
> > >> reconfiguration:
> > >>
> > >> PANIC in rte_mempool_get_ops():
> > >> assert "(ops_index >= 0) && (ops_index < RTE_MEMPOOL_MAX_OPS_IDX)" failed
> > >>
> > >> Cc: <stable@dpdk.org>
> > >> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
> > >> ---
> > >> drivers/net/bonding/rte_eth_bond_pmd.c | 10 ++--------
> > >> 1 file changed, 2 insertions(+), 8 deletions(-)
> > >>
> > >> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
> > >> index b20a272..eb5b6d1 100644
> > >> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> > >> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> > >> @@ -1305,8 +1305,6 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
> > >> struct bond_rx_queue *bd_rx_q;
> > >> struct bond_tx_queue *bd_tx_q;
> > >>
> > >> - uint16_t old_nb_tx_queues = slave_eth_dev->data->nb_tx_queues;
> > >> - uint16_t old_nb_rx_queues = slave_eth_dev->data->nb_rx_queues;
> > >> int errval;
> > >> uint16_t q_id;
> > >>
> > >> @@ -1347,9 +1345,7 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
> > >> }
> > >>
> > >> /* Setup Rx Queues */
> > >> - /* Use existing queues, if any */
> > >> - for (q_id = old_nb_rx_queues;
> > >> - q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
> > >> + for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
> > >> bd_rx_q = (struct bond_rx_queue *)bonded_eth_dev->data->rx_queues[q_id];
> > >>
> > >> errval = rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id,
> > >> @@ -1365,9 +1361,7 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
> > >> }
> > >>
> > >> /* Setup Tx Queues */
> > >> - /* Use existing queues, if any */
> > >> - for (q_id = old_nb_tx_queues;
> > >> - q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
> > >> + for (q_id = 0; q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
> > >> bd_tx_q = (struct bond_tx_queue *)bonded_eth_dev->data->tx_queues[q_id];
> > >>
> > >> errval = rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id,
> > >> --
> > >> 2.7.4
> > >>
> > >
> > > NAK
> > >
> > > There are still some users of this code. Let's give them a chance to
> > > comment before removing it.
> >
> > Hi Eric,
> >
> > Are these users in CC-list? If not, could you, please, add them?
> > This patch awaits in mail-list already more than a month. I think, it's enough
> > time period for all who wants to say something. Patch fixes a real bug that
> > prevent using of DPDK bonding in all applications that reconfigures devices
> > in runtime including OVS.
> >
> Agreed.
>
> Eric, does reverting this patch cause you problems directly, or is your concern
> just with regards to potential impact to others?
>
> Thanks,
> /Bruce
This won't impact me directly. The users are CCed (different thread)
and I haven't seen any comment, so I no longer have any objection to
reverting this change.
Eric
^ permalink raw reply
* Re: [PATCH v2 12/12] virtio: add Tso support
From: Stephen Hemminger @ 2016-10-13 23:33 UTC (permalink / raw)
To: Yuanhan Liu
Cc: Olivier Matz, dev, konstantin.ananyev, sugesh.chandran,
bruce.richardson, jianfeng.tan, helin.zhang, adrien.mazarguil,
dprovan, xiao.w.wang
In-Reply-To: <20161013081839.GT16751@yliu-dev.sh.intel.com>
On Thu, 13 Oct 2016 16:18:39 +0800
Yuanhan Liu <yuanhan.liu@linux.intel.com> wrote:
> On Mon, Oct 03, 2016 at 11:00:23AM +0200, Olivier Matz wrote:
> > +/* When doing TSO, the IP length is not included in the pseudo header
> > + * checksum of the packet given to the PMD, but for virtio it is
> > + * expected.
> > + */
> > +static void
> > +virtio_tso_fix_cksum(struct rte_mbuf *m)
> > +{
> > + /* common case: header is not fragmented */
> > + if (likely(rte_pktmbuf_data_len(m) >= m->l2_len + m->l3_len +
> > + m->l4_len)) {
> ...
> > + /* replace it in the packet */
> > + th->cksum = new_cksum;
> > + } else {
> ...
> > + /* replace it in the packet */
> > + *rte_pktmbuf_mtod_offset(m, uint8_t *,
> > + m->l2_len + m->l3_len + 16) = new_cksum.u8[0];
> > + *rte_pktmbuf_mtod_offset(m, uint8_t *,
> > + m->l2_len + m->l3_len + 17) = new_cksum.u8[1];
> > + }
>
> The tcp header will always be in the mbuf, right? Otherwise, you can't
> update the cksum field here. What's the point of introducing the "else
> clause" then?
>
> --yliu
You need to check the reference count before updating any data in mbuf.
^ permalink raw reply
* Re: ixgbe: support checksum flags in sse vector Rx function
From: Thomas Monjalon @ 2016-10-13 23:27 UTC (permalink / raw)
To: Olivier Matz
Cc: dev, Remy Horton, konstantin.ananyev, helin.zhang,
bruce.richardson, Maxime Leroy
In-Reply-To: <29444fbf-8515-b9ad-cb94-b3f2898b0ada@intel.com>
2016-10-06 15:00, Remy Horton:
> On 07/07/2016 13:19, Olivier Matz wrote:
> [..]
> > Signed-off-by: Maxime Leroy <maxime.leroy@6wind.com>
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > ---
> > drivers/net/ixgbe/ixgbe_rxtx_vec_common.h | 8 ++---
> > drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c | 6 ++++
> > drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c | 50 +++++++++++++++++++++----------
> > 3 files changed, 42 insertions(+), 22 deletions(-)
>
> Acked-by: Remy Horton <remy.horton@intel.com>
Applied directly in mainline on Ferruh's advice
^ permalink raw reply
* [PATCH v9] drivers/net:new PMD using tun/tap host interface
From: Keith Wiles @ 2016-10-13 22:03 UTC (permalink / raw)
To: dev; +Cc: pmatilai, yuanhan.liu, ferruh.yigit
In-Reply-To: <1474423220-10207-1-git-send-email-keith.wiles@intel.com>
The rte_eth_tap.c PMD creates a device using TUN/TAP interfaces
on the local host. The PMD allows for DPDK and the host to
communicate using a raw device interface on the host and in
the DPDK application. The device created is a Tap device with
a L2 packet header.
v9 - Fix up the docs to use correct syntax
v8 - Fix issue with tap_tx_queue_setup() not return zero on success.
v7 - Reword the comment in common_base and fix the data->name issue
v6 - fixed the checkpatch issues
v5 - merge in changes from list review see related emails
fixed many minor edits
v4 - merge with latest driver changes
v3 - fix includes by removing ifdef for other type besides Linux
Fix the copyright notice in the Makefile
v2 - merge all of the patches into one patch
Fix a typo on naming the tap device
Update the maintainers list
Signed-off-by: Keith Wiles <keith.wiles@intel.com>
---
MAINTAINERS | 5 +
config/common_base | 9 +
config/common_linuxapp | 1 +
doc/guides/nics/index.rst | 1 +
doc/guides/nics/tap.rst | 136 ++++++
drivers/net/Makefile | 1 +
drivers/net/tap/Makefile | 57 +++
drivers/net/tap/rte_eth_tap.c | 756 ++++++++++++++++++++++++++++++++
drivers/net/tap/rte_pmd_tap_version.map | 4 +
mk/rte.app.mk | 1 +
10 files changed, 971 insertions(+)
create mode 100644 doc/guides/nics/tap.rst
create mode 100644 drivers/net/tap/Makefile
create mode 100644 drivers/net/tap/rte_eth_tap.c
create mode 100644 drivers/net/tap/rte_pmd_tap_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f5fa82..433d402 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -394,6 +394,11 @@ F: doc/guides/nics/pcap_ring.rst
F: app/test/test_pmd_ring.c
F: app/test/test_pmd_ring_perf.c
+Tap PMD
+M: Keith Wiles <keith.wiles@intel.com>
+F: drivers/net/tap
+F: doc/guides/nics/tap.rst
+
Null Networking PMD
M: Tetsuya Mukawa <mtetsuyah@gmail.com>
F: drivers/net/null/
diff --git a/config/common_base b/config/common_base
index f5d2eff..47ef843 100644
--- a/config/common_base
+++ b/config/common_base
@@ -592,3 +592,12 @@ CONFIG_RTE_APP_TEST_RESOURCE_TAR=n
CONFIG_RTE_TEST_PMD=y
CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+
+#
+# Compile the TAP PMD
+#
+# The TAP PMD is currently only built for Linux and the
+# option is enabled by default in common_linuxapp file,
+# set to 'n' in the common_base file.
+#
+CONFIG_RTE_LIBRTE_PMD_TAP=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 2483dfa..782b503 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -44,3 +44,4 @@ CONFIG_RTE_LIBRTE_PMD_VHOST=y
CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
CONFIG_RTE_LIBRTE_POWER=y
CONFIG_RTE_VIRTIO_USER=y
+CONFIG_RTE_LIBRTE_PMD_TAP=y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 92d56a5..f676a52 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -56,6 +56,7 @@ Network Interface Controller Drivers
vhost
vmxnet3
pcap_ring
+ tap
**Figures**
diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst
new file mode 100644
index 0000000..622b9e7
--- /dev/null
+++ b/doc/guides/nics/tap.rst
@@ -0,0 +1,136 @@
+.. BSD LICENSE
+ Copyright(c) 2016 Intel Corporation. All rights reserved.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Tun/Tap Poll Mode Driver
+========================
+
+The ``rte_eth_tap.c`` PMD creates a device using TUN/TAP interfaces on the
+local host. The PMD allows for DPDK and the host to communicate using a raw
+device interface on the host and in the DPDK application.
+
+The device created is a TAP device, which sends/receives packet in a raw
+format with a L2 header. The usage for a TAP PMD is for connectivity to the
+local host using a TAP interface. When the TAP PMD is initialized it will
+create a number of tap devices in the host accessed via ``ifconfig -a`` or
+``ip`` command. The commands can be used to assign and query the virtual like
+device.
+
+These TAP interfaces can be used with Wireshark or tcpdump or Pktgen-DPDK
+along with being able to be used as a network connection to the DPDK
+application. The method enable one or more interfaces is to use the
+``--vdev=net_tap`` option on the DPDK application command line. Each
+``--vdev=net_tap`` option give will create an interface named dtap0, dtap1,
+and so on.
+
+The interfaced name can be changed by adding the ``iface=foo0``, for example::
+
+ --vdev=net_tap,iface=foo0 --vdev=net_tap,iface=foo1, ...
+
+Also the speed of the interface can be changed from 10G to whatever number
+needed, but the interface does not enforce that speed, for example::
+
+ --vdev=net_tap,iface=foo0,speed=25000
+
+After the DPDK application is started you can send and receive packets on the
+interface using the standard rx_burst/tx_burst APIs in DPDK. From the host
+point of view you can use any host tool like tcpdump, Wireshark, ping, Pktgen
+and others to communicate with the DPDK application. The DPDK application may
+not understand network protocols like IPv4/6, UDP or TCP unless the
+application has been written to understand these protocols.
+
+If you need the interface as a real network interface meaning running and has
+a valid IP address then you can do this with the following commands::
+
+ sudo ip link set dtap0 up; sudo ip addr add 192.168.0.250/24 dev dtap0
+ sudo ip link set dtap1 up; sudo ip addr add 192.168.1.250/24 dev dtap1
+
+Please change the IP addresses as you see fit.
+
+If routing is enabled on the host you can also communicate with the DPDK App
+over the internet via a standard socket layer application as long as you
+account for the protocol handing in the application.
+
+If you have a Network Stack in your DPDK application or something like it you
+can utilize that stack to handle the network protocols. Plus you would be able
+to address the interface using an IP address assigned to the internal
+interface.
+
+Example
+-------
+
+The following is a simple example of using the TUN/TAP PMD with the Pktgen
+packet generator. It requires that the ``socat`` utility is installed on the
+test system.
+
+Build DPDK, then pull down Pktgen and build pktgen using the DPDK SDK/Target
+used to build the dpdk you pulled down.
+
+Run pktgen from the pktgen directory in a terminal with a commandline like the
+following::
+
+ sudo ./app/app/x86_64-native-linuxapp-gcc/app/pktgen -l 1-5 -n 4 \
+ --proc-type auto --log-level 8 --socket-mem 512,512 --file-prefix pg \
+ --vdev=net_tap --vdev=net_tap -b 05:00.0 -b 05:00.1 \
+ -b 04:00.0 -b 04:00.1 -b 04:00.2 -b 04:00.3 \
+ -b 81:00.0 -b 81:00.1 -b 81:00.2 -b 81:00.3 \
+ -b 82:00.0 -b 83:00.0 -- -T -P -m [2:3].0 -m [4:5].1 \
+ -f themes/black-yellow.theme
+
+.. Note:
+
+ Change the ``-b`` options to blacklist all of your physical ports. The
+ following command line is all one line.
+
+ Also, ``-f themes/black-yellow.theme`` is optional if the default colors
+ work on your system configuration. See the Pktgen docs for more
+ information.
+
+Verify with ``ifconfig -a`` command in a different xterm window, should have a
+``dtap0`` and ``dtap1`` interfaces created.
+
+Next set the links for the two interfaces to up via the commands below::
+
+ sudo ip link set dtap0 up; sudo ip addr add 192.168.0.250/24 dev dtap0
+ sudo ip link set dtap1 up; sudo ip addr add 192.168.1.250/24 dev dtap1
+
+Then use socat to create a loopback for the two interfaces::
+
+ sudo socat interface:dtap0 interface:dtap1
+
+Then on the Pktgen command line interface you can start sending packets using
+the commands ``start 0`` and ``start 1`` or you can start both at the same
+time with ``start all``. The command ``str`` is an alias for ``start all`` and
+``stp`` is an alias for ``stop all``.
+
+While running you should see the 64 byte counters increasing to verify the
+traffic is being looped back. You can use ``set all size XXX`` to change the
+size of the packets after you stop the traffic. Use the pktgen ``help``
+command to see a list of all commands. You can also use the ``-f`` option to
+load commands at startup.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index bc93230..e366a85 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -51,6 +51,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap
DIRS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede
DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += ring
DIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += szedata2
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap
DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
new file mode 100644
index 0000000..e18f30c
--- /dev/null
+++ b/drivers/net/tap/Makefile
@@ -0,0 +1,57 @@
+# BSD LICENSE
+#
+# Copyright(c) 2016 Intel Corporation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_tap.a
+
+EXPORT_MAP := rte_pmd_tap_version.map
+
+LIBABIVER := 1
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_kvargs
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
new file mode 100644
index 0000000..7f303db
--- /dev/null
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -0,0 +1,756 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_vdev.h>
+#include <rte_kvargs.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <poll.h>
+#include <arpa/inet.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <linux/if_ether.h>
+#include <fcntl.h>
+
+/* Linux based path to the TUN device */
+#define TUN_TAP_DEV_PATH "/dev/net/tun"
+#define DEFAULT_TAP_NAME "dtap"
+
+#define ETH_TAP_IFACE_ARG "iface"
+#define ETH_TAP_SPEED_ARG "speed"
+
+#define RTE_PMD_TAP_MAX_QUEUES 32
+
+static const char *valid_arguments[] = {
+ ETH_TAP_IFACE_ARG,
+ ETH_TAP_SPEED_ARG,
+ NULL
+};
+
+static const char *drivername = "Tap PMD";
+static int tap_unit;
+
+static struct rte_eth_link pmd_link = {
+ .link_speed = ETH_SPEED_NUM_10G,
+ .link_duplex = ETH_LINK_FULL_DUPLEX,
+ .link_status = ETH_LINK_DOWN,
+ .link_autoneg = ETH_LINK_SPEED_AUTONEG
+};
+
+struct pkt_stats {
+ uint64_t opackets; /* Number of output packets */
+ uint64_t ipackets; /* Number of input packets */
+ uint64_t obytes; /* Number of bytes on output */
+ uint64_t ibytes; /* Number of bytes on input */
+ uint64_t errs; /* Number of error packets */
+};
+
+struct rx_queue {
+ struct rte_mempool *mp; /* Mempool for RX packets */
+ uint16_t in_port; /* Port ID */
+ int fd;
+
+ struct pkt_stats stats; /* Stats for this RX queue */
+};
+
+struct tx_queue {
+ int fd;
+ struct pkt_stats stats; /* Stats for this TX queue */
+};
+
+struct pmd_internals {
+ char name[RTE_ETH_NAME_MAX_LEN]; /* Internal Tap device name */
+ uint16_t nb_queues; /* Number of queues supported */
+ struct ether_addr eth_addr; /* Mac address of the device port */
+
+ int if_index; /* IF_INDEX for the port */
+ int fds[RTE_PMD_TAP_MAX_QUEUES]; /* List of all file descriptors */
+
+ struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */
+ struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */
+};
+
+/* Tun/Tap allocation routine
+ *
+ * name is the number of the interface to use, unless NULL to take the host
+ * supplied name.
+ */
+static int
+tun_alloc(char *name)
+{
+ struct ifreq ifr;
+ unsigned int features;
+ int fd;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ if (name && name[0])
+ strncpy(ifr.ifr_name, name, IFNAMSIZ);
+
+ fd = open(TUN_TAP_DEV_PATH, O_RDWR);
+ if (fd < 0) {
+ RTE_LOG(ERR, PMD, "Unable to create TAP interface");
+ goto error;
+ }
+
+ /* Grab the TUN features to verify we can work */
+ if (ioctl(fd, TUNGETFEATURES, &features) < 0) {
+ RTE_LOG(ERR, PMD, "Unable to get TUN/TAP features\n");
+ goto error;
+ }
+ RTE_LOG(DEBUG, PMD, "TUN/TAP Features %08x\n", features);
+
+ if (!(features & IFF_MULTI_QUEUE) && (RTE_PMD_TAP_MAX_QUEUES > 1)) {
+ RTE_LOG(DEBUG, PMD, "TUN/TAP device only one queue\n");
+ goto error;
+ } else if ((features & IFF_ONE_QUEUE) &&
+ (RTE_PMD_TAP_MAX_QUEUES == 1)) {
+ ifr.ifr_flags |= IFF_ONE_QUEUE;
+ RTE_LOG(DEBUG, PMD, "Single queue only support\n");
+ } else {
+ ifr.ifr_flags |= IFF_MULTI_QUEUE;
+ RTE_LOG(DEBUG, PMD, "Multi-queue support for %d queues\n",
+ RTE_PMD_TAP_MAX_QUEUES);
+ }
+
+ /* Set the TUN/TAP configuration and get the name if needed */
+ if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) {
+ RTE_LOG(ERR, PMD, "Unable to set TUNSETIFF for %s\n",
+ ifr.ifr_name);
+ perror("TUNSETIFF");
+ goto error;
+ }
+
+ /* Always set the file descriptor to non-blocking */
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ RTE_LOG(ERR, PMD, "Unable to set to nonblocking\n");
+ perror("F_SETFL, NONBLOCK");
+ goto error;
+ }
+
+ /* If the name is different that new name as default */
+ if (name && strcmp(name, ifr.ifr_name))
+ snprintf(name, RTE_ETH_NAME_MAX_LEN - 1, "%s", ifr.ifr_name);
+
+ return fd;
+
+error:
+ if (fd > 0)
+ close(fd);
+ return -1;
+}
+
+/* Callback to handle the rx burst of packets to the correct interface and
+ * file descriptor(s) in a multi-queue setup.
+ */
+static uint16_t
+pmd_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+ int len;
+ struct rte_mbuf *mbuf;
+ struct rx_queue *rxq = queue;
+ uint16_t num_rx;
+ unsigned long num_rx_bytes = 0;
+
+ for (num_rx = 0; num_rx < nb_pkts; ) {
+ /* allocate the next mbuf */
+ mbuf = rte_pktmbuf_alloc(rxq->mp);
+ if (unlikely(!mbuf)) {
+ RTE_LOG(WARNING, PMD, "Unable to allocate mbuf\n");
+ break;
+ }
+
+ len = read(rxq->fd, rte_pktmbuf_mtod(mbuf, char *),
+ rte_pktmbuf_tailroom(mbuf));
+ if (len <= 0) {
+ rte_pktmbuf_free(mbuf);
+ break;
+ }
+
+ mbuf->data_len = len;
+ mbuf->pkt_len = len;
+ mbuf->port = rxq->in_port;
+
+ /* account for the receive frame */
+ bufs[num_rx++] = mbuf;
+ num_rx_bytes += mbuf->pkt_len;
+ }
+ rxq->stats.ipackets += num_rx;
+ rxq->stats.ibytes += num_rx_bytes;
+
+ return num_rx;
+}
+
+/* Callback to handle sending packets from the tap interface
+ */
+static uint16_t
+pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+ struct rte_mbuf *mbuf;
+ struct tx_queue *txq = queue;
+ struct pollfd pfd;
+ uint16_t num_tx = 0;
+ unsigned long num_tx_bytes = 0;
+ int i, n;
+
+ if (unlikely(nb_pkts == 0))
+ return 0;
+
+ pfd.events = POLLOUT;
+ pfd.fd = txq->fd;
+ for (i = 0; i < nb_pkts; i++) {
+ n = poll(&pfd, 1, 0);
+
+ if (n <= 0)
+ break;
+
+ if (pfd.revents & POLLOUT) {
+ /* copy the tx frame data */
+ mbuf = bufs[num_tx];
+ n = write(pfd.fd, rte_pktmbuf_mtod(mbuf, void*),
+ rte_pktmbuf_pkt_len(mbuf));
+ if (n <= 0)
+ break;
+
+ num_tx++;
+ num_tx_bytes += mbuf->pkt_len;
+ rte_pktmbuf_free(mbuf);
+ }
+ }
+
+ txq->stats.opackets += num_tx;
+ txq->stats.errs += nb_pkts - num_tx;
+ txq->stats.obytes += num_tx_bytes;
+
+ return num_tx;
+}
+
+static int
+tap_dev_start(struct rte_eth_dev *dev)
+{
+ /* Force the Link up */
+ dev->data->dev_link.link_status = ETH_LINK_UP;
+
+ return 0;
+}
+
+/* This function gets called when the current port gets stopped.
+ */
+static void
+tap_dev_stop(struct rte_eth_dev *dev)
+{
+ int i;
+ struct pmd_internals *internals = dev->data->dev_private;
+
+ for (i = 0; i < internals->nb_queues; i++)
+ if (internals->fds[i] != -1)
+ close(internals->fds[i]);
+
+ dev->data->dev_link.link_status = ETH_LINK_DOWN;
+}
+
+static int
+tap_dev_configure(struct rte_eth_dev *dev __rte_unused)
+{
+ return 0;
+}
+
+static void
+tap_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+{
+ struct pmd_internals *internals = dev->data->dev_private;
+
+ dev_info->driver_name = drivername;
+ dev_info->if_index = internals->if_index;
+ dev_info->max_mac_addrs = 1;
+ dev_info->max_rx_pktlen = (uint32_t)ETHER_MAX_VLAN_FRAME_LEN;
+ dev_info->max_rx_queues = internals->nb_queues;
+ dev_info->max_tx_queues = internals->nb_queues;
+ dev_info->min_rx_bufsize = 0;
+ dev_info->pci_dev = NULL;
+}
+
+static void
+tap_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *tap_stats)
+{
+ unsigned int i, imax;
+ unsigned long rx_total = 0, tx_total = 0, tx_err_total = 0;
+ unsigned long rx_bytes_total = 0, tx_bytes_total = 0;
+ const struct pmd_internals *pmd = dev->data->dev_private;
+
+ imax = (pmd->nb_queues < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
+ pmd->nb_queues : RTE_ETHDEV_QUEUE_STAT_CNTRS;
+
+ for (i = 0; i < imax; i++) {
+ tap_stats->q_ipackets[i] = pmd->rxq[i].stats.ipackets;
+ tap_stats->q_ibytes[i] = pmd->rxq[i].stats.ibytes;
+ rx_total += tap_stats->q_ipackets[i];
+ rx_bytes_total += tap_stats->q_ibytes[i];
+ }
+
+ for (i = 0; i < imax; i++) {
+ tap_stats->q_opackets[i] = pmd->txq[i].stats.opackets;
+ tap_stats->q_errors[i] = pmd->txq[i].stats.errs;
+ tap_stats->q_obytes[i] = pmd->txq[i].stats.obytes;
+ tx_total += tap_stats->q_opackets[i];
+ tx_err_total += tap_stats->q_errors[i];
+ tx_bytes_total += tap_stats->q_obytes[i];
+ }
+
+ tap_stats->ipackets = rx_total;
+ tap_stats->ibytes = rx_bytes_total;
+ tap_stats->opackets = tx_total;
+ tap_stats->oerrors = tx_err_total;
+ tap_stats->obytes = tx_bytes_total;
+}
+
+static void
+tap_stats_reset(struct rte_eth_dev *dev)
+{
+ int i;
+ struct pmd_internals *pmd = dev->data->dev_private;
+
+ for (i = 0; i < pmd->nb_queues; i++) {
+ pmd->rxq[i].stats.ipackets = 0;
+ pmd->rxq[i].stats.ibytes = 0;
+ }
+
+ for (i = 0; i < pmd->nb_queues; i++) {
+ pmd->txq[i].stats.opackets = 0;
+ pmd->txq[i].stats.errs = 0;
+ pmd->txq[i].stats.obytes = 0;
+ }
+}
+
+static void
+tap_dev_close(struct rte_eth_dev *dev __rte_unused)
+{
+}
+
+static void
+tap_rx_queue_release(void *queue)
+{
+ struct rx_queue *rxq = queue;
+
+ if (rxq && (rxq->fd > 0)) {
+ close(rxq->fd);
+ rxq->fd = -1;
+ }
+}
+
+static void
+tap_tx_queue_release(void *queue)
+{
+ struct tx_queue *txq = queue;
+
+ if (txq && (txq->fd > 0)) {
+ close(txq->fd);
+ txq->fd = -1;
+ }
+}
+
+static int
+tap_link_update(struct rte_eth_dev *dev __rte_unused,
+ int wait_to_complete __rte_unused)
+{
+ return 0;
+}
+
+static int
+tap_setup_queue(struct rte_eth_dev *dev,
+ struct pmd_internals *internals,
+ uint16_t qid)
+{
+ struct rx_queue *rx = &internals->rxq[qid];
+ struct tx_queue *tx = &internals->txq[qid];
+ int fd;
+
+ fd = rx->fd;
+ if (fd < 0) {
+ fd = tx->fd;
+ if (fd < 0) {
+ RTE_LOG(INFO, PMD, "Add queue to TAP %s for qid %d\n",
+ dev->data->name, qid);
+ fd = tun_alloc(dev->data->name);
+ if (fd < 0) {
+ RTE_LOG(ERR, PMD, "tun_alloc(%s) failed\n",
+ dev->data->name);
+ return -1;
+ }
+ }
+ }
+ dev->data->rx_queues[qid] = rx;
+ dev->data->tx_queues[qid] = tx;
+
+ rx->fd = fd;
+ tx->fd = fd;
+
+ return fd;
+}
+
+static int
+tap_rx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t rx_queue_id,
+ uint16_t nb_rx_desc __rte_unused,
+ unsigned int socket_id __rte_unused,
+ const struct rte_eth_rxconf *rx_conf __rte_unused,
+ struct rte_mempool *mp)
+{
+ struct pmd_internals *internals = dev->data->dev_private;
+ uint16_t buf_size;
+ int fd;
+
+ if ((rx_queue_id >= internals->nb_queues) || !mp) {
+ RTE_LOG(ERR, PMD, "nb_queues %d mp %p\n",
+ internals->nb_queues, mp);
+ return -1;
+ }
+
+ internals->rxq[rx_queue_id].mp = mp;
+ internals->rxq[rx_queue_id].in_port = dev->data->port_id;
+
+ /* Now get the space available for data in the mbuf */
+ buf_size = (uint16_t)(rte_pktmbuf_data_room_size(mp) -
+ RTE_PKTMBUF_HEADROOM);
+
+ if (buf_size < ETH_FRAME_LEN) {
+ RTE_LOG(ERR, PMD,
+ "%s: %d bytes will not fit in mbuf (%d bytes)\n",
+ dev->data->name, ETH_FRAME_LEN, buf_size);
+ return -ENOMEM;
+ }
+
+ fd = tap_setup_queue(dev, internals, rx_queue_id);
+ if (fd == -1)
+ return -1;
+
+ internals->fds[rx_queue_id] = fd;
+ RTE_LOG(INFO, PMD, "RX TAP device name %s, qid %d on fd %d\n",
+ dev->data->name, rx_queue_id, internals->rxq[rx_queue_id].fd);
+
+ return 0;
+}
+
+static int
+tap_tx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t tx_queue_id,
+ uint16_t nb_tx_desc __rte_unused,
+ unsigned int socket_id __rte_unused,
+ const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+ struct pmd_internals *internals = dev->data->dev_private;
+ int ret;
+
+ if (tx_queue_id >= internals->nb_queues)
+ return -1;
+
+ ret = tap_setup_queue(dev, internals, tx_queue_id);
+ if (ret == -1)
+ return -1;
+
+ RTE_LOG(INFO, PMD, "TX TAP device name %s, qid %d on fd %d\n",
+ dev->data->name, tx_queue_id, internals->txq[tx_queue_id].fd);
+
+ return 0;
+}
+
+static const struct eth_dev_ops ops = {
+ .dev_start = tap_dev_start,
+ .dev_stop = tap_dev_stop,
+ .dev_close = tap_dev_close,
+ .dev_configure = tap_dev_configure,
+ .dev_infos_get = tap_dev_info,
+ .rx_queue_setup = tap_rx_queue_setup,
+ .tx_queue_setup = tap_tx_queue_setup,
+ .rx_queue_release = tap_rx_queue_release,
+ .tx_queue_release = tap_tx_queue_release,
+ .link_update = tap_link_update,
+ .stats_get = tap_stats_get,
+ .stats_reset = tap_stats_reset,
+};
+
+static int
+pmd_mac_address(int fd, struct rte_eth_dev *dev, struct ether_addr *addr)
+{
+ struct ifreq ifr;
+
+ if ((fd <= 0) || !dev || !addr)
+ return -1;
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
+ RTE_LOG(ERR, PMD, "ioctl failed (SIOCGIFHWADDR) (%s)\n",
+ ifr.ifr_name);
+ return -1;
+ }
+
+ /* Set the host based MAC address to this special MAC format */
+ ifr.ifr_hwaddr.sa_data[0] = 'T';
+ ifr.ifr_hwaddr.sa_data[1] = 'a';
+ ifr.ifr_hwaddr.sa_data[2] = 'p';
+ ifr.ifr_hwaddr.sa_data[3] = '-';
+ ifr.ifr_hwaddr.sa_data[4] = dev->data->port_id;
+ ifr.ifr_hwaddr.sa_data[5] = dev->data->numa_node;
+ if (ioctl(fd, SIOCSIFHWADDR, &ifr) == -1) {
+ RTE_LOG(ERR, PMD, "%s: ioctl failed (SIOCSIFHWADDR) (%s)\n",
+ dev->data->name, ifr.ifr_name);
+ return -1;
+ }
+
+ /* Set the local application MAC address, needs to be different then
+ * the host based MAC address.
+ */
+ ifr.ifr_hwaddr.sa_data[0] = 'd';
+ ifr.ifr_hwaddr.sa_data[1] = 'n';
+ ifr.ifr_hwaddr.sa_data[2] = 'e';
+ ifr.ifr_hwaddr.sa_data[3] = 't';
+ ifr.ifr_hwaddr.sa_data[4] = dev->data->port_id;
+ ifr.ifr_hwaddr.sa_data[5] = dev->data->numa_node;
+ rte_memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+
+ return 0;
+}
+
+static int
+eth_dev_tap_create(const char *name, char *tap_name)
+{
+ int numa_node = rte_socket_id();
+ struct rte_eth_dev *dev = NULL;
+ struct pmd_internals *pmd = NULL;
+ struct rte_eth_dev_data *data = NULL;
+ int i, fd = -1;
+
+ RTE_LOG(INFO, PMD,
+ "%s: Create TAP Ethernet device with %d queues on numa %u\n",
+ name, RTE_PMD_TAP_MAX_QUEUES, rte_socket_id());
+
+ data = rte_zmalloc_socket(tap_name, sizeof(*data), 0, numa_node);
+ if (!data)
+ goto error_exit;
+
+ pmd = rte_zmalloc_socket(tap_name, sizeof(*pmd), 0, numa_node);
+ if (!pmd)
+ goto error_exit;
+
+ /* Use the name and not the tap_name */
+ dev = rte_eth_dev_allocate(name);
+ if (!dev)
+ goto error_exit;
+
+ snprintf(pmd->name, sizeof(pmd->name), "%s", tap_name);
+
+ pmd->nb_queues = RTE_PMD_TAP_MAX_QUEUES;
+
+ /* Setup some default values */
+ data->dev_private = pmd;
+ data->port_id = dev->data->port_id;
+ data->dev_flags = RTE_ETH_DEV_DETACHABLE;
+ data->kdrv = RTE_KDRV_NONE;
+ data->drv_name = drivername;
+ data->numa_node = numa_node;
+
+ data->dev_link = pmd_link;
+ data->mac_addrs = &pmd->eth_addr;
+ data->nb_rx_queues = pmd->nb_queues;
+ data->nb_tx_queues = pmd->nb_queues;
+ data->drv_name = drivername;
+
+ dev->data = data;
+ dev->dev_ops = &ops;
+ dev->driver = NULL;
+ dev->rx_pkt_burst = pmd_rx_burst;
+ dev->tx_pkt_burst = pmd_tx_burst;
+ snprintf(dev->data->name, sizeof(dev->data->name), "%s", name);
+
+ /* Create the first Tap device */
+ fd = tun_alloc(tap_name);
+ if (fd < 0)
+ goto error_exit;
+
+ /* Presetup the fds to -1 as being not working */
+ for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
+ pmd->fds[i] = -1;
+ pmd->rxq[i].fd = -1;
+ pmd->txq[i].fd = -1;
+ }
+
+ /* Take the TUN/TAP fd and place in the first location */
+ pmd->rxq[0].fd = fd;
+ pmd->txq[0].fd = fd;
+ pmd->fds[0] = fd;
+
+ if (pmd_mac_address(fd, dev, &pmd->eth_addr) < 0)
+ goto error_exit;
+
+ return 0;
+
+error_exit:
+ RTE_PMD_DEBUG_TRACE("Unable to initialize %s\n", name);
+
+ rte_free(data);
+ rte_free(pmd);
+
+ rte_eth_dev_release_port(dev);
+
+ return -EINVAL;
+}
+
+static int
+set_interface_name(const char *key __rte_unused,
+ const char *value,
+ void *extra_args)
+{
+ char *name = (char *)extra_args;
+
+ if (value)
+ snprintf(name, RTE_ETH_NAME_MAX_LEN - 1, "%s", value);
+ else
+ snprintf(name, RTE_ETH_NAME_MAX_LEN - 1, "%s%d",
+ DEFAULT_TAP_NAME, (tap_unit - 1));
+
+ return 0;
+}
+
+static int
+set_interface_speed(const char *key __rte_unused,
+ const char *value,
+ void *extra_args)
+{
+ *(int *)extra_args = (value) ? atoi(value) : ETH_SPEED_NUM_10G;
+
+ return 0;
+}
+
+/* Open a TAP interface device.
+ */
+static int
+rte_pmd_tap_probe(const char *name, const char *params)
+{
+ int ret;
+ struct rte_kvargs *kvlist = NULL;
+ int speed;
+ char tap_name[RTE_ETH_NAME_MAX_LEN];
+
+ speed = ETH_SPEED_NUM_10G;
+ snprintf(tap_name, sizeof(tap_name), "%s%d",
+ DEFAULT_TAP_NAME, tap_unit++);
+
+ RTE_LOG(INFO, PMD, "Initializing pmd_tap for %s as %s\n",
+ name, tap_name);
+
+ if (params && (params[0] != '\0')) {
+ RTE_LOG(INFO, PMD, "paramaters (%s)\n", params);
+
+ kvlist = rte_kvargs_parse(params, valid_arguments);
+ if (kvlist) {
+ if (rte_kvargs_count(kvlist, ETH_TAP_SPEED_ARG) == 1) {
+ ret = rte_kvargs_process(kvlist,
+ ETH_TAP_SPEED_ARG,
+ &set_interface_speed,
+ &speed);
+ if (ret == -1)
+ goto leave;
+ }
+
+ if (rte_kvargs_count(kvlist, ETH_TAP_IFACE_ARG) == 1) {
+ ret = rte_kvargs_process(kvlist,
+ ETH_TAP_IFACE_ARG,
+ &set_interface_name,
+ tap_name);
+ if (ret == -1)
+ goto leave;
+ }
+ }
+ }
+ pmd_link.link_speed = speed;
+
+ ret = eth_dev_tap_create(name, tap_name);
+
+leave:
+ if (ret == -1) {
+ RTE_LOG(INFO, PMD, "Failed to create pmd_tap for %s as %s\n",
+ name, tap_name);
+ tap_unit--; /* Restore the unit number */
+ }
+ rte_kvargs_free(kvlist);
+
+ return ret;
+}
+
+/* detach a TAP device.
+ */
+static int
+rte_pmd_tap_remove(const char *name)
+{
+ struct rte_eth_dev *eth_dev = NULL;
+ struct pmd_internals *internals;
+ int i;
+
+ RTE_LOG(INFO, PMD, "Closing TUN/TAP Ethernet device on numa %u\n",
+ rte_socket_id());
+
+ /* find the ethdev entry */
+ eth_dev = rte_eth_dev_allocated(name);
+ if (!eth_dev)
+ return 0;
+
+ internals = eth_dev->data->dev_private;
+ for (i = 0; i < internals->nb_queues; i++)
+ if (internals->fds[i] != -1)
+ close(internals->fds[i]);
+
+ rte_free(eth_dev->data->dev_private);
+ rte_free(eth_dev->data);
+
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_vdev_driver pmd_tap_drv = {
+ .probe = rte_pmd_tap_probe,
+ .remove = rte_pmd_tap_remove,
+};
+
+DRIVER_REGISTER_VDEV(net_tap, pmd_tap_drv);
+DRIVER_REGISTER_PARAM_STRING(net_tap, "iface=<string>,speed=N");
diff --git a/drivers/net/tap/rte_pmd_tap_version.map b/drivers/net/tap/rte_pmd_tap_version.map
new file mode 100644
index 0000000..61463bf
--- /dev/null
+++ b/drivers/net/tap/rte_pmd_tap_version.map
@@ -0,0 +1,4 @@
+DPDK_16.11 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 72c2fe7..f20fc1a 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -124,6 +124,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap -lpcap
_LDLIBS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += -lrte_pmd_qede -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING) += -lrte_pmd_ring
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += -lrte_pmd_szedata2 -lsze2
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += -lrte_pmd_tap
_LDLIBS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += -lrte_pmd_thunderx_nicvf -lm
_LDLIBS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += -lrte_pmd_virtio
ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
--
2.8.0.GIT
^ permalink raw reply related
* Re: [PATCH] eal: avoid unnecessary conflicts over rte_config file
From: Tahhan, Maryam @ 2016-10-13 21:39 UTC (permalink / raw)
To: Ananyev, Konstantin, John Ousterhout, thomas.monjalon@6wind.com
Cc: dev@dpdk.org
In-Reply-To: <2601191342CEEE43887BDE71AB9772583F0C1256@irsmsx105.ger.corp.intel.com>
> Hi John,
>
> > Before this patch, DPDK used the file ~/.rte_config as a lock to
> > detect potential interference between multiple DPDK applications
> > running on the same machine. However, if a single user ran DPDK
> > applications concurrently on several different machines, and if the
> > user's home directory was shared between the machines via NFS, DPDK
> > would incorrectly detect conflicts for all but the first application
> > and abort them. This patch fixes the problem by incorporating the
> > machine name into the config file name (e.g., ~/.rte_hostname_config).
> >
> > Signed-off-by: John Ousterhout <ouster@cs.stanford.edu>
> > ---
> > doc/guides/prog_guide/multi_proc_support.rst | 11 +++++++----
> > lib/librte_eal/common/eal_common_proc.c | 8 ++------
> > lib/librte_eal/common/eal_filesystem.h | 15 +++++++++++++--
> > 3 files changed, 22 insertions(+), 12 deletions(-)
> >
> > diff --git a/doc/guides/prog_guide/multi_proc_support.rst
> > b/doc/guides/prog_guide/multi_proc_support.rst
> > index badd102..a54fa1c 100644
> > --- a/doc/guides/prog_guide/multi_proc_support.rst
> > +++ b/doc/guides/prog_guide/multi_proc_support.rst
> > @@ -129,10 +129,13 @@ Support for this usage scenario is provided
> > using the ``--file-prefix`` paramete
> >
> > By default, the EAL creates hugepage files on each hugetlbfs
> > filesystem using the rtemap_X filename, where X is in the range 0 to the
> maximum number of hugepages -1.
> > -Similarly, it creates shared configuration files, memory mapped in
> > each process, using the /var/run/.rte_config filename, -when run as
> > root (or $HOME/.rte_config when run as a non-root user; -if filesystem and
> device permissions are set up to allow this).
> > -The rte part of the filenames of each of the above is configurable using the
> file-prefix parameter.
> > +Similarly, it creates shared configuration files, memory mapped in each
> process.
> > +When run as root, the name of the configuration file will be
> > +/var/run/.rte_*host*_config, where *host* is the name of the machine.
> > +When run as a non-root user, the the name of the configuration file
> > +will be $HOME/.rte_*host*_config (if filesystem and device permissions
> are set up to allow this).
> > +If the ``--file-prefix`` parameter has been specified, its value will
> > +be used in place of "rte" in the file names.
>
> I am not sure that we need to handle all such cases inside EAL.
> User can easily overcome that problem by just adding something like:
> --file-prefix=`uname -n`
> to his command-line.
> Konstantin
>
I agree with Konstantin, there's no need to include the hostname in the rte config file + I'm not sure this will be backward compatible with existing DPDK applications that use a secondary processes that use the config file (as in, multiprocess DPDK applications in use would all need to be updated). What Konstantin suggests fixes the issue you were encountering without breaking backward compatibility.
Is addition, the hostname is not unique... you could in theory have 2 hosts with the same hostname and encounter the issue you were seeing again.
> >
> > In addition to specifying the file-prefix parameter, any DPDK
> > applications that are to be run side-by-side must explicitly limit their
> memory use.
> > diff --git a/lib/librte_eal/common/eal_common_proc.c
> > b/lib/librte_eal/common/eal_common_proc.c
> > index 12e0fca..517aa0c 100644
> > --- a/lib/librte_eal/common/eal_common_proc.c
> > +++ b/lib/librte_eal/common/eal_common_proc.c
> > @@ -45,12 +45,8 @@ rte_eal_primary_proc_alive(const char
> > *config_file_path)
> >
> > if (config_file_path)
> > config_fd = open(config_file_path, O_RDONLY);
> > - else {
> > - char default_path[PATH_MAX+1];
> > - snprintf(default_path, PATH_MAX, RUNTIME_CONFIG_FMT,
> > - default_config_dir, "rte");
> > - config_fd = open(default_path, O_RDONLY);
> > - }
> > + else
> > + config_fd = open(eal_runtime_config_path(), O_RDONLY);
> > if (config_fd < 0)
> > return 0;
> >
> > diff --git a/lib/librte_eal/common/eal_filesystem.h
> > b/lib/librte_eal/common/eal_filesystem.h
> > index fdb4a70..4929aa3 100644
> > --- a/lib/librte_eal/common/eal_filesystem.h
> > +++ b/lib/librte_eal/common/eal_filesystem.h
> > @@ -41,7 +41,7 @@
> > #define EAL_FILESYSTEM_H
> >
> > /** Path of rte config file. */
> > -#define RUNTIME_CONFIG_FMT "%s/.%s_config"
> > +#define RUNTIME_CONFIG_FMT "%s/.%s_%s_config"
> >
> > #include <stdint.h>
> > #include <limits.h>
> > @@ -59,11 +59,22 @@ eal_runtime_config_path(void)
> > static char buffer[PATH_MAX]; /* static so auto-zeroed */
> > const char *directory = default_config_dir;
> > const char *home_dir = getenv("HOME");
> > + static char nameBuffer[1000];
> > + int result;
> >
> > if (getuid() != 0 && home_dir != NULL)
> > directory = home_dir;
> > +
> > + /*
> > + * Include the name of the host in the config file path. Otherwise,
> > + * if DPDK applications run on different hosts but share a home
> > + * directory (e.g. via NFS), they will choose the same config
> > + * file and conflict unnecessarily.
> > + */
> > + result = gethostname(nameBuffer, sizeof(nameBuffer)-1);
> > snprintf(buffer, sizeof(buffer) - 1, RUNTIME_CONFIG_FMT,
> directory,
> > - internal_config.hugefile_prefix);
> > + internal_config.hugefile_prefix,
> > + (result == 0) ? nameBuffer : "unknown-host");
> > return buffer;
> > }
> >
> > --
> > 2.8.3
^ permalink raw reply
* Re: [PATCH v3 00/19] KNI checkpatch cleanup
From: Thomas Monjalon @ 2016-10-13 21:15 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev
In-Reply-To: <20160926153938.7575-1-ferruh.yigit@intel.com>
2016-09-26 16:39, Ferruh Yigit:
> KNI checkpatch cleanup, mostly non-functional but cosmetic modifications.
> Only functional change is related logging, switched to kernel dynamic
> logging and compile time KNI debug options removed, some log message
> levels updated.
Applied, thanks
Note that it is generally preferred to fix coding style when working
on code changes and avoid mass cleanup.
^ permalink raw reply
* Re: [PATCH] kni: add support for core_id param in single threaded mode
From: Thomas Monjalon @ 2016-10-13 20:24 UTC (permalink / raw)
To: Vladyslav Buslov; +Cc: dev, Ferruh Yigit
In-Reply-To: <7153a79a-e727-f848-28ca-1a4defdadb0c@intel.com>
> > Allow binding KNI thread to specific core in single threaded mode
> > by setting core_id and force_bind config parameters.
> >
> > Signed-off-by: Vladyslav Buslov <vladyslav.buslov@harmonicinc.com>
> > Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
>
> Tested-by: Ferruh Yigit <ferruh.yigit@intel.com>
Applied, thanks
^ permalink raw reply
* Re: [PATCH v4 2/3] app/test: add a case to verify lpm tlb8 recycle
From: Thomas Monjalon @ 2016-10-13 20:18 UTC (permalink / raw)
To: Wei Dai; +Cc: dev
In-Reply-To: <1470638445-126473-1-git-send-email-wei.dai@intel.com>
2016-08-08 14:40, Wei Dai:
> As a bug-fix for lpm tlb8 recycle is introduced,
> add a test case to verify tlb8 group is correctly
> freed when it only includes a rule with depth=24.
>
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
Series applied with typo tlb/tbl fixed
^ permalink raw reply
* Re: [PATCH v4] log: respect rte_openlog_stream calls before rte_eal_init
From: Thomas Monjalon @ 2016-10-13 20:03 UTC (permalink / raw)
To: John Ousterhout; +Cc: dev
In-Reply-To: <20161012193832.5016-1-ouster@cs.stanford.edu>
2016-10-12 12:38, John Ousterhout:
> Before this patch, application-specific loggers could not be
> installed before rte_eal_init completed (the initialization process
> called rte_openlog_stream, overwriting any previously installed
> logger). This made it impossible for an application to capture the
> initial log messages generated during rte_eal_init. This patch changes
> initialization so that information from a previous call to
> rte_openlog_stream is not lost. Specifically:
> * The default log stream is now maintained separately from an
> application-specific log stream installed with rte_openlog_stream.
> * rte_eal_common_log_init has been renamed to eal_log_set_default,
> since this is all it does. It no longer invokes rte_openlog_stream; it
> just updates the default stream. Also, this method now returns void,
> rather than int, since there are no errors.
>
> This patch also removes the "early log" mechanism and cleans up the
> log initialization mechanism:
> * The default log stream defaults to stderr on all platforms if
> eal_log_set_default hasn't been invoked (Linux used to use stdout
> during the first part of initialization).
> * Removed rte_eal_log_early_init; all of the desired functionality can
> be achieved by calling eal_log_set_default.
> * Removed lib/librte_eal/bsdapp/eal/eal_log.c: it contained only one
> function, rte_eal_log_init, which is not needed or invoked for BSD.
> * Removed declaration for eal_default_log_stream in rte_log.h (it's now
> private to eal_common_log.c).
> * Moved call to rte_eal_log_init earlier in rte_eal_init for Linux, so
> that it starts using the preferrred log ASAP.
>
> Signed-off-by: John Ousterhout <ouster@cs.stanford.edu>
Applied, thanks
^ permalink raw reply
* Re: [PATCH v3 12/12] net/virtio: add Tso support
From: Olivier Matz @ 2016-10-13 19:58 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Yuanhan Liu, dev, konstantin.ananyev, sugesh.chandran,
bruce.richardson, jianfeng.tan, helin.zhang, adrien.mazarguil,
stephen, dprovan, xiao.w.wang, maxime.coquelin
In-Reply-To: <1603777.zeWNS1Z9oX@xps13>
On 10/13/2016 08:50 PM, Thomas Monjalon wrote:
> 2016-10-14 00:05, Yuanhan Liu:
>> On Thu, Oct 13, 2016 at 04:16:11PM +0200, Olivier Matz wrote:
>>> +/* When doing TSO, the IP length is not included in the pseudo header
>>> + * checksum of the packet given to the PMD, but for virtio it is
>>> + * expected.
>>> + */
>>> +static void
>>> +virtio_tso_fix_cksum(struct rte_mbuf *m)
>>> +{
>>> + /* common case: header is not fragmented */
>>> + if (likely(rte_pktmbuf_data_len(m) >= m->l2_len + m->l3_len +
>>> + m->l4_len)) {
>>> + struct ipv4_hdr *iph;
>>> + struct ipv6_hdr *ip6h;
>>> + struct tcp_hdr *th;
>>> + uint16_t prev_cksum, new_cksum, ip_len, ip_paylen;
>>> + uint32_t tmp;
>> ...
>>> + } else {
>>
>> As discussed just now, if you drop the else part, you could add my
>> ACK for the whole virtio changes, and Review-ed by for all mbuf and
>> other changes.
>>
>> Thoams, please pick them by youself directly: since it depends on
>> other patches and they will be picked (or already be picked?) by you.
>
> Applied
> - without TSO checksum on fragmented header
> - with some release notes changes
> - with Yuanhan acked/reviewed
> Thanks
>
Thanks Thomas, and also to Xiao, Maxime and Yuanhan for the review!
^ permalink raw reply
* Re: [PATCH] doc: ZUC PMD cannot be built as a shared library
From: De Lara Guarch, Pablo @ 2016-10-13 19:45 UTC (permalink / raw)
To: dev@dpdk.org
In-Reply-To: <1476387303-238224-1-git-send-email-pablo.de.lara.guarch@intel.com>
> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Thursday, October 13, 2016 12:35 PM
> To: dev@dpdk.org
> Cc: De Lara Guarch, Pablo
> Subject: [PATCH] doc: ZUC PMD cannot be built as a shared library
>
> ZUC PMD cannot be built as a shared library, due to
> the fact that some assembly code in the underlying libsso
> library is not relocatable.
> This will be fixed in the future, but for the moment,
> it is added as a limitation of the PMD.
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Applied to dpdk-next-crypto.
Pablo
^ permalink raw reply
* Re: [PATCH] doc: how to build KASUMI as shared library
From: De Lara Guarch, Pablo @ 2016-10-13 19:44 UTC (permalink / raw)
To: dev@dpdk.org
In-Reply-To: <1476387252-238163-1-git-send-email-pablo.de.lara.guarch@intel.com>
> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Thursday, October 13, 2016 12:34 PM
> To: dev@dpdk.org
> Cc: De Lara Guarch, Pablo
> Subject: [PATCH] doc: how to build KASUMI as shared library
>
> Libsso KASUMI library has to be built with specific
> parameters to make the KASUMI PMD be built as
> a shared library, so a note has been added in
> its documentation.
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Applied to dpdk-next-crypto.
Pablo
^ permalink raw reply
* Re: [PATCH] doc: fix libcrypto title
From: De Lara Guarch, Pablo @ 2016-10-13 19:44 UTC (permalink / raw)
To: De Lara Guarch, Pablo, dev@dpdk.org
In-Reply-To: <1476387229-238098-1-git-send-email-pablo.de.lara.guarch@intel.com>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Pablo de Lara
> Sent: Thursday, October 13, 2016 12:34 PM
> To: dev@dpdk.org
> Cc: De Lara Guarch, Pablo
> Subject: [dpdk-dev] [PATCH] doc: fix libcrypto title
>
> Libcrypto documentation was missing the equal signs ("="),
> in its title, so it was not present in the documentation
> generated.
>
> Fixes: d61f70b4c918 ("crypto/libcrypto: add driver for OpenSSL library")
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Applied to dpdk-next-crypto.
Pablo
^ permalink raw reply
* Re: [PATCH] crypto/zuc: fix init function names
From: De Lara Guarch, Pablo @ 2016-10-13 19:36 UTC (permalink / raw)
To: Trahe, Fiona, dev@dpdk.org
In-Reply-To: <348A99DA5F5B7549AA880327E580B435890F23F0@IRSMSX101.ger.corp.intel.com>
> -----Original Message-----
> From: Trahe, Fiona
> Sent: Thursday, October 13, 2016 10:57 AM
> To: De Lara Guarch, Pablo; dev@dpdk.org
> Cc: De Lara Guarch, Pablo
> Subject: RE: [dpdk-dev] [PATCH] crypto/zuc: fix init function names
>
>
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Pablo de Lara
> > Sent: Tuesday, October 11, 2016 2:15 AM
> > To: dev@dpdk.org
> > Cc: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> > Subject: [dpdk-dev] [PATCH] crypto/zuc: fix init function names
> >
> > All init/uninit function names in the virtual devices have been renamed, so
> > they finish with probe or remove, so to keep consistency, same thing should
> be
> > done in this PMD.
> >
> > Fixes: cf7685d68f00 ("crypto/zuc: add driver for ZUC library")
> >
> > Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> Acked-by: Fiona Trahe <fiona.trahe@intel.com>
Applied to dpdk-next-crypto.
Thanks,
Pablo
^ permalink raw reply
* Re: [PATCH] crypto/libcrypto: fix init function names
From: De Lara Guarch, Pablo @ 2016-10-13 19:35 UTC (permalink / raw)
To: Trahe, Fiona, dev@dpdk.org
In-Reply-To: <348A99DA5F5B7549AA880327E580B435890F23D5@IRSMSX101.ger.corp.intel.com>
> -----Original Message-----
> From: Trahe, Fiona
> Sent: Thursday, October 13, 2016 10:56 AM
> To: De Lara Guarch, Pablo; dev@dpdk.org
> Cc: De Lara Guarch, Pablo
> Subject: RE: [dpdk-dev] [PATCH] crypto/libcrypto: fix init function names
>
>
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Pablo de Lara
> > Sent: Tuesday, October 11, 2016 2:15 AM
> > To: dev@dpdk.org
> > Cc: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> > Subject: [dpdk-dev] [PATCH] crypto/libcrypto: fix init function names
> >
> > All init/uninit function names in the virtual devices have been renamed, so
> > they finish with probe or remove, so to keep consistency, same thing should
> be
> > done in this PMD.
> >
> > Fixes: d61f70b4c918 ("crypto/libcrypto: add driver for OpenSSL library")
> >
> > Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> Acked-by: Fiona Trahe <fiona.trahe@intel.com>
Applied to dpdk-next-crypto.
Pablo
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox