DPDK patches and discussions
 help / color / mirror / Atom feed
From: John Daley <johndale@cisco.com>
To: ferruh.yigit@intel.com
Cc: dev@dpdk.org, Hyong Youb Kim <hyonkim@cisco.com>
Subject: [dpdk-dev] [PATCH v2 11/15] net/enic: add the simple version of Tx handler
Date: Fri, 29 Jun 2018 02:29:40 -0700	[thread overview]
Message-ID: <20180629092944.15576-12-johndale@cisco.com> (raw)
In-Reply-To: <20180629092944.15576-1-johndale@cisco.com>

From: Hyong Youb Kim <hyonkim@cisco.com>

Add a much-simplified handler that works when all offloads are
disabled, except mbuf fast free. When compared against the default
handler, under ideal conditions, cycles per packet drop by 60+%.
The driver tries to use the simple handler first.

The idea of using specialized/simplified handlers is from the Intel
and Mellanox drivers.

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
---

v2: removed devarg to disable handler

 drivers/net/enic/enic.h        |  2 ++
 drivers/net/enic/enic_compat.h |  5 +++
 drivers/net/enic/enic_ethdev.c |  4 ---
 drivers/net/enic/enic_main.c   | 36 ++++++++++++++++++++
 drivers/net/enic/enic_rxtx.c   | 77 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 120 insertions(+), 4 deletions(-)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index af790fc2e..a40ea790e 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -318,6 +318,8 @@ uint16_t enic_dummy_recv_pkts(void *rx_queue,
 			      uint16_t nb_pkts);
 uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			uint16_t nb_pkts);
+uint16_t enic_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+			       uint16_t nb_pkts);
 uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			uint16_t nb_pkts);
 int enic_set_mtu(struct enic *enic, uint16_t new_mtu);
diff --git a/drivers/net/enic/enic_compat.h b/drivers/net/enic/enic_compat.h
index c0af1ed29..ceb1b0962 100644
--- a/drivers/net/enic/enic_compat.h
+++ b/drivers/net/enic/enic_compat.h
@@ -56,6 +56,11 @@
 #define dev_debug(x, args...) dev_printk(DEBUG, args)
 
 extern int enicpmd_logtype_flow;
+extern int enicpmd_logtype_init;
+
+#define PMD_INIT_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, enicpmd_logtype_init, \
+		"%s" fmt "\n", __func__, ##args)
 
 #define __le16 u16
 #define __le32 u32
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index ef18f8802..15d93711d 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -24,10 +24,6 @@
 int enicpmd_logtype_init;
 int enicpmd_logtype_flow;
 
-#define PMD_INIT_LOG(level, fmt, args...) \
-	rte_log(RTE_LOG_ ## level, enicpmd_logtype_init, \
-		"%s" fmt "\n", __func__, ##args)
-
 #define ENICPMD_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
 
 /*
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index c03ec247a..e89105d96 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -493,6 +493,27 @@ static void enic_rxq_intr_deinit(struct enic *enic)
 	}
 }
 
+static void enic_prep_wq_for_simple_tx(struct enic *enic, uint16_t queue_idx)
+{
+	struct wq_enet_desc *desc;
+	struct vnic_wq *wq;
+	unsigned int i;
+
+	/*
+	 * Fill WQ descriptor fields that never change. Every descriptor is
+	 * one packet, so set EOP. Also set CQ_ENTRY every ENIC_WQ_CQ_THRESH
+	 * descriptors (i.e. request one completion update every 32 packets).
+	 */
+	wq = &enic->wq[queue_idx];
+	desc = (struct wq_enet_desc *)wq->ring.descs;
+	for (i = 0; i < wq->ring.desc_count; i++, desc++) {
+		desc->header_length_flags = 1 << WQ_ENET_FLAGS_EOP_SHIFT;
+		if (i % ENIC_WQ_CQ_THRESH == ENIC_WQ_CQ_THRESH - 1)
+			desc->header_length_flags |=
+				(1 << WQ_ENET_FLAGS_CQ_ENTRY_SHIFT);
+	}
+}
+
 int enic_enable(struct enic *enic)
 {
 	unsigned int index;
@@ -535,6 +556,21 @@ int enic_enable(struct enic *enic)
 		}
 	}
 
+	/*
+	 * Use the simple TX handler if possible. All offloads must be disabled
+	 * except mbuf fast free.
+	 */
+	if ((eth_dev->data->dev_conf.txmode.offloads &
+	     ~DEV_TX_OFFLOAD_MBUF_FAST_FREE) == 0) {
+		PMD_INIT_LOG(DEBUG, " use the simple tx handler");
+		eth_dev->tx_pkt_burst = &enic_simple_xmit_pkts;
+		for (index = 0; index < enic->wq_count; index++)
+			enic_prep_wq_for_simple_tx(enic, index);
+	} else {
+		PMD_INIT_LOG(DEBUG, " use the default tx handler");
+		eth_dev->tx_pkt_burst = &enic_xmit_pkts;
+	}
+
 	for (index = 0; index < enic->wq_count; index++)
 		enic_start_wq(enic, index);
 	for (index = 0; index < enic->rq_count; index++)
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 7cddb53d9..7dec486fe 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -741,4 +741,81 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	return index;
 }
 
+static void enqueue_simple_pkts(struct rte_mbuf **pkts,
+				struct wq_enet_desc *desc,
+				uint16_t n,
+				struct enic *enic)
+{
+	struct rte_mbuf *p;
+
+	while (n) {
+		n--;
+		p = *pkts++;
+		desc->address = p->buf_iova + p->data_off;
+		desc->length = p->pkt_len;
+		/*
+		 * The app should not send oversized
+		 * packets. tx_pkt_prepare includes a check as
+		 * well. But some apps ignore the device max size and
+		 * tx_pkt_prepare. Oversized packets cause WQ errrors
+		 * and the NIC ends up disabling the whole WQ. So
+		 * truncate packets..
+		 */
+		if (unlikely(p->pkt_len > ENIC_TX_MAX_PKT_SIZE)) {
+			desc->length = ENIC_TX_MAX_PKT_SIZE;
+			rte_atomic64_inc(&enic->soft_stats.tx_oversized);
+		}
+		desc++;
+	}
+}
+
+uint16_t enic_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+			       uint16_t nb_pkts)
+{
+	unsigned int head_idx, desc_count;
+	struct wq_enet_desc *desc;
+	struct vnic_wq *wq;
+	struct enic *enic;
+	uint16_t rem, n;
+
+	wq = (struct vnic_wq *)tx_queue;
+	enic = vnic_dev_priv(wq->vdev);
+	enic_cleanup_wq(enic, wq);
+	/* Will enqueue this many packets in this call */
+	nb_pkts = RTE_MIN(nb_pkts, wq->ring.desc_avail);
+	if (nb_pkts == 0)
+		return 0;
+
+	head_idx = wq->head_idx;
+	desc_count = wq->ring.desc_count;
+
+	/* Descriptors until the end of the ring */
+	n = desc_count - head_idx;
+	n = RTE_MIN(nb_pkts, n);
 
+	/* Save mbuf pointers to free later */
+	memcpy(wq->bufs + head_idx, tx_pkts, sizeof(struct rte_mbuf *) * n);
+
+	/* Enqueue until the ring end */
+	rem = nb_pkts - n;
+	desc = ((struct wq_enet_desc *)wq->ring.descs) + head_idx;
+	enqueue_simple_pkts(tx_pkts, desc, n, enic);
+
+	/* Wrap to the start of the ring */
+	if (rem) {
+		tx_pkts += n;
+		memcpy(wq->bufs, tx_pkts, sizeof(struct rte_mbuf *) * rem);
+		desc = (struct wq_enet_desc *)wq->ring.descs;
+		enqueue_simple_pkts(tx_pkts, desc, rem, enic);
+	}
+	rte_wmb();
+
+	/* Update head_idx and desc_avail */
+	wq->ring.desc_avail -= nb_pkts;
+	head_idx += nb_pkts;
+	if (head_idx >= desc_count)
+		head_idx -= desc_count;
+	wq->head_idx = head_idx;
+	iowrite32_relaxed(head_idx, &wq->ctrl->posted_index);
+	return nb_pkts;
+}
-- 
2.16.2

  parent reply	other threads:[~2018-06-29  9:34 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-28  3:19 [dpdk-dev] [PATCH 01/14] net/enic: fix receive packet types John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 02/14] net/enic: update the UDP RSS detection mechanism John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 03/14] net/enic: do not overwrite admin Tx queue limit John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 04/14] net/enic: initialize RQ fetch index before enabling RQ John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 05/14] net/enic: report ring limits and preferred default values John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 06/14] net/enic: add devarg to specify ingress VLAN rewrite mode John Daley
2018-06-28 16:04   ` Ferruh Yigit
2018-06-28  3:19 ` [dpdk-dev] [PATCH 07/14] net/enic: add handlers to add/delete vxlan port number John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 08/14] net/enic: use mbuf pointer array for inflight Tx packets John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 09/14] net/enic: support mbuf fast free offload John Daley
2018-06-28 16:05   ` Ferruh Yigit
2018-06-28  3:19 ` [dpdk-dev] [PATCH 10/14] net/enic: reduce Tx completion updates John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 11/14] net/enic: add the simple version of Tx handler John Daley
2018-06-28 16:05   ` Ferruh Yigit
2018-06-28  3:19 ` [dpdk-dev] [PATCH 12/14] net/enic: check maximum packet size in Tx prepare handler John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 13/14] net/enic: add simple Rx handler John Daley
2018-06-28  3:19 ` [dpdk-dev] [PATCH 14/14] net/enic: cap Rx packet processing to end of desc ring John Daley
2018-06-28 16:08 ` [dpdk-dev] [PATCH 01/14] net/enic: fix receive packet types Ferruh Yigit
2018-06-29  9:29 ` [dpdk-dev] [PATCH v2 00/15] enic PMD fixes and performance improvements John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 01/15] net/enic: fix receive packet types John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 02/15] net/enic: update the UDP RSS detection mechanism John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 03/15] net/enic: do not overwrite admin Tx queue limit John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 04/15] net/enic: initialize RQ fetch index before enabling RQ John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 05/15] net/enic: report ring limits and preferred default values John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 06/15] net/enic: add devarg to specify ingress VLAN rewrite mode John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 07/15] net/enic: add handlers to add/delete vxlan port number John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 08/15] net/enic: use mbuf pointer array for inflight Tx packets John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 09/15] net/enic: support mbuf fast free offload John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 10/15] net/enic: reduce Tx completion updates John Daley
2018-06-29  9:29   ` John Daley [this message]
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 12/15] net/enic: check maximum packet size in Tx prepare handler John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 13/15] net/enic: add simple Rx handler John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 14/15] net/enic: cap Rx packet processing to end of desc ring John Daley
2018-06-29  9:29   ` [dpdk-dev] [PATCH v2 15/15] doc: update release notes with new enic features John Daley
2018-07-02 23:10   ` [dpdk-dev] [PATCH v2 00/15] enic PMD fixes and performance improvements Ferruh Yigit
2018-07-25 18:37   ` Kevin Traynor
2018-07-25 19:46     ` John Daley (johndale)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180629092944.15576-12-johndale@cisco.com \
    --to=johndale@cisco.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=hyonkim@cisco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).