[dpdk-stable] patch 'net/netvsc: fix multiple channel Rx' has been queued to LTS release 18.11.11

Kevin Traynor ktraynor at redhat.com
Thu Nov 5 13:39:10 CET 2020


Hi,

FYI, your patch has been queued to LTS release 18.11.11

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 11/10/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/5c72d08cb81031f228851f5cf2e72d93022ed5de

Thanks.

Kevin.

---
>From 5c72d08cb81031f228851f5cf2e72d93022ed5de Mon Sep 17 00:00:00 2001
From: Long Li <longli at microsoft.com>
Date: Mon, 10 Aug 2020 19:33:11 -0700
Subject: [PATCH] net/netvsc: fix multiple channel Rx

[ upstream commit ac837bdd22400b220d60336f22c18091a92a40c9 ]

netvsc uses rxbuf_info buffer to track received packets attached via
rte_pktmbuf_attach_extbuf() and ack the host based on usage count. It
uses the transaction_id in the VMBus packet to locate where to use
memory in the rxbuf_info.

This is not correct in multiple channel setup, as different channels may
return identical transaction_ids at a time, and may corrupt the
rxbuf_info buffer.

Fix this by defining rxbuf_info for each queue.

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  | 13 +++++++++----
 drivers/net/netvsc/hn_rxtx.c | 33 ++++++++++++++++++++++++++-------
 drivers/net/netvsc/hn_var.h  |  6 +++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/drivers/net/netvsc/hn_nvs.c b/drivers/net/netvsc/hn_nvs.c
index f97bb10846..78ebb954f4 100644
--- a/drivers/net/netvsc/hn_nvs.c
+++ b/drivers/net/netvsc/hn_nvs.c
@@ -224,7 +224,13 @@ hn_nvs_conn_rxbuf(struct hn_data *hv)
 	hv->rxbuf_section_cnt = resp.nvs_sect[0].slotcnt;
 
-	hv->rxbuf_info = rte_calloc("HN_RXBUF_INFO", hv->rxbuf_section_cnt,
-				    sizeof(*hv->rxbuf_info), RTE_CACHE_LINE_SIZE);
-	if (!hv->rxbuf_info) {
+	/*
+	 * Pimary queue's rxbuf_info is not allocated at creation time.
+	 * Now we can allocate it after we figure out the slotcnt.
+	 */
+	hv->primary->rxbuf_info = rte_calloc("HN_RXBUF_INFO",
+			hv->rxbuf_section_cnt,
+			sizeof(*hv->primary->rxbuf_info),
+			RTE_CACHE_LINE_SIZE);
+	if (!hv->primary->rxbuf_info) {
 		PMD_DRV_LOG(ERR,
 			    "could not allocate rxbuf info");
@@ -256,5 +262,4 @@ hn_nvs_disconn_rxbuf(struct hn_data *hv)
 	}
 
-	rte_free(hv->rxbuf_info);
 	/*
 	 * Linger long enough for NVS to disconnect RXBUF.
diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c
index c6506e442d..5d580f6f7f 100644
--- a/drivers/net/netvsc/hn_rxtx.c
+++ b/drivers/net/netvsc/hn_rxtx.c
@@ -494,19 +494,19 @@ static void hn_rx_buf_free_cb(void *buf __rte_unused, void *opaque)
 {
 	struct hn_rx_bufinfo *rxb = opaque;
-	struct hn_data *hv = rxb->hv;
+	struct hn_rx_queue *rxq = rxb->rxq;
 
-	rte_atomic32_dec(&hv->rxbuf_outstanding);
+	rte_atomic32_dec(&rxq->rxbuf_outstanding);
 	hn_nvs_ack_rxbuf(rxb->chan, rxb->xactid);
 }
 
-static struct hn_rx_bufinfo *hn_rx_buf_init(const struct hn_rx_queue *rxq,
+static struct hn_rx_bufinfo *hn_rx_buf_init(struct hn_rx_queue *rxq,
 					    const struct vmbus_chanpkt_rxbuf *pkt)
 {
 	struct hn_rx_bufinfo *rxb;
 
-	rxb = rxq->hv->rxbuf_info + pkt->hdr.xactid;
+	rxb = rxq->rxbuf_info + pkt->hdr.xactid;
 	rxb->chan = rxq->chan;
 	rxb->xactid = pkt->hdr.xactid;
-	rxb->hv = rxq->hv;
+	rxb->rxq = rxq;
 
 	rxb->shinfo.free_cb = hn_rx_buf_free_cb;
@@ -537,5 +537,5 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
 	 */
 	if (dlen >= HN_RXCOPY_THRESHOLD &&
-	    (uint32_t)rte_atomic32_read(&hv->rxbuf_outstanding) <
+	    (uint32_t)rte_atomic32_read(&rxq->rxbuf_outstanding) <
 			hv->rxbuf_section_cnt / 2) {
 		struct rte_mbuf_ext_shared_info *shinfo;
@@ -554,5 +554,5 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
 		/* 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_atomic32_inc(&rxq->rxbuf_outstanding);
 
 		rte_pktmbuf_attach_extbuf(m, data, iova,
@@ -843,4 +843,21 @@ struct hn_rx_queue *hn_rx_queue_alloc(struct hn_data *hv,
 	}
 
+	/* setup rxbuf_info for non-primary queue */
+	if (queue_id) {
+		rxq->rxbuf_info = rte_calloc("HN_RXBUF_INFO",
+					hv->rxbuf_section_cnt,
+					sizeof(*rxq->rxbuf_info),
+					RTE_CACHE_LINE_SIZE);
+
+		if (!rxq->rxbuf_info) {
+			PMD_DRV_LOG(ERR,
+				"Could not allocate rxbuf info for queue %d\n",
+				queue_id);
+			rte_free(rxq->event_buf);
+			rte_free(rxq);
+			return NULL;
+		}
+	}
+
 	return rxq;
 }
@@ -897,4 +914,5 @@ hn_dev_rx_queue_setup(struct rte_eth_dev *dev,
 fail:
 	rte_ring_free(rxq->rx_ring);
+	rte_free(rxq->rxbuf_info);
 	rte_free(rxq->event_buf);
 	rte_free(rxq);
@@ -920,4 +938,5 @@ hn_dev_rx_queue_release(void *arg)
 	/* Keep primary queue to allow for control operations */
 	if (rxq != rxq->hv->primary) {
+		rte_free(rxq->rxbuf_info);
 		rte_free(rxq->event_buf);
 		rte_free(rxq);
diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h
index 34cd11d641..fceb345099 100644
--- a/drivers/net/netvsc/hn_var.h
+++ b/drivers/net/netvsc/hn_var.h
@@ -83,4 +83,6 @@ struct hn_rx_queue {
 
 	void *event_buf;
+	struct hn_rx_bufinfo *rxbuf_info;
+	rte_atomic32_t  rxbuf_outstanding;
 };
 
@@ -89,5 +91,5 @@ struct hn_rx_queue {
 struct hn_rx_bufinfo {
 	struct vmbus_channel *chan;
-	struct hn_data *hv;
+	struct hn_rx_queue *rxq;
 	uint64_t	xactid;
 	struct rte_mbuf_ext_shared_info shinfo;
@@ -110,7 +112,5 @@ struct hn_data {
 
 	struct rte_mem_resource *rxbuf_res;	/* UIO resource for Rx */
-	struct hn_rx_bufinfo *rxbuf_info;
 	uint32_t	rxbuf_section_cnt;	/* # of Rx sections */
-	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-11-05 12:38:54.331318590 +0000
+++ 0003-net-netvsc-fix-multiple-channel-Rx.patch	2020-11-05 12:38:54.143895944 +0000
@@ -1 +1 @@
-From ac837bdd22400b220d60336f22c18091a92a40c9 Mon Sep 17 00:00:00 2001
+From 5c72d08cb81031f228851f5cf2e72d93022ed5de Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit ac837bdd22400b220d60336f22c18091a92a40c9 ]
+
@@ -18 +19,0 @@
-Cc: stable at dpdk.org
@@ -29 +30 @@
-index f88854dafc..eeb82ab9ee 100644
+index f97bb10846..78ebb954f4 100644
@@ -56 +57 @@
-index 87b1184bc1..c8c4ee10c8 100644
+index c6506e442d..5d580f6f7f 100644
@@ -59 +60 @@
-@@ -525,19 +525,19 @@ static void hn_rx_buf_free_cb(void *buf __rte_unused, void *opaque)
+@@ -494,19 +494,19 @@ static void hn_rx_buf_free_cb(void *buf __rte_unused, void *opaque)
@@ -84 +85 @@
-@@ -569,5 +569,5 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
+@@ -537,5 +537,5 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
@@ -91 +92 @@
-@@ -586,5 +586,5 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
+@@ -554,5 +554,5 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
@@ -98 +99 @@
-@@ -889,4 +889,21 @@ struct hn_rx_queue *hn_rx_queue_alloc(struct hn_data *hv,
+@@ -843,4 +843,21 @@ struct hn_rx_queue *hn_rx_queue_alloc(struct hn_data *hv,
@@ -120 +121 @@
-@@ -954,4 +971,5 @@ hn_dev_rx_queue_setup(struct rte_eth_dev *dev,
+@@ -897,4 +914,5 @@ hn_dev_rx_queue_setup(struct rte_eth_dev *dev,
@@ -126,6 +127,6 @@
-@@ -976,4 +994,5 @@ hn_rx_queue_free(struct hn_rx_queue *rxq, bool keep_primary)
- 		return;
- 
-+	rte_free(rxq->rxbuf_info);
- 	rte_free(rxq->event_buf);
- 	rte_free(rxq);
+@@ -920,4 +938,5 @@ hn_dev_rx_queue_release(void *arg)
+ 	/* Keep primary queue to allow for control operations */
+ 	if (rxq != rxq->hv->primary) {
++		rte_free(rxq->rxbuf_info);
+ 		rte_free(rxq->event_buf);
+ 		rte_free(rxq);
@@ -133 +134 @@
-index 7cb7713e93..4b63f87607 100644
+index 34cd11d641..fceb345099 100644
@@ -136 +137 @@
-@@ -84,4 +84,6 @@ struct hn_rx_queue {
+@@ -83,4 +83,6 @@ struct hn_rx_queue {
@@ -143 +144 @@
-@@ -90,5 +92,5 @@ struct hn_rx_queue {
+@@ -89,5 +91,5 @@ struct hn_rx_queue {
@@ -150 +151 @@
-@@ -112,7 +114,5 @@ struct hn_data {
+@@ -110,7 +112,5 @@ struct hn_data {



More information about the stable mailing list