From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id AA5B3A05D3 for ; Thu, 25 Apr 2019 17:40:52 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 956031B5CF; Thu, 25 Apr 2019 17:40:52 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id CBFFF1B5CD for ; Thu, 25 Apr 2019 17:40:50 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3A95188AD5; Thu, 25 Apr 2019 15:40:49 +0000 (UTC) Received: from rh.redhat.com (unknown [10.36.116.255]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5B41B5D9CC; Thu, 25 Apr 2019 15:40:48 +0000 (UTC) From: Kevin Traynor To: Stephen Hemminger Cc: dpdk stable Date: Thu, 25 Apr 2019 16:39:39 +0100 Message-Id: <20190425154037.28778-4-ktraynor@redhat.com> In-Reply-To: <20190425154037.28778-1-ktraynor@redhat.com> References: <20190425154037.28778-1-ktraynor@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 25 Apr 2019 15:40:49 +0000 (UTC) Subject: [dpdk-stable] patch 'net/netvsc: fix VF support with secondary process' has been queued to LTS release 18.11.2 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" 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 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 --- 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@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,