From patchwork Fri Mar 30 06:58:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: junjie.j.chen@intel.com X-Patchwork-Id: 36766 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8090D2C12; Fri, 30 Mar 2018 08:59:25 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id AB90D1D7 for ; Fri, 30 Mar 2018 08:59:23 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Mar 2018 23:59:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,380,1517904000"; d="scan'208";a="42570235" Received: from cjj-s2600wft.sh.intel.com ([10.67.111.131]) by fmsmga001.fm.intel.com with ESMTP; 29 Mar 2018 23:59:20 -0700 From: Junjie Chen To: jianfeng.tan@intel.com, maxime.coquelin@redhat.com, mtetsuyah@gmail.com Cc: dev@dpdk.org, Junjie Chen , Chen@dpdk.org Date: Fri, 30 Mar 2018 14:58:31 +0800 Message-Id: <20180330065831.107558-1-junjie.j.chen@intel.com> X-Mailer: git-send-email 2.16.0 In-Reply-To: <20180329153544.270488-1-junjie.j.chen@intel.com> References: <20180329153544.270488-1-junjie.j.chen@intel.com> Subject: [dpdk-dev] [PATCH v3] net/vhost: fix segfault when creating vdev dynamically X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" When creating vdev dynamically, vhost pmd driver starts directly without checking TX/RX queues are ready or not, and thus causes segmentation fault when vhost library accesses queues. This patch adds a flag to check whether queues are setup or not, and adds queues setup into dev_start function to allow user to start them after setting up. Fixes: aed0b12930b3 ("net/vhost: fix socket file deleted on stop") Signed-off-by: Chen, Junjie Tested-by: Zhiyong Yang Reviewed-by: Maxime Coquelin --- Changes in v3: - Update commit log, refine duplicated code Changes in v2: - Check queues status in new_device, create queue in dev_start if not setup yet drivers/net/vhost/rte_eth_vhost.c | 69 ++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c index 3aae01c39..11b607650 100644 --- a/drivers/net/vhost/rte_eth_vhost.c +++ b/drivers/net/vhost/rte_eth_vhost.c @@ -117,6 +117,7 @@ struct pmd_internal { char *dev_name; char *iface_name; uint16_t max_queues; + uint16_t vid; rte_atomic32_t started; }; @@ -527,8 +528,10 @@ update_queuing_status(struct rte_eth_dev *dev) unsigned int i; int allow_queuing = 1; - if (rte_atomic32_read(&internal->started) == 0 || - rte_atomic32_read(&internal->dev_attached) == 0) + if (rte_atomic32_read(&internal->dev_attached) == 0) + return; + + if (rte_atomic32_read(&internal->started) == 0) allow_queuing = 0; /* Wait until rx/tx_pkt_burst stops accessing vhost device */ @@ -551,13 +554,36 @@ update_queuing_status(struct rte_eth_dev *dev) } } +static void +queue_setup(struct rte_eth_dev *eth_dev, struct pmd_internal *internal) +{ + struct vhost_queue *vq; + int i; + + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + vq = eth_dev->data->rx_queues[i]; + if (!vq) + continue; + vq->vid = internal->vid; + vq->internal = internal; + vq->port = eth_dev->data->port_id; + } + for (i = 0; i < eth_dev->data->nb_tx_queues; i++) { + vq = eth_dev->data->tx_queues[i]; + if (!vq) + continue; + vq->vid = internal->vid; + vq->internal = internal; + vq->port = eth_dev->data->port_id; + } +} + static int new_device(int vid) { struct rte_eth_dev *eth_dev; struct internal_list *list; struct pmd_internal *internal; - struct vhost_queue *vq; unsigned i; char ifname[PATH_MAX]; #ifdef RTE_LIBRTE_VHOST_NUMA @@ -580,21 +606,13 @@ new_device(int vid) eth_dev->data->numa_node = newnode; #endif - for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { - vq = eth_dev->data->rx_queues[i]; - if (vq == NULL) - continue; - vq->vid = vid; - vq->internal = internal; - vq->port = eth_dev->data->port_id; - } - for (i = 0; i < eth_dev->data->nb_tx_queues; i++) { - vq = eth_dev->data->tx_queues[i]; - if (vq == NULL) - continue; - vq->vid = vid; - vq->internal = internal; - vq->port = eth_dev->data->port_id; + internal->vid = vid; + if (eth_dev->data->rx_queues && eth_dev->data->tx_queues) { + queue_setup(eth_dev, internal); + rte_atomic32_set(&internal->dev_attached, 1); + } else { + RTE_LOG(INFO, PMD, "RX/TX queues have not setup yet\n"); + rte_atomic32_set(&internal->dev_attached, 0); } for (i = 0; i < rte_vhost_get_vring_num(vid); i++) @@ -604,7 +622,6 @@ new_device(int vid) eth_dev->data->dev_link.link_status = ETH_LINK_UP; - rte_atomic32_set(&internal->dev_attached, 1); update_queuing_status(eth_dev); RTE_LOG(INFO, PMD, "Vhost device %d created\n", vid); @@ -634,8 +651,9 @@ destroy_device(int vid) eth_dev = list->eth_dev; internal = eth_dev->data->dev_private; - rte_atomic32_set(&internal->dev_attached, 0); + rte_atomic32_set(&internal->started, 0); update_queuing_status(eth_dev); + rte_atomic32_set(&internal->dev_attached, 0); eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; @@ -770,12 +788,17 @@ rte_eth_vhost_get_vid_from_port_id(uint16_t port_id) } static int -eth_dev_start(struct rte_eth_dev *dev) +eth_dev_start(struct rte_eth_dev *eth_dev) { - struct pmd_internal *internal = dev->data->dev_private; + struct pmd_internal *internal = eth_dev->data->dev_private; + + if (unlikely(rte_atomic32_read(&internal->dev_attached) == 0)) { + queue_setup(eth_dev, internal); + rte_atomic32_set(&internal->dev_attached, 1); + } rte_atomic32_set(&internal->started, 1); - update_queuing_status(dev); + update_queuing_status(eth_dev); return 0; }