Update ENIC driver patches for DPDK 2.2.0

This includes all patches in ENIC driver which are up-streamed to DPDK
to improve RX performance, fix buffer/error handling and interoperation
with link bonding PMD library.

Change-Id: Id4c71a350d5234834951f9261c69db5476ba396b
Signed-off-by: John Lo <loj@cisco.com>
This commit is contained in:
John Lo
2016-03-29 16:14:35 -04:00
parent 13f3c450cc
commit 23650e6cad
12 changed files with 573 additions and 74 deletions

View File

@ -1,34 +0,0 @@
From 39272e0a1c227b1ab9360e6fbcbc497eaaed4cb0 Mon Sep 17 00:00:00 2001
From: John Lo <loj@cisco.com>
Date: Fri, 26 Feb 2016 12:45:55 -0500
Subject: [PATCH 1/2] Fix link bonding PMD slave status polling path used by
ENIC driver,
---
drivers/net/bonding/rte_eth_bond_pmd.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index b1373c6..9efd73c 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1734,7 +1734,7 @@ bond_ethdev_slave_link_status_change_monitor(void *cb_arg)
if (!bonded_ethdev->data->dev_started ||
!internals->link_status_polling_enabled)
- return;
+ goto rearm_and_exit;
/* If device is currently being configured then don't check slaves link
* status, wait until next period */
@@ -1768,6 +1768,7 @@ bond_ethdev_slave_link_status_change_monitor(void *cb_arg)
rte_spinlock_unlock(&internals->lock);
}
+ rearm_and_exit:
if (polling_slave_found)
/* Set alarm to continue monitoring link status of slave ethdev's */
rte_eal_alarm_set(internals->link_status_polling_interval_ms * 1000,
--
1.9.1

View File

@ -1,20 +1,20 @@
From 0963caf48db910ca6f93c5cbff8d5d24b2be64dd Mon Sep 17 00:00:00 2001
From: John Lo <loj@cisco.com>
Date: Mon, 7 Mar 2016 14:12:29 -0500
Subject: [PATCH 2/2] Replacement of ENIC PMD receive path to improve
performance and code clarifty.
commit 947d860c821f4248dcf2fc01e98671524973eeea
Author: John Daley <johndale@cisco.com>
Date: Fri Mar 4 13:09:00 2016 -0800
---
drivers/net/enic/Makefile | 1 +
drivers/net/enic/base/vnic_rq.c | 99 ++---------
drivers/net/enic/base/vnic_rq.h | 147 +---------------
drivers/net/enic/enic.h | 16 +-
drivers/net/enic/enic_ethdev.c | 27 ++-
drivers/net/enic/enic_main.c | 321 ++++++++++------------------------
drivers/net/enic/enic_res.h | 16 +-
drivers/net/enic/enic_rx.c | 378 ++++++++++++++++++++++++++++++++++++++++
8 files changed, 519 insertions(+), 486 deletions(-)
create mode 100644 drivers/net/enic/enic_rx.c
enic: improve Rx performance
This is a wholesale replacement of the Enic PMD receive path in order
to improve performance and code clarity. The changes are:
- Simplify and reduce code path length of receive function.
- Put most of the fast-path receive functions in one file.
- Reduce the number of posted_index updates (pay attention to
rx_free_thresh)
- Remove the unneeded container structure around the RQ mbuf ring
- Prefetch next Mbuf and descriptors while processing the current one
- Use a lookup table for converting CQ flags to mbuf flags.
Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index f0ee093..f316274 100644
@ -494,7 +494,7 @@ index 2a88043..6f2ada5 100644
ENICPMD_FUNC_TRACE();
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 07a9810..d0c9bff 100644
index f818c32..9fff020 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -60,6 +60,17 @@
@ -960,10 +960,10 @@ index 49f7e22..33f2e84 100644
diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
new file mode 100644
index 0000000..12b1f62
index 0000000..945a60f
--- /dev/null
+++ b/drivers/net/enic/enic_rx.c
@@ -0,0 +1,378 @@
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2008-2014 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2007 Nuova Systems, Inc. All rights reserved.
@ -1127,20 +1127,12 @@ index 0000000..12b1f62
+
+ /* Check for packet error. Can't be more specific than MAC error */
+ if (enic_cq_rx_desc_packet_error(bwflags)) {
+#ifdef RTE_NEXT_ABI
+ pkt_err_flags |= PKT_RX_MAC_ERR;
+#else
+ pkt_err_flags |= PKT_EXT_RX_PKT_ERROR;
+#endif
+ }
+
+ /* Check for bad FCS. MAC error isn't quite, but no other choice */
+ if (!enic_cq_rx_desc_fcs_ok(cqrd)) {
+#ifdef RTE_NEXT_ABI
+ pkt_err_flags |= PKT_RX_MAC_ERR;
+#else
+ pkt_err_flags |= PKT_EXT_RX_BAD_FCS;
+#endif
+ }
+ return pkt_err_flags;
+}
@ -1342,6 +1334,3 @@ index 0000000..12b1f62
+
+ return nb_rx;
+}
--
1.9.1

View File

@ -1,11 +1,17 @@
From 70725980c4d8f1e01cfa352a95341893aab00e7e Mon Sep 17 00:00:00 2001
From: John Lo <loj@cisco.com>
Date: Mon, 7 Mar 2016 14:07:19 -0500
Subject: [PATCH 1/2] Fix-ENIC-PMD-problem-with-not-sending-the-first-pack.
commit aba31298526865f5db99eaa54b63eb39dc95b74f
Author: John Daley <johndale@cisco.com>
Date: Tue Mar 8 10:49:07 2016 -0800
---
drivers/net/enic/base/enic_vnic_wq.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
enic: fix last packet not being sent
The last packet of the tx burst function array was not being
emitted until the subsequent call. The nic descriptor index
was being set to the current tx descriptor instead of one past
the descriptor as required by the nic.
Fixes: d739ba4c6abf ("enic: improve Tx packet rate")
Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/base/enic_vnic_wq.h b/drivers/net/enic/base/enic_vnic_wq.h
index e3ea574..b019109 100644
@ -26,6 +32,3 @@ index e3ea574..b019109 100644
}
#endif /* _ENIC_VNIC_WQ_H_ */
--
1.9.1

View File

@ -0,0 +1,42 @@
commit bba57df3861c644e98c5e8f79e62f6ca5074cb40
Author: Nelson Escobar <neescoba@cisco.com>
Date: Thu Mar 17 15:48:13 2016 -0700
enic: add missing newline to print statements
Add the missing '\n' character to the end of a few print statements.
Fixes: fefed3d1e62c ("enic: new driver")
Signed-off-by: Nelson Escobar <neescoba@cisco.com>
Acked-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 9fff020..e30672c 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -342,13 +342,13 @@ enic_alloc_rx_queue_mbufs(struct enic *enic, struct vnic_rq *rq)
unsigned i;
dma_addr_t dma_addr;
- dev_debug(enic, "queue %u, allocating %u rx queue mbufs", rq->index,
+ dev_debug(enic, "queue %u, allocating %u rx queue mbufs\n", rq->index,
rq->ring.desc_count);
for (i = 0; i < rq->ring.desc_count; i++, rqd++) {
mb = rte_rxmbuf_alloc(rq->mp);
if (mb == NULL) {
- dev_err(enic, "RX mbuf alloc failed queue_id=%u",
+ dev_err(enic, "RX mbuf alloc failed queue_id=%u\n",
(unsigned)rq->index);
return -ENOMEM;
}
@@ -388,7 +388,7 @@ enic_alloc_consistent(__rte_unused void *priv, size_t size,
rz = rte_memzone_reserve_aligned((const char *)name,
size, SOCKET_ID_ANY, 0, ENIC_ALIGN);
if (!rz) {
- pr_err("%s : Failed to allocate memory requested for %s",
+ pr_err("%s : Failed to allocate memory requested for %s\n",
__func__, name);
return NULL;
}

View File

@ -0,0 +1,46 @@
commit ddf2da3ecec97a316838f40fe13e217afafc6252
Author: Nelson Escobar <neescoba@cisco.com>
Date: Thu Mar 17 15:49:58 2016 -0700
enic: fix crash when allocating too many queues
Add checks to make sure we don't try to allocate more tx or rx queues
than we support.
Fixes: fefed3d1e62c ("enic: new driver")
Signed-off-by: Nelson Escobar <neescoba@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index bab0f7d..4969476 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -174,6 +174,13 @@ static int enicpmd_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
struct enic *enic = pmd_priv(eth_dev);
ENICPMD_FUNC_TRACE();
+ if (queue_idx >= ENIC_WQ_MAX) {
+ dev_err(enic,
+ "Max number of TX queues exceeded. Max is %d\n",
+ ENIC_WQ_MAX);
+ return -EINVAL;
+ }
+
eth_dev->data->tx_queues[queue_idx] = (void *)&enic->wq[queue_idx];
ret = enic_alloc_wq(enic, queue_idx, socket_id, nb_desc);
@@ -262,6 +269,13 @@ static int enicpmd_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
struct enic *enic = pmd_priv(eth_dev);
ENICPMD_FUNC_TRACE();
+ if (queue_idx >= ENIC_RQ_MAX) {
+ dev_err(enic,
+ "Max number of RX queues exceeded. Max is %d\n",
+ ENIC_RQ_MAX);
+ return -EINVAL;
+ }
+
eth_dev->data->rx_queues[queue_idx] = (void *)&enic->rq[queue_idx];
ret = enic_alloc_rq(enic, queue_idx, socket_id, mp, nb_desc);

View File

@ -0,0 +1,38 @@
commit 3253bbc79c8a1eddf791d9ec11bcea4a004d258e
Author: John Daley <johndale@cisco.com>
Date: Thu Mar 17 15:57:05 2016 -0700
enic: fix mbuf flags on Rx
In the receive path, the function to set mbuf ol_flags used the
mbuf packet_type before it was set.
Fixes: 947d860c821f ("enic: improve Rx performance")
Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
index 945a60f..59ebaa4 100644
--- a/drivers/net/enic/enic_rx.c
+++ b/drivers/net/enic/enic_rx.c
@@ -210,7 +210,7 @@ enic_cq_rx_to_pkt_flags(struct cq_desc *cqd, struct rte_mbuf *mbuf)
ciflags = enic_cq_rx_desc_ciflags(cqrd);
bwflags = enic_cq_rx_desc_bwflags(cqrd);
- ASSERT(mbuf->ol_flags == 0);
+ mbuf->ol_flags = 0;
/* flags are meaningless if !EOP */
if (unlikely(!enic_cq_rx_desc_eop(ciflags)))
@@ -340,10 +340,10 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
rxmb->pkt_len = rx_pkt_len;
rxmb->data_len = rx_pkt_len;
rxmb->port = enic->port_id;
+ rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
rxmb->ol_flags = ol_err_flags;
if (!ol_err_flags)
enic_cq_rx_to_pkt_flags(&cqd, rxmb);
- rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
/* prefetch mbuf data for caller */
rte_packet_prefetch(RTE_PTR_ADD(rxmb->buf_addr,

View File

@ -0,0 +1,112 @@
commit 5776c30293bbbdb3e332c868fbccf99b2026fba0
Author: John Daley <johndale@cisco.com>
Date: Thu Mar 17 15:57:06 2016 -0700
enic: fix error packets handling
If the packet_error bit in the completion descriptor is set, the
remainder of the descriptor and data are invalid. PKT_RX_MAC_ERR
was set in the mbuf->ol_flags if packet_error was set and used
later to indicate an error packet. But since PKT_RX_MAC_ERR is
defined as 0, mbuf flags and packet types and length were being
misinterpreted.
Make the function enic_cq_rx_to_pkt_err_flags() return true for error
packets and use the return value instead of mbuf->ol_flags to indicate
error packets. Also remove warning for error packets and rely on
rx_error stats.
Fixes: 947d860c821f ("enic: improve Rx performance")
Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
index 59ebaa4..817a891 100644
--- a/drivers/net/enic/enic_rx.c
+++ b/drivers/net/enic/enic_rx.c
@@ -129,13 +129,6 @@ enic_cq_rx_desc_rss_hash(struct cq_enet_rq_desc *cqrd)
return le32_to_cpu(cqrd->rss_hash);
}
-static inline uint8_t
-enic_cq_rx_desc_fcs_ok(struct cq_enet_rq_desc *cqrd)
-{
- return ((cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_FCS_OK) ==
- CQ_ENET_RQ_DESC_FLAGS_FCS_OK);
-}
-
static inline uint16_t
enic_cq_rx_desc_vlan(struct cq_enet_rq_desc *cqrd)
{
@@ -150,25 +143,21 @@ enic_cq_rx_desc_n_bytes(struct cq_desc *cqd)
CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
}
-static inline uint64_t
-enic_cq_rx_to_pkt_err_flags(struct cq_desc *cqd)
+static inline uint8_t
+enic_cq_rx_to_pkt_err_flags(struct cq_desc *cqd, uint64_t *pkt_err_flags_out)
{
struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
uint16_t bwflags;
+ int ret = 0;
uint64_t pkt_err_flags = 0;
bwflags = enic_cq_rx_desc_bwflags(cqrd);
-
- /* Check for packet error. Can't be more specific than MAC error */
- if (enic_cq_rx_desc_packet_error(bwflags)) {
- pkt_err_flags |= PKT_RX_MAC_ERR;
- }
-
- /* Check for bad FCS. MAC error isn't quite, but no other choice */
- if (!enic_cq_rx_desc_fcs_ok(cqrd)) {
- pkt_err_flags |= PKT_RX_MAC_ERR;
+ if (unlikely(enic_cq_rx_desc_packet_error(bwflags))) {
+ pkt_err_flags = PKT_RX_MAC_ERR;
+ ret = 1;
}
- return pkt_err_flags;
+ *pkt_err_flags_out = pkt_err_flags;
+ return ret;
}
/*
@@ -282,6 +271,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
dma_addr_t dma_addr;
struct cq_desc cqd;
uint64_t ol_err_flags;
+ uint8_t packet_error;
/* Check for pkts available */
color = (cqd_ptr->type_color >> CQ_DESC_COLOR_SHIFT)
@@ -303,9 +293,9 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
break;
}
- /* Check for FCS or packet errors */
- ol_err_flags = enic_cq_rx_to_pkt_err_flags(&cqd);
- if (ol_err_flags == 0)
+ /* A packet error means descriptor and data are untrusted */
+ packet_error = enic_cq_rx_to_pkt_err_flags(&cqd, &ol_err_flags);
+ if (!packet_error)
rx_pkt_len = enic_cq_rx_desc_n_bytes(&cqd);
else
rx_pkt_len = 0;
@@ -340,10 +330,13 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
rxmb->pkt_len = rx_pkt_len;
rxmb->data_len = rx_pkt_len;
rxmb->port = enic->port_id;
- rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
- rxmb->ol_flags = ol_err_flags;
- if (!ol_err_flags)
+ if (!packet_error) {
+ rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
enic_cq_rx_to_pkt_flags(&cqd, rxmb);
+ } else {
+ rxmb->packet_type = 0;
+ rxmb->ol_flags = 0;
+ }
/* prefetch mbuf data for caller */
rte_packet_prefetch(RTE_PTR_ADD(rxmb->buf_addr,

View File

@ -0,0 +1,53 @@
commit 50765c820e98a4434efbc0a58df4b9d78afb7a5f
Author: John Daley <johndale@cisco.com>
Date: Thu Mar 17 15:57:07 2016 -0700
enic: remove packet error conditional
small cleanup to remove conditional.
Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
index 817a891..232987a 100644
--- a/drivers/net/enic/enic_rx.c
+++ b/drivers/net/enic/enic_rx.c
@@ -266,7 +266,6 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
nb_hold = rq->rx_nb_hold; /* mbufs held by software */
while (nb_rx < nb_pkts) {
- uint16_t rx_pkt_len;
volatile struct rq_enet_desc *rqd_ptr;
dma_addr_t dma_addr;
struct cq_desc cqd;
@@ -295,10 +294,6 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
/* A packet error means descriptor and data are untrusted */
packet_error = enic_cq_rx_to_pkt_err_flags(&cqd, &ol_err_flags);
- if (!packet_error)
- rx_pkt_len = enic_cq_rx_desc_n_bytes(&cqd);
- else
- rx_pkt_len = 0;
/* Get the mbuf to return and replace with one just allocated */
rxmb = rq->mbuf_ring[rx_id];
@@ -327,16 +322,17 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
rxmb->data_off = RTE_PKTMBUF_HEADROOM;
rxmb->nb_segs = 1;
rxmb->next = NULL;
- rxmb->pkt_len = rx_pkt_len;
- rxmb->data_len = rx_pkt_len;
rxmb->port = enic->port_id;
if (!packet_error) {
+ rxmb->pkt_len = enic_cq_rx_desc_n_bytes(&cqd);
rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
enic_cq_rx_to_pkt_flags(&cqd, rxmb);
} else {
+ rxmb->pkt_len = 0;
rxmb->packet_type = 0;
rxmb->ol_flags = 0;
}
+ rxmb->data_len = rxmb->pkt_len;
/* prefetch mbuf data for caller */
rte_packet_prefetch(RTE_PTR_ADD(rxmb->buf_addr,

View File

@ -0,0 +1,36 @@
commit 57524648749fb7dc1daf3af3213dab472ee432de
Author: John Daley <johndale@cisco.com>
Date: Fri Mar 18 11:27:07 2016 -0700
enic: update maintainers
Change maintainers for ENIC PMD and fix pointer to enic
documentation in MAINTAINERS.
Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index 6ed54dd..e848ffa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -276,8 +276,9 @@ F: doc/guides/nics/cxgbe.rst
Cisco enic
M: John Daley <johndale@cisco.com>
-M: Sujith Sankar <ssujith@cisco.com>
+M: Nelson Escobar <neescoba@cisco.com>
F: drivers/net/enic/
+F: doc/guides/nics/enic.rst
Combo szedata2
M: Matej Vido <matejvido@gmail.com>
diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 2a228fd..e67c3db 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -218,4 +218,4 @@ Any questions or bugs should be reported to DPDK community and to the ENIC PMD
maintainers:
- John Daley <johndale@cisco.com>
-- Sujith Sankar <ssujith@cisco.com>
+- Nelson Escobar <neescoba@cisco.com>

View File

@ -0,0 +1,61 @@
commit 65ca78fdf9a684743bfca278cf1fcfea4603931d
Author: Nelson Escobar <neescoba@cisco.com>
Date: Fri Mar 18 11:33:34 2016 -0700
enic: fix Rx descriptor limit
On initialization, the rq descriptor count was set to the limit
of the vic. When the requested number of rx descriptors was
less than this count, enic_alloc_rq() was incorrectly setting
the count to the lower value. This results in later calls to
enic_alloc_rq() incorrectly using the lower value as the adapter
limit.
Fixes: fefed3d1e62c ("enic: new driver")
Signed-off-by: Nelson Escobar <neescoba@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index e30672c..2f79cf0 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -524,24 +524,22 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
"policy. Applying the value in the adapter "\
"policy (%d).\n",
queue_idx, nb_desc, enic->config.rq_desc_count);
- } else if (nb_desc != enic->config.rq_desc_count) {
- enic->config.rq_desc_count = nb_desc;
- dev_info(enic,
- "RX Queues - effective number of descs:%d\n",
- nb_desc);
+ nb_desc = enic->config.rq_desc_count;
}
+ dev_info(enic, "RX Queues - effective number of descs:%d\n",
+ nb_desc);
}
/* Allocate queue resources */
rc = vnic_rq_alloc(enic->vdev, rq, queue_idx,
- enic->config.rq_desc_count, sizeof(struct rq_enet_desc));
+ nb_desc, sizeof(struct rq_enet_desc));
if (rc) {
dev_err(enic, "error in allocation of rq\n");
goto err_exit;
}
rc = vnic_cq_alloc(enic->vdev, &enic->cq[queue_idx], queue_idx,
- socket_id, enic->config.rq_desc_count,
+ socket_id, nb_desc,
sizeof(struct cq_enet_rq_desc));
if (rc) {
dev_err(enic, "error in allocation of cq for rq\n");
@@ -550,7 +548,7 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
/* Allocate the mbuf ring */
rq->mbuf_ring = (struct rte_mbuf **)rte_zmalloc_socket("rq->mbuf_ring",
- sizeof(struct rte_mbuf *) * enic->config.rq_desc_count,
+ sizeof(struct rte_mbuf *) * nb_desc,
RTE_CACHE_LINE_SIZE, rq->socket_id);
if (rq->mbuf_ring != NULL)

View File

@ -0,0 +1,82 @@
commit 67c4432ec364ce21f5059ba0696a9d0f3393356c
Author: John Daley <johndale@cisco.com>
Date: Thu Mar 24 14:00:39 2016 -0700
enic: fix TX hang when number of packets > queue size
If the nb_pkts parameter to rte_eth_tx_burst() was greater than
the TX descriptor count, a completion was not being requested
from the NIC, so descriptors would not be released back to the
host causing a lock-up.
Introduce a limit of how many TX descriptors can be used in a single
call to the enic PMD burst TX function before requesting a completion.
Fixes: d739ba4c6abf ("enic: improve Tx packet rate")
Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 4969476..6bea940 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -523,7 +523,7 @@ static void enicpmd_remove_mac_addr(struct rte_eth_dev *eth_dev, __rte_unused ui
static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
{
- unsigned int index;
+ uint16_t index;
unsigned int frags;
unsigned int pkt_len;
unsigned int seg_len;
@@ -535,6 +535,7 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
unsigned short vlan_id;
unsigned short ol_flags;
uint8_t last_seg, eop;
+ unsigned int host_tx_descs = 0;
for (index = 0; index < nb_pkts; index++) {
tx_pkt = *tx_pkts++;
@@ -550,6 +551,7 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
return index;
}
}
+
pkt_len = tx_pkt->pkt_len;
vlan_id = tx_pkt->vlan_tci;
ol_flags = tx_pkt->ol_flags;
@@ -559,9 +561,19 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
next_tx_pkt = tx_pkt->next;
seg_len = tx_pkt->data_len;
inc_len += seg_len;
- eop = (pkt_len == inc_len) || (!next_tx_pkt);
- last_seg = eop &&
- (index == ((unsigned int)nb_pkts - 1));
+
+ host_tx_descs++;
+ last_seg = 0;
+ eop = 0;
+ if ((pkt_len == inc_len) || !next_tx_pkt) {
+ eop = 1;
+ /* post if last packet in batch or > thresh */
+ if ((index == (nb_pkts - 1)) ||
+ (host_tx_descs > ENIC_TX_POST_THRESH)) {
+ last_seg = 1;
+ host_tx_descs = 0;
+ }
+ }
enic_send_pkt(enic, wq, tx_pkt, (unsigned short)seg_len,
!frags, eop, last_seg, ol_flags, vlan_id);
tx_pkt = next_tx_pkt;
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 33f2e84..00fa71d 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -53,6 +53,7 @@
#define ENIC_NON_TSO_MAX_DESC 16
#define ENIC_DEFAULT_RX_FREE_THRESH 32
+#define ENIC_TX_POST_THRESH (ENIC_MIN_WQ_DESCS / 2)
#define ENIC_SETTING(enic, f) ((enic->config.flags & VENETF_##f) ? 1 : 0)

View File

@ -0,0 +1,71 @@
commit 65bcf215aae2e0b9935557e237af054ad0860bad
Author: Nelson Escobar <neescoba@cisco.com>
Date: Tue Mar 22 13:42:08 2016 -0700
bonding: fix bond link detect in non-interrupt mode
Stopping then re-starting a bond interface containing slaves that
used polling for link detection caused the bond to think all slave
links were down and inactive.
Move the start of the polling for link from slave_add() to
bond_ethdev_start() and in bond_ethdev_stop() make sure we clear
the last_link_status of the slaves.
Signed-off-by: Nelson Escobar <neescoba@cisco.com>
Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fb26d35..f0960c6 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1454,18 +1454,11 @@ slave_add(struct bond_dev_private *internals,
slave_details->port_id = slave_eth_dev->data->port_id;
slave_details->last_link_status = 0;
- /* If slave device doesn't support interrupts then we need to enabled
- * polling to monitor link status */
+ /* Mark slave devices that don't support interrupts so we can
+ * compensate when we start the bond
+ */
if (!(slave_eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)) {
slave_details->link_status_poll_enabled = 1;
-
- if (!internals->link_status_polling_enabled) {
- internals->link_status_polling_enabled = 1;
-
- rte_eal_alarm_set(internals->link_status_polling_interval_ms * 1000,
- bond_ethdev_slave_link_status_change_monitor,
- (void *)&rte_eth_devices[internals->port_id]);
- }
}
slave_details->link_status_wait_to_complete = 0;
@@ -1550,6 +1543,18 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
eth_dev->data->port_id, internals->slaves[i].port_id);
return -1;
}
+ /* We will need to poll for link status if any slave doesn't
+ * support interrupts
+ */
+ if (internals->slaves[i].link_status_poll_enabled)
+ internals->link_status_polling_enabled = 1;
+ }
+ /* start polling if needed */
+ if (internals->link_status_polling_enabled) {
+ rte_eal_alarm_set(
+ internals->link_status_polling_interval_ms * 1000,
+ bond_ethdev_slave_link_status_change_monitor,
+ (void *)&rte_eth_devices[internals->port_id]);
}
if (internals->user_defined_primary_port)
@@ -1622,6 +1627,8 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
internals->active_slave_count = 0;
internals->link_status_polling_enabled = 0;
+ for (i = 0; i < internals->slave_count; i++)
+ internals->slaves[i].last_link_status = 0;
eth_dev->data->dev_link.link_status = 0;
eth_dev->data->dev_started = 0;