patches for DPDK stable branches
 help / color / mirror / Atom feed
* [dpdk-stable] [PATCH] net/enic: fix memory leak with oversized Tx packets
@ 2017-02-03  1:18 John Daley
  2017-02-03 22:52 ` Ferruh Yigit
  0 siblings, 1 reply; 3+ messages in thread
From: John Daley @ 2017-02-03  1:18 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: dev, John Daley, stable

If a packet send is attempted with a packet larger than the NIC
is capabile of processing (9208) it will be dropped with no
completion descriptor returned or completion index update, which
will lead to an mbuf leak and eventual hang.

Drop and count oversized Tx packets in the Tx burst function and
dereference/free the mbuf without sending it to the NIC.

Since the maximum Rx and Tx packet sizes are different on enic
and are now both being used, make the define ENIC_DEFAULT_MAX_PKT_SIZE
be 2 defines, one for Rx and one for Tx.

Fixes: fefed3d1e62c ("enic: new driver")
Cc: stable@dpdk.org

Signed-off-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/enic.h      |  1 +
 drivers/net/enic/enic_main.c |  5 ++++-
 drivers/net/enic/enic_res.c  |  5 +++--
 drivers/net/enic/enic_res.h  |  5 ++++-
 drivers/net/enic/enic_rxtx.c | 13 ++++++++++---
 5 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index a454017..e921de4 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -103,6 +103,7 @@ struct enic_fdir {
 struct enic_soft_stats {
 	rte_atomic64_t rx_nombuf;
 	rte_atomic64_t rx_packet_errors;
+	rte_atomic64_t tx_oversized;
 };
 
 struct enic_memzone_entry {
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 21e8ede..570b7b6 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -137,6 +137,7 @@ static void enic_clear_soft_stats(struct enic *enic)
 	struct enic_soft_stats *soft_stats = &enic->soft_stats;
 	rte_atomic64_clear(&soft_stats->rx_nombuf);
 	rte_atomic64_clear(&soft_stats->rx_packet_errors);
+	rte_atomic64_clear(&soft_stats->tx_oversized);
 }
 
 static void enic_init_soft_stats(struct enic *enic)
@@ -144,6 +145,7 @@ static void enic_init_soft_stats(struct enic *enic)
 	struct enic_soft_stats *soft_stats = &enic->soft_stats;
 	rte_atomic64_init(&soft_stats->rx_nombuf);
 	rte_atomic64_init(&soft_stats->rx_packet_errors);
+	rte_atomic64_init(&soft_stats->tx_oversized);
 	enic_clear_soft_stats(enic);
 }
 
@@ -183,7 +185,8 @@ void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats)
 	r_stats->obytes = stats->tx.tx_bytes_ok;
 
 	r_stats->ierrors = stats->rx.rx_errors + stats->rx.rx_drop;
-	r_stats->oerrors = stats->tx.tx_errors;
+	r_stats->oerrors = stats->tx.tx_errors
+			   + rte_atomic64_read(&soft_stats->tx_oversized);
 
 	r_stats->imissed = stats->rx.rx_no_bufs + rx_truncated;
 
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 8a230a1..867bd25 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -89,10 +89,11 @@ int enic_get_vnic_config(struct enic *enic)
 	/* max packet size is only defined in newer VIC firmware
 	 * and will be 0 for legacy firmware and VICs
 	 */
-	if (c->max_pkt_size > ENIC_DEFAULT_MAX_PKT_SIZE)
+	if (c->max_pkt_size > ENIC_DEFAULT_RX_MAX_PKT_SIZE)
 		enic->max_mtu = c->max_pkt_size - (ETHER_HDR_LEN + 4);
 	else
-		enic->max_mtu = ENIC_DEFAULT_MAX_PKT_SIZE - (ETHER_HDR_LEN + 4);
+		enic->max_mtu = ENIC_DEFAULT_RX_MAX_PKT_SIZE
+				- (ETHER_HDR_LEN + 4);
 	if (c->mtu == 0)
 		c->mtu = 1500;
 
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 303530e..1135d2e 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -48,7 +48,10 @@
 #define ENIC_MIN_MTU			68
 
 /* Does not include (possible) inserted VLAN tag and FCS */
-#define ENIC_DEFAULT_MAX_PKT_SIZE	9022
+#define ENIC_DEFAULT_RX_MAX_PKT_SIZE	9022
+
+/* Does not include (possible) inserted VLAN tag and FCS */
+#define ENIC_TX_MAX_PKT_SIZE		9208
 
 #define ENIC_MULTICAST_PERFECT_FILTERS	32
 #define ENIC_UNICAST_PERFECT_FILTERS	32
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 26b83ae..343dabc 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -546,16 +546,23 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
 	for (index = 0; index < nb_pkts; index++) {
 		tx_pkt = *tx_pkts++;
+		pkt_len = tx_pkt->pkt_len;
+		data_len = tx_pkt->data_len;
+		ol_flags = tx_pkt->ol_flags;
 		nb_segs = tx_pkt->nb_segs;
+
+		if (pkt_len > ENIC_TX_MAX_PKT_SIZE) {
+			rte_pktmbuf_free(tx_pkt);
+			rte_atomic64_inc(&enic->soft_stats.tx_oversized);
+			continue;
+		}
+
 		if (nb_segs > wq_desc_avail) {
 			if (index > 0)
 				goto post;
 			goto done;
 		}
 
-		pkt_len = tx_pkt->pkt_len;
-		data_len = tx_pkt->data_len;
-		ol_flags = tx_pkt->ol_flags;
 		mss = 0;
 		vlan_id = 0;
 		vlan_tag_insert = 0;
-- 
2.10.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dpdk-stable] [PATCH] net/enic: fix memory leak with oversized Tx packets
  2017-02-03  1:18 [dpdk-stable] [PATCH] net/enic: fix memory leak with oversized Tx packets John Daley
@ 2017-02-03 22:52 ` Ferruh Yigit
  0 siblings, 0 replies; 3+ messages in thread
From: Ferruh Yigit @ 2017-02-03 22:52 UTC (permalink / raw)
  To: John Daley; +Cc: dev, stable

On 2/3/2017 1:18 AM, John Daley wrote:
> If a packet send is attempted with a packet larger than the NIC
> is capabile of processing (9208) it will be dropped with no
> completion descriptor returned or completion index update, which
> will lead to an mbuf leak and eventual hang.
> 
> Drop and count oversized Tx packets in the Tx burst function and
> dereference/free the mbuf without sending it to the NIC.
> 
> Since the maximum Rx and Tx packet sizes are different on enic
> and are now both being used, make the define ENIC_DEFAULT_MAX_PKT_SIZE
> be 2 defines, one for Rx and one for Tx.
> 
> Fixes: fefed3d1e62c ("enic: new driver")
> Cc: stable@dpdk.org
> 
> Signed-off-by: John Daley <johndale@cisco.com>

Applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [dpdk-stable] [PATCH] net/enic: fix memory leak with oversized Tx packets
@ 2017-02-03  1:17 John Daley
  0 siblings, 0 replies; 3+ messages in thread
From: John Daley @ 2017-02-03  1:17 UTC (permalink / raw)
  To: johnda888; +Cc: John Daley, stable

If a packet send is attempted with a packet larger than the NIC
is capabile of processing (9208) it will be dropped with no
completion descriptor returned or completion index update, which
will lead to an mbuf leak and eventual hang.

Drop and count oversized Tx packets in the Tx burst function and
dereference/free the mbuf without sending it to the NIC.

Since the maximum Rx and Tx packet sizes are different on enic
and are now both being used, make the define ENIC_DEFAULT_MAX_PKT_SIZE
be 2 defines, one for Rx and one for Tx.

Fixes: fefed3d1e62c ("enic: new driver")
Cc: stable@dpdk.org

Signed-off-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/enic.h      |  1 +
 drivers/net/enic/enic_main.c |  5 ++++-
 drivers/net/enic/enic_res.c  |  5 +++--
 drivers/net/enic/enic_res.h  |  5 ++++-
 drivers/net/enic/enic_rxtx.c | 13 ++++++++++---
 5 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index a454017..e921de4 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -103,6 +103,7 @@ struct enic_fdir {
 struct enic_soft_stats {
 	rte_atomic64_t rx_nombuf;
 	rte_atomic64_t rx_packet_errors;
+	rte_atomic64_t tx_oversized;
 };
 
 struct enic_memzone_entry {
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 21e8ede..570b7b6 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -137,6 +137,7 @@ static void enic_clear_soft_stats(struct enic *enic)
 	struct enic_soft_stats *soft_stats = &enic->soft_stats;
 	rte_atomic64_clear(&soft_stats->rx_nombuf);
 	rte_atomic64_clear(&soft_stats->rx_packet_errors);
+	rte_atomic64_clear(&soft_stats->tx_oversized);
 }
 
 static void enic_init_soft_stats(struct enic *enic)
@@ -144,6 +145,7 @@ static void enic_init_soft_stats(struct enic *enic)
 	struct enic_soft_stats *soft_stats = &enic->soft_stats;
 	rte_atomic64_init(&soft_stats->rx_nombuf);
 	rte_atomic64_init(&soft_stats->rx_packet_errors);
+	rte_atomic64_init(&soft_stats->tx_oversized);
 	enic_clear_soft_stats(enic);
 }
 
@@ -183,7 +185,8 @@ void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats)
 	r_stats->obytes = stats->tx.tx_bytes_ok;
 
 	r_stats->ierrors = stats->rx.rx_errors + stats->rx.rx_drop;
-	r_stats->oerrors = stats->tx.tx_errors;
+	r_stats->oerrors = stats->tx.tx_errors
+			   + rte_atomic64_read(&soft_stats->tx_oversized);
 
 	r_stats->imissed = stats->rx.rx_no_bufs + rx_truncated;
 
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 8a230a1..867bd25 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -89,10 +89,11 @@ int enic_get_vnic_config(struct enic *enic)
 	/* max packet size is only defined in newer VIC firmware
 	 * and will be 0 for legacy firmware and VICs
 	 */
-	if (c->max_pkt_size > ENIC_DEFAULT_MAX_PKT_SIZE)
+	if (c->max_pkt_size > ENIC_DEFAULT_RX_MAX_PKT_SIZE)
 		enic->max_mtu = c->max_pkt_size - (ETHER_HDR_LEN + 4);
 	else
-		enic->max_mtu = ENIC_DEFAULT_MAX_PKT_SIZE - (ETHER_HDR_LEN + 4);
+		enic->max_mtu = ENIC_DEFAULT_RX_MAX_PKT_SIZE
+				- (ETHER_HDR_LEN + 4);
 	if (c->mtu == 0)
 		c->mtu = 1500;
 
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 303530e..1135d2e 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -48,7 +48,10 @@
 #define ENIC_MIN_MTU			68
 
 /* Does not include (possible) inserted VLAN tag and FCS */
-#define ENIC_DEFAULT_MAX_PKT_SIZE	9022
+#define ENIC_DEFAULT_RX_MAX_PKT_SIZE	9022
+
+/* Does not include (possible) inserted VLAN tag and FCS */
+#define ENIC_TX_MAX_PKT_SIZE		9208
 
 #define ENIC_MULTICAST_PERFECT_FILTERS	32
 #define ENIC_UNICAST_PERFECT_FILTERS	32
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 26b83ae..343dabc 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -546,16 +546,23 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
 	for (index = 0; index < nb_pkts; index++) {
 		tx_pkt = *tx_pkts++;
+		pkt_len = tx_pkt->pkt_len;
+		data_len = tx_pkt->data_len;
+		ol_flags = tx_pkt->ol_flags;
 		nb_segs = tx_pkt->nb_segs;
+
+		if (pkt_len > ENIC_TX_MAX_PKT_SIZE) {
+			rte_pktmbuf_free(tx_pkt);
+			rte_atomic64_inc(&enic->soft_stats.tx_oversized);
+			continue;
+		}
+
 		if (nb_segs > wq_desc_avail) {
 			if (index > 0)
 				goto post;
 			goto done;
 		}
 
-		pkt_len = tx_pkt->pkt_len;
-		data_len = tx_pkt->data_len;
-		ol_flags = tx_pkt->ol_flags;
 		mss = 0;
 		vlan_id = 0;
 		vlan_tag_insert = 0;
-- 
2.10.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-02-03 22:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-03  1:18 [dpdk-stable] [PATCH] net/enic: fix memory leak with oversized Tx packets John Daley
2017-02-03 22:52 ` Ferruh Yigit
  -- strict thread matches above, loose matches on Subject: below --
2017-02-03  1:17 John Daley

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).