[dpdk-stable] patch 'net/netvsc: fix underflow when Rx external mbuf' has been queued to LTS release 18.11.10

Kevin Traynor ktraynor at redhat.com
Thu Aug 20 17:33:31 CEST 2020


Hi,

FYI, your patch has been queued to LTS release 18.11.10

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 08/25/20. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable-queue

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable-queue/commit/77cf88c0c6a69b720007ec5a683b389b1e253a20

Thanks.

Kevin.

---
>From 77cf88c0c6a69b720007ec5a683b389b1e253a20 Mon Sep 17 00:00:00 2001
From: Long Li <longli at microsoft.com>
Date: Tue, 23 Jun 2020 18:11:45 -0700
Subject: [PATCH] net/netvsc: fix underflow when Rx external mbuf

[ upstream commit d43b8c710836db953fad1bb6449a827e19b5a87a ]

When rte_pktmbuf_attach_extbuf() is used, the driver should not decrease
the reference count in its callback function hn_rx_buf_free_cb, because
the reference count is already decreased by rte_pktmbuf. Doing it twice
may result in underflow and driver may never send an ack packet over
vmbus to host.

Also declares rxbuf_outstanding as atomic, because this value is shared
among all receive queues.

Fixes: 4e9c73e96e83 ("net/netvsc: add Hyper-V network device")

Signed-off-by: Long Li <longli at microsoft.com>
Acked-by: Stephen Hemminger <stephen at networkplumber.org>
---
 drivers/net/netvsc/hn_nvs.c  |  1 -
 drivers/net/netvsc/hn_rxtx.c | 32 ++++++++++++--------------------
 drivers/net/netvsc/hn_var.h  |  2 +-
 3 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/net/netvsc/hn_nvs.c b/drivers/net/netvsc/hn_nvs.c
index 76a7281f1b..f97bb10846 100644
--- a/drivers/net/netvsc/hn_nvs.c
+++ b/drivers/net/netvsc/hn_nvs.c
@@ -100,5 +100,4 @@ __hn_nvs_execute(struct hn_data *hv,
 	if (hdr->type == NVS_TYPE_RNDIS) {
 		hn_nvs_ack_rxbuf(chan, xactid);
-		--hv->rxbuf_outstanding;
 		goto retry;
 	}
diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c
index b526b490b2..d7940b8119 100644
--- a/drivers/net/netvsc/hn_rxtx.c
+++ b/drivers/net/netvsc/hn_rxtx.c
@@ -489,22 +489,11 @@ next:
 }
 
-/*
- * Ack the consumed RXBUF associated w/ this channel packet,
- * so that this RXBUF can be recycled by the hypervisor.
- */
-static void hn_rx_buf_release(struct hn_rx_bufinfo *rxb)
-{
-	struct rte_mbuf_ext_shared_info *shinfo = &rxb->shinfo;
-	struct hn_data *hv = rxb->hv;
-
-	if (rte_mbuf_ext_refcnt_update(shinfo, -1) == 0) {
-		hn_nvs_ack_rxbuf(rxb->chan, rxb->xactid);
-		--hv->rxbuf_outstanding;
-	}
-}
-
 static void hn_rx_buf_free_cb(void *buf __rte_unused, void *opaque)
 {
-	hn_rx_buf_release(opaque);
+	struct hn_rx_bufinfo *rxb = opaque;
+	struct hn_data *hv = rxb->hv;
+
+	rte_atomic32_dec(&hv->rxbuf_outstanding);
+	hn_nvs_ack_rxbuf(rxb->chan, rxb->xactid);
 }
 
@@ -546,5 +535,6 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
 	 */
 	if (dlen >= HN_RXCOPY_THRESHOLD &&
-	    hv->rxbuf_outstanding < hv->rxbuf_section_cnt / 2) {
+	    (uint32_t)rte_atomic32_read(&hv->rxbuf_outstanding) <
+			hv->rxbuf_section_cnt / 2) {
 		struct rte_mbuf_ext_shared_info *shinfo;
 		const void *rxbuf;
@@ -560,6 +550,7 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
 		shinfo = &rxb->shinfo;
 
-		if (rte_mbuf_ext_refcnt_update(shinfo, 1) == 1)
-			++hv->rxbuf_outstanding;
+		/* shinfo is already set to 1 by the caller */
+		if (rte_mbuf_ext_refcnt_update(shinfo, 1) == 2)
+			rte_atomic32_inc(&hv->rxbuf_outstanding);
 
 		rte_pktmbuf_attach_extbuf(m, data, iova,
@@ -793,5 +784,6 @@ hn_nvs_handle_rxbuf(struct rte_eth_dev *dev,
 
 	/* Send ACK now if external mbuf not used */
-	hn_rx_buf_release(rxb);
+	if (rte_mbuf_ext_refcnt_update(&rxb->shinfo, -1) == 0)
+		hn_nvs_ack_rxbuf(rxb->chan, rxb->xactid);
 }
 
diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h
index 5dcd53638a..34cd11d641 100644
--- a/drivers/net/netvsc/hn_var.h
+++ b/drivers/net/netvsc/hn_var.h
@@ -112,5 +112,5 @@ struct hn_data {
 	struct hn_rx_bufinfo *rxbuf_info;
 	uint32_t	rxbuf_section_cnt;	/* # of Rx sections */
-	volatile uint32_t rxbuf_outstanding;
+	rte_atomic32_t	rxbuf_outstanding;
 	uint16_t	max_queues;		/* Max available queues */
 	uint16_t	num_queues;
-- 
2.26.2

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2020-08-20 16:26:16.760344814 +0100
+++ 0026-net-netvsc-fix-underflow-when-Rx-external-mbuf.patch	2020-08-20 16:26:15.811324206 +0100
@@ -1 +1 @@
-From d43b8c710836db953fad1bb6449a827e19b5a87a Mon Sep 17 00:00:00 2001
+From 77cf88c0c6a69b720007ec5a683b389b1e253a20 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit d43b8c710836db953fad1bb6449a827e19b5a87a ]
+
@@ -16 +17,0 @@
-Cc: stable at dpdk.org
@@ -27 +28 @@
-index 477202b2a0..f88854dafc 100644
+index 76a7281f1b..f97bb10846 100644
@@ -37 +38 @@
-index 6a52885d58..cc4ced37aa 100644
+index b526b490b2..d7940b8119 100644
@@ -40 +41 @@
-@@ -520,22 +520,11 @@ next:
+@@ -489,22 +489,11 @@ next:
@@ -68 +69 @@
-@@ -577,5 +566,6 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
+@@ -546,5 +535,6 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
@@ -76 +77 @@
-@@ -591,6 +581,7 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
+@@ -560,6 +550,7 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
@@ -86 +87 @@
-@@ -833,5 +824,6 @@ hn_nvs_handle_rxbuf(struct rte_eth_dev *dev,
+@@ -793,5 +784,6 @@ hn_nvs_handle_rxbuf(struct rte_eth_dev *dev,
@@ -95 +96 @@
-index 881832d857..7cb7713e93 100644
+index 5dcd53638a..34cd11d641 100644
@@ -98 +99 @@
-@@ -114,5 +114,5 @@ struct hn_data {
+@@ -112,5 +112,5 @@ struct hn_data {



More information about the stable mailing list