From patchwork Wed May 18 17:10:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ferruh Yigit X-Patchwork-Id: 12883 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 54141694A; Wed, 18 May 2016 19:10:31 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 86DB06936 for ; Wed, 18 May 2016 19:10:29 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga104.fm.intel.com with ESMTP; 18 May 2016 10:10:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,329,1459839600"; d="scan'208";a="983863275" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga002.fm.intel.com with ESMTP; 18 May 2016 10:10:25 -0700 Received: from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com [10.237.217.46]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id u4IHAOdb002202; Wed, 18 May 2016 18:10:24 +0100 Received: from sivswdev02.ir.intel.com (localhost [127.0.0.1]) by sivswdev02.ir.intel.com with ESMTP id u4IHAO9K025446; Wed, 18 May 2016 18:10:24 +0100 Received: (from fyigit@localhost) by sivswdev02.ir.intel.com with id u4IHAN9x025442; Wed, 18 May 2016 18:10:23 +0100 From: Ferruh Yigit To: dev@dpdk.org Cc: Tetsuya Mukawa , Yuanhan Liu , Ferruh Yigit Date: Wed, 18 May 2016 18:10:22 +0100 Message-Id: <1463591422-25408-1-git-send-email-ferruh.yigit@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <20160509213124.GK5641@yliu-dev.sh.intel.com> References: <20160509213124.GK5641@yliu-dev.sh.intel.com> Subject: [dpdk-dev] [PATCH v2] vhost: add support for dynamic vhost PMD creation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add rte_eth_from_vhost() API to create vhost PMD dynamically from applications. Signed-off-by: Ferruh Yigit --- v2: * drop rte_ prefix from non-public function * re-use eth_rx_queue_setup/eth_tx_queue_setup * pass vdev options as parameter to API --- drivers/net/vhost/rte_eth_vhost.c | 130 ++++++++++++++++++++++++++++ drivers/net/vhost/rte_eth_vhost.h | 26 ++++++ drivers/net/vhost/rte_pmd_vhost_version.map | 7 ++ 3 files changed, 163 insertions(+) diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c index 310cbef..8019eb1 100644 --- a/drivers/net/vhost/rte_eth_vhost.c +++ b/drivers/net/vhost/rte_eth_vhost.c @@ -796,6 +796,79 @@ error: return -1; } +static int +eth_from_vhost_create(const char *name, char *iface_name, uint16_t nb_queues, + const unsigned int numa_node, struct rte_mempool *mb_pool) +{ + struct rte_eth_dev_data *data = NULL; + struct pmd_internal *internal = NULL; + struct rte_eth_dev *dev = NULL; + struct internal_list *list; + int port_id; + int ret; + int i; + + port_id = eth_dev_vhost_create(name, iface_name, nb_queues, numa_node); + if (port_id < 0) + return -1; + + dev = &rte_eth_devices[port_id]; + data = dev->data; + + data->rx_queues = rte_zmalloc_socket(name, sizeof(void *) * nb_queues, + 0, numa_node); + if (data->rx_queues == NULL) + goto error; + + data->tx_queues = rte_zmalloc_socket(name, sizeof(void *) * nb_queues, + 0, numa_node); + if (data->tx_queues == NULL) + goto error; + + for (i = 0; i < nb_queues; i++) { + ret = eth_rx_queue_setup(dev, i, 0, numa_node, NULL, mb_pool); + if (ret < 0) + goto error; + } + + for (i = 0; i < nb_queues; i++) { + ret = eth_tx_queue_setup(dev, i, 0, numa_node, NULL); + if (ret < 0) + goto error; + } + + return port_id; + +error: + internal = data->dev_private; + list = find_internal_resource(internal->iface_name); + + pthread_mutex_lock(&internal_list_lock); + TAILQ_REMOVE(&internal_list, list, next); + pthread_mutex_unlock(&internal_list_lock); + + if (internal) + free(internal->dev_name); + free(vring_states[port_id]); + free(data->mac_addrs); + rte_eth_dev_release_port(dev); + if (data->rx_queues) { + for (i = 0; i < nb_queues; i++) + free(data->rx_queues[i]); + rte_free(data->rx_queues); + } + if (data->tx_queues) { + for (i = 0; i < nb_queues; i++) + free(data->tx_queues[i]); + rte_free(data->tx_queues); + } + rte_free(internal); + rte_free(list); + rte_free(data); + + return -1; +} + static inline int open_iface(const char *key __rte_unused, const char *value, void *extra_args) { @@ -827,6 +900,63 @@ open_queues(const char *key __rte_unused, const char *value, void *extra_args) return 0; } +int +rte_eth_from_vhost(const char *name, char *iface_name_arg, + const unsigned int numa_node, struct rte_mempool *mb_pool, + const char *params) +{ + char *iface_name = iface_name_arg; + struct rte_kvargs *kvlist = NULL; + uint16_t queues = 1; + int port_id; + int ret; + + if (!name || !mb_pool) + return -1; + + if (params) { + kvlist = rte_kvargs_parse(params, valid_arguments); + if (kvlist == NULL) + return -1; + + if (rte_kvargs_count(kvlist, ETH_VHOST_IFACE_ARG) == 1) { + ret = rte_kvargs_process(kvlist, ETH_VHOST_IFACE_ARG, + &open_iface, &iface_name); + if (ret < 0) { + rte_kvargs_free(kvlist); + return ret; + } + } + + if (rte_kvargs_count(kvlist, ETH_VHOST_QUEUES_ARG) == 1) { + ret = rte_kvargs_process(kvlist, ETH_VHOST_QUEUES_ARG, + &open_queues, &queues); + if (ret < 0) { + rte_kvargs_free(kvlist); + return ret; + } + } + } + + if (!iface_name || !queues) + return -1; + + port_id = eth_from_vhost_create(name, iface_name, queues, numa_node, + mb_pool); + if (port_id < 0) + return port_id; + + ret = rte_vhost_driver_register(iface_name); + if (ret < 0) + return ret; + + ret = vhost_driver_session_start(); + if (ret < 0) + return ret; + + return port_id; +} + static int rte_pmd_vhost_devinit(const char *name, const char *params) { diff --git a/drivers/net/vhost/rte_eth_vhost.h b/drivers/net/vhost/rte_eth_vhost.h index ff5d877..480dac8 100644 --- a/drivers/net/vhost/rte_eth_vhost.h +++ b/drivers/net/vhost/rte_eth_vhost.h @@ -102,6 +102,32 @@ struct rte_eth_vhost_queue_event { int rte_eth_vhost_get_queue_event(uint8_t port_id, struct rte_eth_vhost_queue_event *event); +/** + * Create a new ethdev from vhost device + * + * @param name + * Name to be given to the new ethdev + * @param iface_name + * Specifies a path to connect to a QEMU virtio-net device + * @param numa_node + * The numa node on which the memory for this port is to be allocated + * @param mb_pool + * Memory pool used by created ethdev + * @param params + * Optional argument list, supported arguments: + * iface : iface_name, + * queues: number of rx/tx queues [default to 1] + * These values can override direct API params when conflict. + * sample params="iface=/tmp/sock0,queues=1" + * + * @return + * - On success, created ehtdev port_id. + * - On failure, a negative value. + */ +int rte_eth_from_vhost(const char *name, char *iface_name_arg, + const unsigned int numa_node, struct rte_mempool *mb_pool, + const char *params); + #ifdef __cplusplus } #endif diff --git a/drivers/net/vhost/rte_pmd_vhost_version.map b/drivers/net/vhost/rte_pmd_vhost_version.map index 65bf3a8..bb2fe29 100644 --- a/drivers/net/vhost/rte_pmd_vhost_version.map +++ b/drivers/net/vhost/rte_pmd_vhost_version.map @@ -8,3 +8,10 @@ DPDK_16.04 { local: *; }; + +DPDK_16.07 { + global: + + rte_eth_from_vhost; + +} DPDK_16.04;