[dpdk-dev,2/2] driver/net/mpipe: fix the crash/hung issue when testpmd quits

Message ID 1450813790-11874-3-git-send-email-lsun@ezchip.com (mailing list archive)
State Superseded, archived
Headers

Commit Message

Liming Sun Dec. 22, 2015, 7:49 p.m. UTC
  1. Fixed the compiling issue of the ethtool example on tilegx
   platform.
2. Fixed the hung/crash issue when quitting testpmd under high
   traffic rate. The buffer error bit needs to be checked before
   processing the idesc and releasing the buffer. Code logic is
   also simplified.

Signed-off-by: Liming Sun <lsun@ezchip.com>
---
 drivers/net/mpipe/mpipe_tilegx.c                   |   46 +++++++-------------
 .../common/include/arch/tile/rte_rwlock.h          |    1 +
 2 files changed, 17 insertions(+), 30 deletions(-)
  

Comments

Zhigang Lu Jan. 8, 2016, 7:49 a.m. UTC | #1
>-----Original Message-----
>From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Liming Sun
>Sent: Wednesday, December 23, 2015 3:50 AM
>To: dev@dpdk.org
>Subject: [dpdk-dev] [PATCH 2/2] driver/net/mpipe: fix the crash/hung issue
when
>testpmd quits
>
>1. Fixed the compiling issue of the ethtool example on tilegx
>   platform.
>2. Fixed the hung/crash issue when quitting testpmd under high
>   traffic rate. The buffer error bit needs to be checked before
>   processing the idesc and releasing the buffer. Code logic is
>   also simplified.
>
>Signed-off-by: Liming Sun <lsun@ezchip.com>
>---
> drivers/net/mpipe/mpipe_tilegx.c                   |   46
>+++++++-------------
> .../common/include/arch/tile/rte_rwlock.h          |    1 +
> 2 files changed, 17 insertions(+), 30 deletions(-)
>
>diff --git a/drivers/net/mpipe/mpipe_tilegx.c
>b/drivers/net/mpipe/mpipe_tilegx.c
>index 8d006fa..4cb54c3 100644
>--- a/drivers/net/mpipe/mpipe_tilegx.c
>+++ b/drivers/net/mpipe/mpipe_tilegx.c
>@@ -134,7 +134,6 @@ struct mpipe_dev_priv {
> 	struct rte_mempool *rx_mpool;	/* mpool used by the rx queues. */
> 	unsigned rx_offset;		/* Receive head room. */
> 	unsigned rx_size_code;		/* mPIPE rx buffer size code. */
>-	unsigned rx_buffers;		/* receive buffers on stack. */
> 	int is_xaui:1,			/* Is this an xgbe or gbe? */
> 	    initialized:1,		/* Initialized port? */
> 	    running:1;			/* Running port? */
>@@ -529,7 +528,6 @@ mpipe_recv_fill_stack(struct mpipe_dev_priv *priv, int
>count)
> 		mpipe_recv_push(priv, mbuf);
> 	}
>
>-	priv->rx_buffers += count;
> 	PMD_DEBUG_RX("%s: Filled %d/%d buffers\n", mpipe_name(priv), i,
>count);  }
>
>@@ -539,10 +537,9 @@ mpipe_recv_flush_stack(struct mpipe_dev_priv *priv)
> 	const int offset = priv->rx_offset & ~RTE_MEMPOOL_ALIGN_MASK;
> 	uint8_t in_port = priv->port_id;
> 	struct rte_mbuf *mbuf;
>-	unsigned count;
> 	void *va;
>
>-	for (count = 0; count < priv->rx_buffers; count++) {
>+	while (1) {
> 		va = gxio_mpipe_pop_buffer(priv->context, priv->stack);
> 		if (!va)
> 			break;
>@@ -561,10 +558,6 @@ mpipe_recv_flush_stack(struct mpipe_dev_priv *priv)
>
> 		__rte_mbuf_raw_free(mbuf);
> 	}
>-
>-	PMD_DEBUG_RX("%s: Returned %d/%d buffers\n",
>-		     mpipe_name(priv), count, priv->rx_buffers);
>-	priv->rx_buffers -= count;
> }
>
> static void
>@@ -1246,31 +1239,23 @@ mpipe_recv_flush(struct mpipe_dev_priv *priv)
> 	gxio_mpipe_iqueue_t *iqueue;
> 	gxio_mpipe_idesc_t idesc;
> 	struct rte_mbuf *mbuf;
>-	int retries = 0;
> 	unsigned queue;
>
>-	do {
>-		mpipe_recv_flush_stack(priv);
>-
>-		/* Flush packets sitting in recv queues. */
>-		for (queue = 0; queue < priv->nb_rx_queues; queue++) {
>-			rx_queue = mpipe_rx_queue(priv, queue);
>-			iqueue = &rx_queue->iqueue;
>-			while (gxio_mpipe_iqueue_try_get(iqueue, &idesc) >=
0) {
>-				mbuf = mpipe_recv_mbuf(priv, &idesc,
in_port);
>-				rte_pktmbuf_free(mbuf);
>-				priv->rx_buffers--;
>-			}
>-			rte_free(rx_queue->rx_ring_mem);
>-		}
>-	} while (retries++ < 10 && priv->rx_buffers);
>+	/* Release packets on the buffer stack. */
>+	mpipe_recv_flush_stack(priv);
>
>-	if (priv->rx_buffers) {
>-		RTE_LOG(ERR, PMD, "%s: Leaked %d receive buffers.\n",
>-			mpipe_name(priv), priv->rx_buffers);
>-	} else {
>-		PMD_DEBUG_RX("%s: Returned all receive buffers.\n",
>-			     mpipe_name(priv));
>+	/* Flush packets sitting in recv queues. */
>+	for (queue = 0; queue < priv->nb_rx_queues; queue++) {
>+		rx_queue = mpipe_rx_queue(priv, queue);
>+		iqueue = &rx_queue->iqueue;
>+		while (gxio_mpipe_iqueue_try_get(iqueue, &idesc) >= 0) {
>+			/* Skip idesc with the 'buffer error' bit set. */
>+			if (idesc.be)
>+				continue;
>+			mbuf = mpipe_recv_mbuf(priv, &idesc, in_port);
>+			rte_pktmbuf_free(mbuf);
>+		}
>+		rte_free(rx_queue->rx_ring_mem);
> 	}
> }
>
>@@ -1339,6 +1324,7 @@ mpipe_do_xmit(struct mpipe_tx_queue *tx_queue,
>struct rte_mbuf **tx_pkts,
> 				.xfer_size = rte_pktmbuf_data_len(mbuf),
> 				.bound     = next ? 0 : 1,
> 				.stack_idx = mpipe_mbuf_stack_index(priv,
mbuf),
>+				.size      = priv->rx_size_code,
> 			} };
> 			if (mpipe_local.mbuf_push_debt[port_id] > 0) {
> 				mpipe_local.mbuf_push_debt[port_id]--;
>diff --git a/lib/librte_eal/common/include/arch/tile/rte_rwlock.h
>b/lib/librte_eal/common/include/arch/tile/rte_rwlock.h
>index 8f67a19..6d609e8 100644
>--- a/lib/librte_eal/common/include/arch/tile/rte_rwlock.h
>+++ b/lib/librte_eal/common/include/arch/tile/rte_rwlock.h
>@@ -38,6 +38,7 @@ extern "C" {
> #endif
>
> #include "generic/rte_rwlock.h"
>+#include <rte_spinlock.h>
>
> static inline void
> rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)
>--
>1.7.1

Acked-by: Zhigang Lu <zlu@ezchip.com>
  

Patch

diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 8d006fa..4cb54c3 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -134,7 +134,6 @@  struct mpipe_dev_priv {
 	struct rte_mempool *rx_mpool;	/* mpool used by the rx queues. */
 	unsigned rx_offset;		/* Receive head room. */
 	unsigned rx_size_code;		/* mPIPE rx buffer size code. */
-	unsigned rx_buffers;		/* receive buffers on stack. */
 	int is_xaui:1,			/* Is this an xgbe or gbe? */
 	    initialized:1,		/* Initialized port? */
 	    running:1;			/* Running port? */
@@ -529,7 +528,6 @@  mpipe_recv_fill_stack(struct mpipe_dev_priv *priv, int count)
 		mpipe_recv_push(priv, mbuf);
 	}
 
-	priv->rx_buffers += count;
 	PMD_DEBUG_RX("%s: Filled %d/%d buffers\n", mpipe_name(priv), i, count);
 }
 
@@ -539,10 +537,9 @@  mpipe_recv_flush_stack(struct mpipe_dev_priv *priv)
 	const int offset = priv->rx_offset & ~RTE_MEMPOOL_ALIGN_MASK;
 	uint8_t in_port = priv->port_id;
 	struct rte_mbuf *mbuf;
-	unsigned count;
 	void *va;
 
-	for (count = 0; count < priv->rx_buffers; count++) {
+	while (1) {
 		va = gxio_mpipe_pop_buffer(priv->context, priv->stack);
 		if (!va)
 			break;
@@ -561,10 +558,6 @@  mpipe_recv_flush_stack(struct mpipe_dev_priv *priv)
 
 		__rte_mbuf_raw_free(mbuf);
 	}
-
-	PMD_DEBUG_RX("%s: Returned %d/%d buffers\n",
-		     mpipe_name(priv), count, priv->rx_buffers);
-	priv->rx_buffers -= count;
 }
 
 static void
@@ -1246,31 +1239,23 @@  mpipe_recv_flush(struct mpipe_dev_priv *priv)
 	gxio_mpipe_iqueue_t *iqueue;
 	gxio_mpipe_idesc_t idesc;
 	struct rte_mbuf *mbuf;
-	int retries = 0;
 	unsigned queue;
 
-	do {
-		mpipe_recv_flush_stack(priv);
-
-		/* Flush packets sitting in recv queues. */
-		for (queue = 0; queue < priv->nb_rx_queues; queue++) {
-			rx_queue = mpipe_rx_queue(priv, queue);
-			iqueue = &rx_queue->iqueue;
-			while (gxio_mpipe_iqueue_try_get(iqueue, &idesc) >= 0) {
-				mbuf = mpipe_recv_mbuf(priv, &idesc, in_port);
-				rte_pktmbuf_free(mbuf);
-				priv->rx_buffers--;
-			}
-			rte_free(rx_queue->rx_ring_mem);
-		}
-	} while (retries++ < 10 && priv->rx_buffers);
+	/* Release packets on the buffer stack. */
+	mpipe_recv_flush_stack(priv);
 
-	if (priv->rx_buffers) {
-		RTE_LOG(ERR, PMD, "%s: Leaked %d receive buffers.\n",
-			mpipe_name(priv), priv->rx_buffers);
-	} else {
-		PMD_DEBUG_RX("%s: Returned all receive buffers.\n",
-			     mpipe_name(priv));
+	/* Flush packets sitting in recv queues. */
+	for (queue = 0; queue < priv->nb_rx_queues; queue++) {
+		rx_queue = mpipe_rx_queue(priv, queue);
+		iqueue = &rx_queue->iqueue;
+		while (gxio_mpipe_iqueue_try_get(iqueue, &idesc) >= 0) {
+			/* Skip idesc with the 'buffer error' bit set. */
+			if (idesc.be)
+				continue;
+			mbuf = mpipe_recv_mbuf(priv, &idesc, in_port);
+			rte_pktmbuf_free(mbuf);
+		}
+		rte_free(rx_queue->rx_ring_mem);
 	}
 }
 
@@ -1339,6 +1324,7 @@  mpipe_do_xmit(struct mpipe_tx_queue *tx_queue, struct rte_mbuf **tx_pkts,
 				.xfer_size = rte_pktmbuf_data_len(mbuf),
 				.bound     = next ? 0 : 1,
 				.stack_idx = mpipe_mbuf_stack_index(priv, mbuf),
+				.size      = priv->rx_size_code,
 			} };
 			if (mpipe_local.mbuf_push_debt[port_id] > 0) {
 				mpipe_local.mbuf_push_debt[port_id]--;
diff --git a/lib/librte_eal/common/include/arch/tile/rte_rwlock.h b/lib/librte_eal/common/include/arch/tile/rte_rwlock.h
index 8f67a19..6d609e8 100644
--- a/lib/librte_eal/common/include/arch/tile/rte_rwlock.h
+++ b/lib/librte_eal/common/include/arch/tile/rte_rwlock.h
@@ -38,6 +38,7 @@  extern "C" {
 #endif
 
 #include "generic/rte_rwlock.h"
+#include <rte_spinlock.h>
 
 static inline void
 rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)