[dpdk-stable] patch 'net/netvsc: fix VF support with secondary process' has been queued to LTS release 18.11.2

Kevin Traynor ktraynor at redhat.com
Thu Apr 25 17:39:39 CEST 2019


Hi,

FYI, your patch has been queued to LTS release 18.11.2

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 05/01/19. 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 can be viewed on the 18.11 branch at:
	https://github.com/kevintraynor/dpdk-stable-queue.git

Thanks.

Kevin Traynor

---
>From 7d8bb5bf17ab230c58aad1e8a046e0514190442c Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <sthemmin at microsoft.com>
Date: Thu, 7 Feb 2019 19:44:02 -0800
Subject: [PATCH] net/netvsc: fix VF support with secondary process

[ upstream commit 4a9efcddaddd2477d370f3720bf93079717c6ddb ]

The VF device management in netvsc was using a pointer to the
rte_eth_devices. But the actual rte_eth_devices array is likely to
be place in the secondary process; which causes a crash.

The solution is to record the port of the VF (instead of a pointer)
and find the device in the per process array as needed.

Fixes: dc7680e8597c ("net/netvsc: support integrated VF")

Signed-off-by: Stephen Hemminger <sthemmin at microsoft.com>
---
 drivers/net/netvsc/hn_ethdev.c |  3 +-
 drivers/net/netvsc/hn_rxtx.c   |  8 ++--
 drivers/net/netvsc/hn_var.h    | 32 +++++++++++--
 drivers/net/netvsc/hn_vf.c     | 84 +++++++++++++++++-----------------
 4 files changed, 77 insertions(+), 50 deletions(-)

diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index da76b0db6..fad209f21 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -734,4 +734,5 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
 	hv->latency = HN_CHAN_LATENCY_NS;
 	hv->max_queues = 1;
+	hv->vf_port = HN_INVALID_PORT;
 
 	err = hn_parse_args(eth_dev);
@@ -787,5 +788,5 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
 
 	/* If VF was reported but not added, do it now */
-	if (hv->vf_present && !hv->vf_dev) {
+	if (hv->vf_present && !hn_vf_attached(hv)) {
 		PMD_INIT_LOG(DEBUG, "Adding VF device");
 
diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c
index 487f76466..96b7f1855 100644
--- a/drivers/net/netvsc/hn_rxtx.c
+++ b/drivers/net/netvsc/hn_rxtx.c
@@ -1306,6 +1306,6 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 
 	/* Transmit over VF if present and up */
-	vf_dev = hv->vf_dev;
-	rte_compiler_barrier();
+	vf_dev = hn_get_vf_dev(hv);
+
 	if (vf_dev && vf_dev->data->dev_started) {
 		void *sub_q = vf_dev->data->tx_queues[queue_id];
@@ -1397,6 +1397,6 @@ hn_recv_pkts(void *prxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		return 0;
 
-	vf_dev = hv->vf_dev;
-	rte_compiler_barrier();
+	/* Transmit over VF if present and up */
+	vf_dev = hn_get_vf_dev(hv);
 
 	if (vf_dev && vf_dev->data->dev_started) {
diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h
index a6516c1e6..b31563435 100644
--- a/drivers/net/netvsc/hn_var.h
+++ b/drivers/net/netvsc/hn_var.h
@@ -92,12 +92,16 @@ struct hn_rx_bufinfo {
 } __rte_cache_aligned;
 
+#define HN_INVALID_PORT	UINT16_MAX
+
 struct hn_data {
 	struct rte_vmbus_device *vmbus;
 	struct hn_rx_queue *primary;
-	struct rte_eth_dev *vf_dev;		/* Subordinate device */
 	rte_spinlock_t  vf_lock;
 	uint16_t	port_id;
-	bool		closed;
-	bool		vf_present;
+	uint16_t	vf_port;
+
+	uint8_t		vf_present;
+	uint8_t		closed;
+
 	uint32_t	link_status;
 	uint32_t	link_speed;
@@ -170,4 +174,26 @@ int	hn_dev_rx_queue_setup(struct rte_eth_dev *dev,
 void	hn_dev_rx_queue_release(void *arg);
 
+/* Check if VF is attached */
+static inline bool
+hn_vf_attached(const struct hn_data *hv)
+{
+	return hv->vf_port != HN_INVALID_PORT;
+}
+
+/* Get VF device for existing netvsc device */
+static inline struct rte_eth_dev *
+hn_get_vf_dev(const struct hn_data *hv)
+{
+	uint16_t vf_port = hv->vf_port;
+
+	/* make sure vf_port is loaded */
+	rte_smp_rmb();
+
+	if (vf_port == HN_INVALID_PORT)
+		return NULL;
+	else
+		return &rte_eth_devices[vf_port];
+}
+
 void	hn_vf_info_get(struct hn_data *hv,
 		       struct rte_eth_dev_info *info);
diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c
index 3f714ec99..de278eb7b 100644
--- a/drivers/net/netvsc/hn_vf.c
+++ b/drivers/net/netvsc/hn_vf.c
@@ -52,13 +52,18 @@ static int hn_vf_match(const struct rte_eth_dev *dev)
 }
 
+
 /*
  * Attach new PCI VF device and return the port_id
  */
-static int hn_vf_attach(struct hn_data *hv, uint16_t port_id,
-			struct rte_eth_dev **vf_dev)
+static int hn_vf_attach(struct hn_data *hv, uint16_t port_id)
 {
 	struct rte_eth_dev_owner owner = { .id = RTE_ETH_DEV_NO_OWNER };
 	int ret;
 
+	if (hn_vf_attached(hv)) {
+		PMD_DRV_LOG(ERR, "VF already attached");
+		return -EEXIST;
+	}
+
 	ret = rte_eth_dev_owner_get(port_id, &owner);
 	if (ret < 0) {
@@ -80,6 +85,7 @@ static int hn_vf_attach(struct hn_data *hv, uint16_t port_id,
 
 	PMD_DRV_LOG(DEBUG, "Attach VF device %u", port_id);
+	hv->vf_port = port_id;
 	rte_smp_wmb();
-	*vf_dev = &rte_eth_devices[port_id];
+
 	return 0;
 }
@@ -97,10 +103,5 @@ int hn_vf_add(struct rte_eth_dev *dev, struct hn_data *hv)
 
 	rte_spinlock_lock(&hv->vf_lock);
-	if (hv->vf_dev) {
-		PMD_DRV_LOG(ERR, "VF already attached");
-		err = -EBUSY;
-	} else {
-		err = hn_vf_attach(hv, port, &hv->vf_dev);
-	}
+	err = hn_vf_attach(hv, port);
 
 	if (err == 0) {
@@ -121,20 +122,20 @@ int hn_vf_add(struct rte_eth_dev *dev, struct hn_data *hv)
 static void hn_vf_remove(struct hn_data *hv)
 {
-	struct rte_eth_dev *vf_dev;
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
-	if (!vf_dev) {
+
+	if (!hn_vf_attached(hv)) {
 		PMD_DRV_LOG(ERR, "VF path not active");
-		rte_spinlock_unlock(&hv->vf_lock);
-		return;
+	} else {
+		/* Stop incoming packets from arriving on VF */
+		hn_nvs_set_datapath(hv, NVS_DATAPATH_SYNTHETIC);
+
+		/* Stop transmission over VF */
+		hv->vf_port = HN_INVALID_PORT;
+		rte_smp_wmb();
+
+		/* Give back ownership */
+		rte_eth_dev_owner_unset(hv->vf_port, hv->owner.id);
 	}
-
-	/* Stop incoming packets from arriving on VF */
-	hn_nvs_set_datapath(hv, NVS_DATAPATH_SYNTHETIC);
-	hv->vf_dev = NULL;
-
-	/* Give back ownership */
-	rte_eth_dev_owner_unset(vf_dev->data->port_id, hv->owner.id);
 	rte_spinlock_unlock(&hv->vf_lock);
 }
@@ -208,5 +209,5 @@ void hn_vf_info_get(struct hn_data *hv, struct rte_eth_dev_info *info)
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev)
 		hn_vf_info_merge(vf_dev, info);
@@ -222,5 +223,5 @@ int hn_vf_link_update(struct rte_eth_dev *dev,
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev && vf_dev->dev_ops->link_update)
 		ret = (*vf_dev->dev_ops->link_update)(vf_dev, wait_to_complete);
@@ -250,11 +251,12 @@ static int hn_vf_lsc_event(uint16_t port_id __rte_unused,
 
 static int _hn_vf_configure(struct rte_eth_dev *dev,
-			    struct rte_eth_dev *vf_dev,
+			    uint16_t vf_port,
 			    const struct rte_eth_conf *dev_conf)
 {
 	struct rte_eth_conf vf_conf = *dev_conf;
-	uint16_t vf_port = vf_dev->data->port_id;
+	struct rte_eth_dev *vf_dev;
 	int ret;
 
+	vf_dev = &rte_eth_devices[vf_port];
 	if (dev_conf->intr_conf.lsc &&
 	    (vf_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)) {
@@ -295,11 +297,9 @@ int hn_vf_configure(struct rte_eth_dev *dev,
 {
 	struct hn_data *hv = dev->data->dev_private;
-	struct rte_eth_dev *vf_dev;
 	int ret = 0;
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
-	if (vf_dev)
-		ret = _hn_vf_configure(dev, vf_dev, dev_conf);
+	if (hv->vf_port != HN_INVALID_PORT)
+		ret = _hn_vf_configure(dev, hv->vf_port, dev_conf);
 	rte_spinlock_unlock(&hv->vf_lock);
 	return ret;
@@ -313,5 +313,5 @@ const uint32_t *hn_vf_supported_ptypes(struct rte_eth_dev *dev)
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev && vf_dev->dev_ops->dev_supported_ptypes_get)
 		ptypes = (*vf_dev->dev_ops->dev_supported_ptypes_get)(vf_dev);
@@ -328,5 +328,5 @@ int hn_vf_start(struct rte_eth_dev *dev)
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev)
 		ret = rte_eth_dev_start(vf_dev->data->port_id);
@@ -341,5 +341,5 @@ void hn_vf_stop(struct rte_eth_dev *dev)
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev)
 		rte_eth_dev_stop(vf_dev->data->port_id);
@@ -353,5 +353,5 @@ void hn_vf_stop(struct rte_eth_dev *dev)
 		struct rte_eth_dev *vf_dev;			\
 		rte_spinlock_lock(&hv->vf_lock);		\
-		vf_dev = hv->vf_dev;				\
+		vf_dev = hn_get_vf_dev(hv);			\
 		if (vf_dev)					\
 			func(vf_dev->data->port_id);		\
@@ -403,5 +403,5 @@ int hn_vf_mc_addr_list(struct rte_eth_dev *dev,
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev)
 		ret = rte_eth_dev_set_mc_addr_list(vf_dev->data->port_id,
@@ -421,5 +421,5 @@ int hn_vf_tx_queue_setup(struct rte_eth_dev *dev,
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev)
 		ret = rte_eth_tx_queue_setup(vf_dev->data->port_id,
@@ -435,5 +435,5 @@ void hn_vf_tx_queue_release(struct hn_data *hv, uint16_t queue_id)
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev && vf_dev->dev_ops->tx_queue_release) {
 		void *subq = vf_dev->data->tx_queues[queue_id];
@@ -456,5 +456,5 @@ int hn_vf_rx_queue_setup(struct rte_eth_dev *dev,
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev)
 		ret = rte_eth_rx_queue_setup(vf_dev->data->port_id,
@@ -470,5 +470,5 @@ void hn_vf_rx_queue_release(struct hn_data *hv, uint16_t queue_id)
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev && vf_dev->dev_ops->rx_queue_release) {
 		void *subq = vf_dev->data->rx_queues[queue_id];
@@ -487,5 +487,5 @@ int hn_vf_stats_get(struct rte_eth_dev *dev,
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev)
 		ret = rte_eth_stats_get(vf_dev->data->port_id, stats);
@@ -504,5 +504,5 @@ int hn_vf_xstats_get_names(struct rte_eth_dev *dev,
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev && vf_dev->dev_ops->xstats_get_names)
 		count = vf_dev->dev_ops->xstats_get_names(vf_dev, names, n);
@@ -529,5 +529,5 @@ int hn_vf_xstats_get(struct rte_eth_dev *dev,
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev && vf_dev->dev_ops->xstats_get)
 		count = vf_dev->dev_ops->xstats_get(vf_dev, xstats, n);
@@ -543,5 +543,5 @@ void hn_vf_xstats_reset(struct rte_eth_dev *dev)
 
 	rte_spinlock_lock(&hv->vf_lock);
-	vf_dev = hv->vf_dev;
+	vf_dev = hn_get_vf_dev(hv);
 	if (vf_dev && vf_dev->dev_ops->xstats_reset)
 		vf_dev->dev_ops->xstats_reset(vf_dev);
-- 
2.20.1

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2019-04-25 16:37:46.946037156 +0100
+++ 0004-net-netvsc-fix-VF-support-with-secondary-process.patch	2019-04-25 16:37:46.683296367 +0100
@@ -1 +1 @@
-From 4a9efcddaddd2477d370f3720bf93079717c6ddb Mon Sep 17 00:00:00 2001
+From 7d8bb5bf17ab230c58aad1e8a046e0514190442c Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 4a9efcddaddd2477d370f3720bf93079717c6ddb ]
+
@@ -14 +15,0 @@
-Cc: stable at dpdk.org
@@ -20 +21 @@
- drivers/net/netvsc/hn_var.h    | 30 +++++++++++-
+ drivers/net/netvsc/hn_var.h    | 32 +++++++++++--
@@ -22 +23 @@
- 4 files changed, 76 insertions(+), 49 deletions(-)
+ 4 files changed, 77 insertions(+), 50 deletions(-)
@@ -25 +26 @@
-index 49b7ca7b2..407ee4849 100644
+index da76b0db6..fad209f21 100644
@@ -28 +29 @@
-@@ -736,4 +736,5 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
+@@ -734,4 +734,5 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
@@ -34 +35 @@
-@@ -789,5 +790,5 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
+@@ -787,5 +788,5 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
@@ -42 +43 @@
-index 6197118b0..fecd69887 100644
+index 487f76466..96b7f1855 100644
@@ -45 +46 @@
-@@ -1314,6 +1314,6 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+@@ -1306,6 +1306,6 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -54 +55 @@
-@@ -1405,6 +1405,6 @@ hn_recv_pkts(void *prxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+@@ -1397,6 +1397,6 @@ hn_recv_pkts(void *prxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
@@ -64 +65 @@
-index 7f3266c45..8383f3246 100644
+index a6516c1e6..b31563435 100644
@@ -67 +68 @@
-@@ -92,13 +92,17 @@ struct hn_rx_bufinfo {
+@@ -92,12 +92,16 @@ struct hn_rx_bufinfo {
@@ -78 +79,2 @@
--	uint8_t		closed;
+-	bool		closed;
+-	bool		vf_present;
@@ -81 +83 @@
- 	uint8_t		vf_present;
++	uint8_t		vf_present;
@@ -83 +84,0 @@
- 	uint8_t		vlan_strip;
@@ -87 +88 @@
-@@ -171,4 +175,26 @@ int	hn_dev_rx_queue_setup(struct rte_eth_dev *dev,
+@@ -170,4 +174,26 @@ int	hn_dev_rx_queue_setup(struct rte_eth_dev *dev,


More information about the stable mailing list