All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] support to run vdev in the secondary process
@ 2017-08-25  9:40 Jianfeng Tan
  2017-08-25  9:40 ` [PATCH 01/12] cryptodev: remove crypto vdev init Jianfeng Tan
                   ` (13 more replies)
  0 siblings, 14 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Patch 1~5: move vdev bus into drivers/bus.
Patch 6: add unix socket channel for primary/secondary communication.
Patch 7~8: make use of the channel to discover and probe virtual devices
         the primary process.
Patch 9~12: support to run vhost-pmd in the secondary process.

How to test:

Step 1: run helloworld as the primary process.
  $ ./helloworld -l 1-2 --vdev 'net_vhost0,iface=/tmp/sock0' --

Step 2: run testpmd as the secondary process.
  $ ./testpmd -l 3-4 --proc-type=secondary -- -i

Step 3: start VM.
  $ ./qemu-system-x86_64 ... -chardev socket,id=chr4,path=/tmp/sock0 ...

Jianfeng Tan (12):
  cryptodev: remove crypto vdev init
  eal: avoid calling rte_vdev_init()
  crypto: move vdev helper functions into dedicated file
  vdev: move to drivers/bus
  bus/vdev: change log type from EAL to PMD
  eal: add channel for primary/secondary communication
  bus/vdev: scan and probe vdev in secondary processes
  ethdev: support attach vdev in secondary process
  vhost: allocate virtio_net in memzone
  vhost: support to kick in secondary process
  net/vhost: support to run in the secondary process
  examples/helloworld: do not exit automatically

 config/common_base                              |   5 +
 doc/guides/rel_notes/deprecation.rst            |   5 -
 drivers/bus/Makefile                            |   2 +
 drivers/bus/vdev/Makefile                       |  57 +++
 drivers/bus/vdev/rte_bus_vdev_version.map       |  10 +
 drivers/bus/vdev/rte_cryptodev_vdev.c           | 154 ++++++++
 drivers/bus/vdev/rte_cryptodev_vdev.h           | 100 ++++++
 drivers/bus/vdev/rte_vdev.h                     | 153 ++++++++
 drivers/bus/vdev/vdev.c                         | 440 +++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                    |  40 +++
 drivers/net/vhost/rte_eth_vhost.c               | 158 ++++++++-
 examples/helloworld/main.c                      |   3 +
 lib/librte_cryptodev/Makefile                   |   1 -
 lib/librte_cryptodev/rte_cryptodev.c            |   6 -
 lib/librte_cryptodev/rte_cryptodev.h            |  18 -
 lib/librte_cryptodev/rte_cryptodev_pmd.c        | 120 -------
 lib/librte_cryptodev/rte_cryptodev_vdev.h       | 100 ------
 lib/librte_cryptodev/rte_cryptodev_version.map  |   1 -
 lib/librte_eal/bsdapp/eal/Makefile              |   1 -
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  21 +-
 lib/librte_eal/common/eal_common_proc.c         | 454 ++++++++++++++++++++++++
 lib/librte_eal/common/eal_common_vdev.c         | 342 ------------------
 lib/librte_eal/common/eal_filesystem.h          |  18 +
 lib/librte_eal/common/eal_private.h             |  10 +
 lib/librte_eal/common/include/rte_dev.h         |  24 +-
 lib/librte_eal/common/include/rte_eal.h         |  74 ++++
 lib/librte_eal/common/include/rte_vdev.h        | 131 -------
 lib/librte_eal/linuxapp/eal/Makefile            |   1 -
 lib/librte_eal/linuxapp/eal/eal.c               |   6 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
 lib/librte_ether/rte_ethdev_vdev.h              |  26 +-
 lib/librte_vhost/rte_vhost.h                    |   3 +
 lib/librte_vhost/socket.c                       |   2 +
 lib/librte_vhost/vhost.c                        |  61 +++-
 lib/librte_vhost/vhost.h                        |   7 +-
 lib/librte_vhost/vhost_user.c                   |   4 +-
 mk/rte.app.mk                                   |   1 +
 39 files changed, 1781 insertions(+), 796 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.c
 create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.h
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH 01/12] cryptodev: remove crypto vdev init
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-09-18 11:48   ` De Lara Guarch, Pablo
  2017-08-25  9:40 ` [PATCH 02/12] eal: avoid calling rte_vdev_init() Jianfeng Tan
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

CC: Pablo de Lara <pablo.de.lara.guarch@intel.com>

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 18 ------------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 4 files changed, 30 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3362f33..665e502 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -96,11 +96,6 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * cryptodev: the following function will be static in 17.11 and included
   by all crypto drivers, therefore, will not be public:
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 327d7e8..12c46a5 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 7ec9c4b..c5d6939 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -49,7 +49,6 @@ extern "C" {
 #include "rte_crypto.h"
 #include "rte_dev.h"
 #include <rte_common.h>
-#include <rte_vdev.h>
 
 extern const char **rte_cyptodev_names;
 
@@ -434,23 +433,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e9ba88a..3b05a4d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 02/12] eal: avoid calling rte_vdev_init()
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
  2017-08-25  9:40 ` [PATCH 01/12] cryptodev: remove crypto vdev init Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-08-29 12:50   ` Gaëtan Rivet
  2017-08-25  9:40 ` [PATCH 03/12] crypto: move vdev helper functions into dedicated file Jianfeng Tan
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..066dfbf 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,12 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") != 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 03/12] crypto: move vdev helper functions into dedicated file
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
  2017-08-25  9:40 ` [PATCH 01/12] cryptodev: remove crypto vdev init Jianfeng Tan
  2017-08-25  9:40 ` [PATCH 02/12] eal: avoid calling rte_vdev_init() Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-09-18 11:51   ` De Lara Guarch, Pablo
  2017-08-25  9:40 ` [PATCH 04/12] vdev: move to drivers/bus Jianfeng Tan
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

---
 lib/librte_cryptodev/Makefile             |   1 +
 lib/librte_cryptodev/rte_cryptodev_pmd.c  | 120 -----------------------
 lib/librte_cryptodev/rte_cryptodev_vdev.c | 154 ++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+), 120 deletions(-)
 create mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.c

diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 6ac331b..301c78d 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -42,6 +42,7 @@ CFLAGS += $(WERROR_FLAGS)
 
 # library source files
 SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c
+SRCS-y += rte_cryptodev_vdev.c
 
 # export include files
 SYMLINK-y-include += rte_crypto.h
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index a57faad..b310f4b 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -32,129 +32,9 @@
 
 #include <rte_malloc.h>
 
-#include "rte_cryptodev_vdev.h"
 #include "rte_cryptodev_pci.h"
 #include "rte_cryptodev_pmd.h"
 
-/**
- * Parse name from argument
- */
-static int
-rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
-		const char *value, void *extra_args)
-{
-	struct rte_crypto_vdev_init_params *params = extra_args;
-
-	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
-		CDEV_LOG_ERR("Invalid name %s, should be less than "
-				"%u bytes", value,
-				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
-		return -1;
-	}
-
-	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
-
-	return 0;
-}
-
-/**
- * Parse integer from argument
- */
-static int
-rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
-		const char *value, void *extra_args)
-{
-	int *i = extra_args;
-
-	*i = atoi(value);
-	if (*i < 0) {
-		CDEV_LOG_ERR("Argument has to be positive.");
-		return -1;
-	}
-
-	return 0;
-}
-
-struct rte_cryptodev *
-rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
-		int socket_id, struct rte_vdev_device *vdev)
-{
-	struct rte_cryptodev *cryptodev;
-
-	/* allocate device structure */
-	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
-	if (cryptodev == NULL)
-		return NULL;
-
-	/* allocate private device structure */
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		cryptodev->data->dev_private =
-				rte_zmalloc_socket("cryptodev device private",
-						dev_private_size,
-						RTE_CACHE_LINE_SIZE,
-						socket_id);
-
-		if (cryptodev->data->dev_private == NULL)
-			rte_panic("Cannot allocate memzone for private device"
-					" data");
-	}
-
-	cryptodev->device = &vdev->device;
-
-	/* initialise user call-back tail queue */
-	TAILQ_INIT(&(cryptodev->link_intr_cbs));
-
-	return cryptodev;
-}
-
-int
-rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
-		const char *input_args)
-{
-	struct rte_kvargs *kvlist = NULL;
-	int ret = 0;
-
-	if (params == NULL)
-		return -EINVAL;
-
-	if (input_args) {
-		kvlist = rte_kvargs_parse(input_args,
-				cryptodev_vdev_valid_params);
-		if (kvlist == NULL)
-			return -1;
-
-		ret = rte_kvargs_process(kvlist,
-					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
-					&rte_cryptodev_vdev_parse_integer_arg,
-					&params->max_nb_queue_pairs);
-		if (ret < 0)
-			goto free_kvlist;
-
-		ret = rte_kvargs_process(kvlist,
-					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
-					&rte_cryptodev_vdev_parse_integer_arg,
-					&params->max_nb_sessions);
-		if (ret < 0)
-			goto free_kvlist;
-
-		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
-					&rte_cryptodev_vdev_parse_integer_arg,
-					&params->socket_id);
-		if (ret < 0)
-			goto free_kvlist;
-
-		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
-					&rte_cryptodev_vdev_parse_name_arg,
-					params);
-		if (ret < 0)
-			goto free_kvlist;
-	}
-
-free_kvlist:
-	rte_kvargs_free(kvlist);
-	return ret;
-}
-
 int
 rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
 			size_t private_data_size,
diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.c b/lib/librte_cryptodev/rte_cryptodev_vdev.c
new file mode 100644
index 0000000..fd308b4
--- /dev/null
+++ b/lib/librte_cryptodev/rte_cryptodev_vdev.c
@@ -0,0 +1,154 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "rte_cryptodev_vdev.h"
+#include "rte_cryptodev_pci.h"
+#include "rte_cryptodev_pmd.h"
+
+/**
+ * Parse name from argument
+ */
+static int
+rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	struct rte_crypto_vdev_init_params *params = extra_args;
+
+	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
+		CDEV_LOG_ERR("Invalid name %s, should be less than "
+				"%u bytes", value,
+				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
+		return -1;
+	}
+
+	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
+
+	return 0;
+}
+
+/**
+ * Parse integer from argument
+ */
+static int
+rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	int *i = extra_args;
+
+	*i = atoi(value);
+	if (*i < 0) {
+		CDEV_LOG_ERR("Argument has to be positive.");
+		return -1;
+	}
+
+	return 0;
+}
+
+struct rte_cryptodev *
+rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
+		int socket_id, struct rte_vdev_device *vdev)
+{
+	struct rte_cryptodev *cryptodev;
+
+	/* allocate device structure */
+	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
+	if (cryptodev == NULL)
+		return NULL;
+
+	/* allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket("cryptodev device private",
+						dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						socket_id);
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private device"
+					" data");
+	}
+
+	cryptodev->device = &vdev->device;
+
+	/* initialise user call-back tail queue */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	return cryptodev;
+}
+
+int
+rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
+		const char *input_args)
+{
+	struct rte_kvargs *kvlist = NULL;
+	int ret = 0;
+
+	if (params == NULL)
+		return -EINVAL;
+
+	if (input_args) {
+		kvlist = rte_kvargs_parse(input_args,
+				cryptodev_vdev_valid_params);
+		if (kvlist == NULL)
+			return -1;
+
+		ret = rte_kvargs_process(kvlist,
+					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->max_nb_queue_pairs);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist,
+					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->max_nb_sessions);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->socket_id);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
+					&rte_cryptodev_vdev_parse_name_arg,
+					params);
+		if (ret < 0)
+			goto free_kvlist;
+	}
+
+free_kvlist:
+	rte_kvargs_free(kvlist);
+	return ret;
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 04/12] vdev: move to drivers/bus
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (2 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 03/12] crypto: move vdev helper functions into dedicated file Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-08-29 13:04   ` Gaëtan Rivet
  2017-08-25  9:40 ` [PATCH 05/12] bus/vdev: change log type from EAL to PMD Jianfeng Tan
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 drivers/bus/Makefile                      |   2 +
 drivers/bus/vdev/Makefile                 |  57 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |  10 +
 drivers/bus/vdev/rte_cryptodev_vdev.c     | 154 ++++++++++++++
 drivers/bus/vdev/rte_cryptodev_vdev.h     | 100 +++++++++
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 342 ++++++++++++++++++++++++++++++
 lib/librte_cryptodev/Makefile             |   2 -
 lib/librte_cryptodev/rte_cryptodev_vdev.c | 154 --------------
 lib/librte_cryptodev/rte_cryptodev_vdev.h | 100 ---------
 lib/librte_eal/bsdapp/eal/Makefile        |   1 -
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 ------------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   1 -
 mk/rte.app.mk                             |   1 +
 18 files changed, 826 insertions(+), 755 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.c
 create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.h
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.c
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 5e97a08..aca0994 100644
--- a/config/common_base
+++ b/config/common_base
@@ -750,3 +750,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 0224214..9b6d45e 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -35,4 +35,6 @@ core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV) += vdev
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..30c4813
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,57 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+SRCS-y += rte_cryptodev_vdev.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+SYMLINK-y-include += rte_cryptodev_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..69740c3
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,10 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+	rte_cryptodev_vdev_pmd_init
+	rte_cryptodev_vdev_parse_init_params
+};
diff --git a/drivers/bus/vdev/rte_cryptodev_vdev.c b/drivers/bus/vdev/rte_cryptodev_vdev.c
new file mode 100644
index 0000000..fd308b4
--- /dev/null
+++ b/drivers/bus/vdev/rte_cryptodev_vdev.c
@@ -0,0 +1,154 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "rte_cryptodev_vdev.h"
+#include "rte_cryptodev_pci.h"
+#include "rte_cryptodev_pmd.h"
+
+/**
+ * Parse name from argument
+ */
+static int
+rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	struct rte_crypto_vdev_init_params *params = extra_args;
+
+	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
+		CDEV_LOG_ERR("Invalid name %s, should be less than "
+				"%u bytes", value,
+				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
+		return -1;
+	}
+
+	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
+
+	return 0;
+}
+
+/**
+ * Parse integer from argument
+ */
+static int
+rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	int *i = extra_args;
+
+	*i = atoi(value);
+	if (*i < 0) {
+		CDEV_LOG_ERR("Argument has to be positive.");
+		return -1;
+	}
+
+	return 0;
+}
+
+struct rte_cryptodev *
+rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
+		int socket_id, struct rte_vdev_device *vdev)
+{
+	struct rte_cryptodev *cryptodev;
+
+	/* allocate device structure */
+	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
+	if (cryptodev == NULL)
+		return NULL;
+
+	/* allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket("cryptodev device private",
+						dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						socket_id);
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private device"
+					" data");
+	}
+
+	cryptodev->device = &vdev->device;
+
+	/* initialise user call-back tail queue */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	return cryptodev;
+}
+
+int
+rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
+		const char *input_args)
+{
+	struct rte_kvargs *kvlist = NULL;
+	int ret = 0;
+
+	if (params == NULL)
+		return -EINVAL;
+
+	if (input_args) {
+		kvlist = rte_kvargs_parse(input_args,
+				cryptodev_vdev_valid_params);
+		if (kvlist == NULL)
+			return -1;
+
+		ret = rte_kvargs_process(kvlist,
+					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->max_nb_queue_pairs);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist,
+					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->max_nb_sessions);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->socket_id);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
+					&rte_cryptodev_vdev_parse_name_arg,
+					params);
+		if (ret < 0)
+			goto free_kvlist;
+	}
+
+free_kvlist:
+	rte_kvargs_free(kvlist);
+	return ret;
+}
diff --git a/drivers/bus/vdev/rte_cryptodev_vdev.h b/drivers/bus/vdev/rte_cryptodev_vdev.h
new file mode 100644
index 0000000..94ab9d3
--- /dev/null
+++ b/drivers/bus/vdev/rte_cryptodev_vdev.h
@@ -0,0 +1,100 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CRYPTODEV_VDEV_H_
+#define _RTE_CRYPTODEV_VDEV_H_
+
+#include <rte_vdev.h>
+#include <inttypes.h>
+
+#include "rte_cryptodev.h"
+
+#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS	8
+#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS	2048
+
+#define RTE_CRYPTODEV_VDEV_NAME				("name")
+#define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG		("max_nb_queue_pairs")
+#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG		("max_nb_sessions")
+#define RTE_CRYPTODEV_VDEV_SOCKET_ID			("socket_id")
+
+static const char * const cryptodev_vdev_valid_params[] = {
+	RTE_CRYPTODEV_VDEV_NAME,
+	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
+	RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
+	RTE_CRYPTODEV_VDEV_SOCKET_ID
+};
+
+/**
+ * @internal
+ * Initialisation parameters for virtual crypto devices
+ */
+struct rte_crypto_vdev_init_params {
+	unsigned int max_nb_queue_pairs;
+	unsigned int max_nb_sessions;
+	uint8_t socket_id;
+	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
+};
+
+/**
+ * @internal
+ * Creates a new virtual crypto device and returns the pointer
+ * to that device.
+ *
+ * @param	name			PMD type name
+ * @param	dev_private_size	Size of crypto PMDs private data
+ * @param	socket_id		Socket to allocate resources on.
+ * @param	vdev			Pointer to virtual device structure.
+ *
+ * @return
+ *   - Cryptodev pointer if device is successfully created.
+ *   - NULL if device cannot be created.
+ */
+struct rte_cryptodev *
+rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
+		int socket_id, struct rte_vdev_device *vdev);
+
+/**
+ * @internal
+ * Parse virtual device initialisation parameters input arguments
+ *
+ * @params	params		Initialisation parameters with defaults set.
+ * @params	input_args	Command line arguments
+ *
+ * @return
+ * 0 on successful parse
+ * <0 on failure to parse
+ */
+int
+rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
+		const char *input_args);
+
+#endif /* _RTE_CRYPTODEV_VDEV_H_ */
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..f7e547a
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,342 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_vdev.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 301c78d..4f70719 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -42,14 +42,12 @@ CFLAGS += $(WERROR_FLAGS)
 
 # library source files
 SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c
-SRCS-y += rte_cryptodev_vdev.c
 
 # export include files
 SYMLINK-y-include += rte_crypto.h
 SYMLINK-y-include += rte_crypto_sym.h
 SYMLINK-y-include += rte_cryptodev.h
 SYMLINK-y-include += rte_cryptodev_pmd.h
-SYMLINK-y-include += rte_cryptodev_vdev.h
 SYMLINK-y-include += rte_cryptodev_pci.h
 
 # versioning export map
diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.c b/lib/librte_cryptodev/rte_cryptodev_vdev.c
deleted file mode 100644
index fd308b4..0000000
--- a/lib/librte_cryptodev/rte_cryptodev_vdev.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2017 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of the copyright holder nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "rte_cryptodev_vdev.h"
-#include "rte_cryptodev_pci.h"
-#include "rte_cryptodev_pmd.h"
-
-/**
- * Parse name from argument
- */
-static int
-rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
-		const char *value, void *extra_args)
-{
-	struct rte_crypto_vdev_init_params *params = extra_args;
-
-	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
-		CDEV_LOG_ERR("Invalid name %s, should be less than "
-				"%u bytes", value,
-				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
-		return -1;
-	}
-
-	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
-
-	return 0;
-}
-
-/**
- * Parse integer from argument
- */
-static int
-rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
-		const char *value, void *extra_args)
-{
-	int *i = extra_args;
-
-	*i = atoi(value);
-	if (*i < 0) {
-		CDEV_LOG_ERR("Argument has to be positive.");
-		return -1;
-	}
-
-	return 0;
-}
-
-struct rte_cryptodev *
-rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
-		int socket_id, struct rte_vdev_device *vdev)
-{
-	struct rte_cryptodev *cryptodev;
-
-	/* allocate device structure */
-	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
-	if (cryptodev == NULL)
-		return NULL;
-
-	/* allocate private device structure */
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		cryptodev->data->dev_private =
-				rte_zmalloc_socket("cryptodev device private",
-						dev_private_size,
-						RTE_CACHE_LINE_SIZE,
-						socket_id);
-
-		if (cryptodev->data->dev_private == NULL)
-			rte_panic("Cannot allocate memzone for private device"
-					" data");
-	}
-
-	cryptodev->device = &vdev->device;
-
-	/* initialise user call-back tail queue */
-	TAILQ_INIT(&(cryptodev->link_intr_cbs));
-
-	return cryptodev;
-}
-
-int
-rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
-		const char *input_args)
-{
-	struct rte_kvargs *kvlist = NULL;
-	int ret = 0;
-
-	if (params == NULL)
-		return -EINVAL;
-
-	if (input_args) {
-		kvlist = rte_kvargs_parse(input_args,
-				cryptodev_vdev_valid_params);
-		if (kvlist == NULL)
-			return -1;
-
-		ret = rte_kvargs_process(kvlist,
-					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
-					&rte_cryptodev_vdev_parse_integer_arg,
-					&params->max_nb_queue_pairs);
-		if (ret < 0)
-			goto free_kvlist;
-
-		ret = rte_kvargs_process(kvlist,
-					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
-					&rte_cryptodev_vdev_parse_integer_arg,
-					&params->max_nb_sessions);
-		if (ret < 0)
-			goto free_kvlist;
-
-		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
-					&rte_cryptodev_vdev_parse_integer_arg,
-					&params->socket_id);
-		if (ret < 0)
-			goto free_kvlist;
-
-		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
-					&rte_cryptodev_vdev_parse_name_arg,
-					params);
-		if (ret < 0)
-			goto free_kvlist;
-	}
-
-free_kvlist:
-	rte_kvargs_free(kvlist);
-	return ret;
-}
diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.h b/lib/librte_cryptodev/rte_cryptodev_vdev.h
deleted file mode 100644
index 94ab9d3..0000000
--- a/lib/librte_cryptodev/rte_cryptodev_vdev.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2017 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of the copyright holder nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_CRYPTODEV_VDEV_H_
-#define _RTE_CRYPTODEV_VDEV_H_
-
-#include <rte_vdev.h>
-#include <inttypes.h>
-
-#include "rte_cryptodev.h"
-
-#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS	8
-#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS	2048
-
-#define RTE_CRYPTODEV_VDEV_NAME				("name")
-#define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG		("max_nb_queue_pairs")
-#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG		("max_nb_sessions")
-#define RTE_CRYPTODEV_VDEV_SOCKET_ID			("socket_id")
-
-static const char * const cryptodev_vdev_valid_params[] = {
-	RTE_CRYPTODEV_VDEV_NAME,
-	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
-	RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
-	RTE_CRYPTODEV_VDEV_SOCKET_ID
-};
-
-/**
- * @internal
- * Initialisation parameters for virtual crypto devices
- */
-struct rte_crypto_vdev_init_params {
-	unsigned int max_nb_queue_pairs;
-	unsigned int max_nb_sessions;
-	uint8_t socket_id;
-	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
-};
-
-/**
- * @internal
- * Creates a new virtual crypto device and returns the pointer
- * to that device.
- *
- * @param	name			PMD type name
- * @param	dev_private_size	Size of crypto PMDs private data
- * @param	socket_id		Socket to allocate resources on.
- * @param	vdev			Pointer to virtual device structure.
- *
- * @return
- *   - Cryptodev pointer if device is successfully created.
- *   - NULL if device cannot be created.
- */
-struct rte_cryptodev *
-rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
-		int socket_id, struct rte_vdev_device *vdev);
-
-/**
- * @internal
- * Parse virtual device initialisation parameters input arguments
- *
- * @params	params		Initialisation parameters with defaults set.
- * @params	input_args	Command line arguments
- *
- * @return
- * 0 on successful parse
- * <0 on failure to parse
- */
-int
-rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
-		const char *input_args);
-
-#endif /* _RTE_CRYPTODEV_VDEV_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 005019e..6fee587 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..7eeb06a 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5386d3a..8bfc343 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -166,28 +166,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -312,4 +290,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 90bca4d..33faa18 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -80,7 +80,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..c423bf8 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -97,6 +97,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV)           += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 05/12] bus/vdev: change log type from EAL to PMD
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (3 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 04/12] vdev: move to drivers/bus Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-08-29 12:54   ` Gaëtan Rivet
  2017-08-25  9:40 ` [PATCH 06/12] eal: add channel for primary/secondary communication Jianfeng Tan
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      | 10 ++++++----
 drivers/bus/vdev/vdev_logs.h | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index f7e547a..cde2a3c 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,8 @@
 #include <rte_memory.h>
 #include <rte_errno.h>
 
+#include "vdev_logs.h"
+
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
 
@@ -102,7 +104,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -188,7 +190,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -211,7 +213,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -292,7 +294,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..7a2d811
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,40 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#define VDEV_LOG(level, fmt, args...) \
+	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (4 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 05/12] bus/vdev: change log type from EAL to PMD Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-09-18 13:49   ` Jiayu Hu
                     ` (2 more replies)
  2017-08-25  9:40 ` [PATCH 07/12] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
                   ` (7 subsequent siblings)
  13 siblings, 3 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Previouly, there is only one way for primary/secondary to exchange
messages, that is, primary process writes info into some predefind
file, and secondary process reads info out. That cannot address
the requirements:
  a. Secondary wants to send info to primary.
  b. Sending info at any time, instead of just initialization time.
  c. Share FD with the other side.

This patch proposes to create a communication channel (as an unix
socket connection) for above requirements.

Three new APIs are added:

  1. rte_eal_primary_secondary_add_action is used to register an action,
if the calling component wants to response the messages from the
corresponding component in its primary process or secondary processes.
  2. rte_eal_primary_secondary_del_action is used to unregister the
action if the calling component does not want to response the messages.
  3. rte_eal_primary_secondary_sendmsg is used to send a message.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
 lib/librte_eal/common/eal_common_proc.c         | 454 ++++++++++++++++++++++++
 lib/librte_eal/common/eal_filesystem.h          |  18 +
 lib/librte_eal/common/eal_private.h             |  10 +
 lib/librte_eal/common/include/rte_eal.h         |  74 ++++
 lib/librte_eal/linuxapp/eal/eal.c               |   6 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
 7 files changed, 578 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index aac6fd7..f4ff29f 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -237,3 +237,11 @@ EXPERIMENTAL {
 	rte_service_unregister;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eal_primary_secondary_add_action;
+	rte_eal_primary_secondary_del_action;
+	rte_eal_primary_secondary_sendmsg;
+} DPDK_17.11;
diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
index 60526ca..fa316bf 100644
--- a/lib/librte_eal/common/eal_common_proc.c
+++ b/lib/librte_eal/common/eal_common_proc.c
@@ -33,8 +33,20 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rte_log.h>
 #include <rte_eal.h>
+#include <rte_lcore.h>
 
+#include "eal_private.h"
 #include "eal_filesystem.h"
 #include "eal_internal_cfg.h"
 
@@ -59,3 +71,445 @@ rte_eal_primary_proc_alive(const char *config_file_path)
 
 	return !!ret;
 }
+
+struct action_entry {
+	TAILQ_ENTRY(action_entry) next;      /**< Next attached action entry*/
+
+#define MAX_ACTION_NAME_LEN	64
+	char action_name[MAX_ACTION_NAME_LEN];
+	rte_eal_primary_secondary_t *action;
+};
+
+/** Double linked list of actions. */
+TAILQ_HEAD(action_entry_list, action_entry);
+
+static struct action_entry_list action_entry_list =
+	TAILQ_HEAD_INITIALIZER(action_entry_list);
+
+static struct action_entry *
+find_action_entry_by_name(const char *name)
+{
+	int len = strlen(name);
+	struct action_entry *entry;
+
+	TAILQ_FOREACH(entry, &action_entry_list, next) {
+		if (strncmp(entry->action_name, name, len) == 0)
+				break;
+	}
+
+	return entry;
+}
+
+int
+rte_eal_primary_secondary_add_action(const char *action_name,
+				     rte_eal_primary_secondary_t action)
+{
+	struct action_entry *entry = malloc(sizeof(struct action_entry));
+
+	if (entry == NULL)
+		return -ENOMEM;
+
+	strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
+	entry->action = action;
+	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
+	return 0;
+}
+
+void
+rte_eal_primary_secondary_del_action(const char *name)
+{
+	struct action_entry *entry = find_action_entry_by_name(name);
+
+	TAILQ_REMOVE(&action_entry_list, entry, next);
+	free(entry);
+}
+
+#define MAX_SECONDARY_PROCS	8
+
+static int efd_pri_sec; /* epoll fd for primary/secondary channel thread */
+static int fd_listen;   /* unix listen socket by primary */
+static int fd_to_pri;   /* only used by secondary process */
+static int fds_to_sec[MAX_SECONDARY_PROCS];
+
+struct msg_hdr {
+	char action_name[MAX_ACTION_NAME_LEN];
+	int fds_num;
+	char params[0];
+} __rte_packed;
+
+static int
+add_sec_proc(int fd)
+{
+	int i;
+
+	for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
+		if (fds_to_sec[i] == -1)
+			break;
+
+	if (i >= MAX_SECONDARY_PROCS)
+		return -1;
+
+	fds_to_sec[i] = fd;
+
+	return i;
+}
+
+static void
+del_sec_proc(int fd)
+{
+	int i;
+
+	for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
+		if (fds_to_sec[i] == fd) {
+			fds_to_sec[i] = -1;
+			break;
+		}
+	}
+}
+
+static int
+read_msg(int sockfd, char *buf, int buflen, int *fds, int fds_num)
+{
+	struct iovec iov;
+	struct msghdr msgh;
+	size_t fdsize = fds_num * sizeof(int);
+	char control[CMSG_SPACE(fdsize)];
+	struct cmsghdr *cmsg;
+	int ret;
+
+	memset(&msgh, 0, sizeof(msgh));
+	iov.iov_base = buf;
+	iov.iov_len  = buflen;
+
+	msgh.msg_iov = &iov;
+	msgh.msg_iovlen = 1;
+	msgh.msg_control = control;
+	msgh.msg_controllen = sizeof(control);
+
+	ret = recvmsg(sockfd, &msgh, 0);
+	if (ret <= 0) {
+		RTE_LOG(ERR, EAL, "recvmsg failed\n");
+		return ret;
+	}
+
+	if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
+		RTE_LOG(ERR, EAL, "truncted msg\n");
+		return -1;
+	}
+
+	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
+		cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
+		if ((cmsg->cmsg_level == SOL_SOCKET) &&
+			(cmsg->cmsg_type == SCM_RIGHTS)) {
+			memcpy(fds, CMSG_DATA(cmsg), fdsize);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int
+process_msg(int fd)
+{
+	int len;
+	int params_len;
+	char buf[1024];
+	int fds[8]; /* accept at most 8 FDs per message */
+	struct msg_hdr *hdr;
+	struct action_entry *entry;
+
+	len = read_msg(fd, buf, 1024, fds, 8);
+	if (len < 0) {
+		RTE_LOG(ERR, EAL, "failed to read message: %s\n",
+			strerror(errno));
+		return -1;
+	}
+
+	hdr = (struct msg_hdr *) buf;
+
+	entry = find_action_entry_by_name(hdr->action_name);
+	if (entry == NULL) {
+		RTE_LOG(ERR, EAL, "cannot find action by: %s\n",
+			hdr->action_name);
+		return -1;
+	}
+
+	params_len = len - sizeof(struct msg_hdr);
+	return entry->action(hdr->params, params_len, fds, hdr->fds_num);
+}
+
+static void *
+thread_primary(__attribute__((unused)) void *arg)
+{
+	int fd;
+	int i, n;
+	struct epoll_event event;
+	struct epoll_event *events;
+
+	event.events = EPOLLIN | EPOLLRDHUP;
+	event.data.fd = fd_listen;
+	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_listen, &event) < 0) {
+		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n",
+			strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	events = calloc(20, sizeof event);
+
+	while (1) {
+		n = epoll_wait(efd_pri_sec, events, 20, -1);
+		for (i = 0; i < n; i++) {
+			if (events[i].data.fd == fd_listen) {
+				if (events[i].events != EPOLLIN) {
+					RTE_LOG(ERR, EAL, "what happens?\n");
+					exit(EXIT_FAILURE);
+				}
+
+				fd = accept(fd_listen, NULL, NULL);
+				if (fd < 0) {
+					RTE_LOG(ERR, EAL, "primary failed to accept: %s\n",
+						strerror(errno));
+					continue;
+				}
+
+				event.data.fd = fd;
+				if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd, &event) < 0) {
+					RTE_LOG(ERR, EAL, "failed to add secondary: %s\n",
+						strerror(errno));
+					continue;
+				}
+				if (add_sec_proc(fd) < 0)
+					RTE_LOG(ERR, EAL, "too many secondary processes\n");
+
+				continue;
+			}
+
+			fd = events[i].data.fd;
+
+			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
+				RTE_LOG(ERR, EAL,
+					"secondary process exit: %d\n", fd);
+				epoll_ctl(efd_pri_sec, EPOLL_CTL_DEL, fd, NULL);
+				del_sec_proc(fd);
+				continue;
+			}
+
+			if ((events[i].events & EPOLLIN)) {
+				RTE_LOG(INFO, EAL,
+					"recv msg from secondary process\n");
+
+				process_msg(fd);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static void *
+thread_secondary(__attribute__((unused)) void *arg)
+{
+	int fd;
+	int i, n;
+	struct epoll_event event;
+	struct epoll_event *events;
+
+	event.events = EPOLLIN | EPOLLRDHUP;
+	event.data.fd = fd_to_pri;
+	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_to_pri, &event) < 0) {
+		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n", strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	events = calloc(20, sizeof event);
+
+	while (1) {
+		n = epoll_wait(efd_pri_sec, events, 20, -1);
+		for (i = 0; i < n; i++) {
+
+			fd = events[i].data.fd;
+
+			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
+				RTE_LOG(ERR, EAL, "primary exits, so do I\n");
+				/* Do we need exit secondary when primary exits? */
+				exit(EXIT_FAILURE);
+			}
+
+			if ((events[i].events & EPOLLIN)) {
+				RTE_LOG(INFO, EAL,
+					"recv msg from primary process\n");
+				process_msg(fd);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+int
+rte_eal_primary_secondary_channel_init(void)
+{
+	int i, fd, ret;
+	const char *path;
+	struct sockaddr_un un;
+	pthread_t tid;
+	void*(*fn)(void *);
+	char thread_name[RTE_MAX_THREAD_NAME_LEN];
+
+	efd_pri_sec = epoll_create1(0);
+	if (efd_pri_sec < 0) {
+		RTE_LOG(ERR, EAL, "epoll_create1 failed\n");
+		return -1;
+	}
+
+	fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create unix socket");
+		return -1;
+	}
+
+	memset(&un, 0, sizeof(un));
+	un.sun_family = AF_UNIX;
+	path = eal_primary_secondary_unix_path();
+	strncpy(un.sun_path, path, sizeof(un.sun_path));
+	un.sun_path[sizeof(un.sun_path) - 1] = '\0';
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+
+		for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
+			fds_to_sec[i] = -1;
+
+		if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+			RTE_LOG(ERR, EAL, "cannot set nonblocking mode\n");
+			close(fd);
+			return -1;
+		}
+
+		/* The file still exists since last run */
+		unlink(path);
+
+		ret = bind(fd, (struct sockaddr *)&un, sizeof(un));
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "failed to bind to %s: %s\n",
+				path, strerror(errno));
+			close(fd);
+			return -1;
+		}
+		RTE_LOG(INFO, EAL, "primary bind to %s\n", path);
+
+		ret = listen(fd, 1024);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "failed to listen: %s", strerror(errno));
+			close(fd);
+			return -1;
+		}
+
+		fn = thread_primary;
+		fd_listen = fd;
+	} else {
+		ret = connect(fd, (struct sockaddr *)&un, sizeof(un));
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "failed to connect primary\n");
+			return -1;
+		}
+		fn = thread_secondary;
+		fd_to_pri = fd;
+	}
+
+	ret = pthread_create(&tid, NULL, fn, NULL);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "failed to create thead: %s\n",
+			strerror(errno));
+		close(fd);
+		close(efd_pri_sec);
+		return -1;
+	}
+
+	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
+		 "ps_channel");
+	ret = rte_thread_setname(tid, thread_name);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "failed to set thead name\n");
+		close(fd);
+		close(efd_pri_sec);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+send_msg(int fd, struct msghdr *p_msgh)
+{
+	int ret;
+
+	do {
+		ret = sendmsg(fd, p_msgh, 0);
+	} while (ret < 0 && errno == EINTR);
+
+	return ret;
+}
+
+int
+rte_eal_primary_secondary_sendmsg(const char *action_name,
+				  const void *params,
+				  int len_params,
+				  int fds[],
+				  int fds_num)
+{
+	int i;
+	int ret = 0;
+	struct msghdr msgh;
+	struct iovec iov;
+	size_t fd_size = fds_num * sizeof(int);
+	char control[CMSG_SPACE(fd_size)];
+	struct cmsghdr *cmsg;
+	struct msg_hdr *msg;
+	int len_msg;
+
+	len_msg = sizeof(struct msg_hdr) + len_params;
+	msg = malloc(len_msg);
+	if (!msg) {
+		RTE_LOG(ERR, EAL, "Cannot alloc memory for msg");
+		return -ENOMEM;
+	}
+	memset(msg, 0, len_msg);
+	strcpy(msg->action_name, action_name);
+	msg->fds_num = fds_num;
+	memcpy(msg->params, params, len_params);
+
+	memset(&msgh, 0, sizeof(msgh));
+	memset(control, 0, sizeof(control));
+
+	iov.iov_base = (uint8_t *)msg;
+	iov.iov_len = len_msg;
+
+	msgh.msg_iov = &iov;
+	msgh.msg_iovlen = 1;
+	msgh.msg_control = control;
+	msgh.msg_controllen = sizeof(control);
+
+	cmsg = CMSG_FIRSTHDR(&msgh);
+	cmsg->cmsg_len = CMSG_LEN(fd_size);
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	memcpy(CMSG_DATA(cmsg), fds, fd_size);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
+			if (fds_to_sec[i] == -1)
+				continue;
+
+			ret = send_msg(fds_to_sec[i], &msgh);
+			if (ret < 0)
+				break;
+		}
+	} else {
+		ret = send_msg(fd_to_pri, &msgh);
+	}
+
+	free(msg);
+
+	return ret;
+}
diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
index 8acbd99..78bb4fb 100644
--- a/lib/librte_eal/common/eal_filesystem.h
+++ b/lib/librte_eal/common/eal_filesystem.h
@@ -67,6 +67,24 @@ eal_runtime_config_path(void)
 	return buffer;
 }
 
+/** Path of primary/secondary communication unix socket file. */
+#define PRIMARY_SECONDARY_UNIX_PATH_FMT "%s/.%s_unix"
+static inline const char *
+eal_primary_secondary_unix_path(void)
+{
+	static char buffer[PATH_MAX]; /* static so auto-zeroed */
+	const char *directory = default_config_dir;
+	const char *home_dir = getenv("HOME");
+
+	if (getuid() != 0 && home_dir != NULL)
+		directory = home_dir;
+	snprintf(buffer, sizeof(buffer) - 1, PRIMARY_SECONDARY_UNIX_PATH_FMT,
+		 directory, internal_config.hugefile_prefix);
+
+	return buffer;
+
+}
+
 /** Path of hugepage info file. */
 #define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
 
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 597d82e..719b160 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -355,4 +355,14 @@ bool rte_eal_using_phys_addrs(void);
  */
 struct rte_bus *rte_bus_find_by_device_name(const char *str);
 
+/**
+ * Create the unix channel for primary/secondary communication.
+ *
+ * @return
+ *   0 on success;
+ *   (<0) on failure.
+ */
+
+int rte_eal_primary_secondary_channel_init(void);
+
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
index 0e7363d..6cfc9d6 100644
--- a/lib/librte_eal/common/include/rte_eal.h
+++ b/lib/librte_eal/common/include/rte_eal.h
@@ -210,6 +210,80 @@ int rte_eal_init(int argc, char **argv);
 int rte_eal_primary_proc_alive(const char *config_file_path);
 
 /**
+ * Action function typedef used by other components.
+ *
+ * As we create unix socket channel for primary/secondary communication, use
+ * this function typedef to register action for coming messages.
+ */
+typedef int (rte_eal_primary_secondary_t)(const char *params,
+					  int len,
+					  int fds[],
+					  int fds_num);
+/**
+ * Register an action function for primary/secondary communication.
+ *
+ * Call this function to register an action, if the calling component wants
+ * to response the messages from the corresponding component in its primary
+ * process or secondary processes.
+ *
+ * @param action_name
+ *   The action_name argument plays as the nonredundant key to find the action.
+ *
+ * @param action
+ *   The action argument is the function pointer to the action function.
+ *
+ * @return
+ *  - 0 on success.
+ *  - (<0) on failure.
+ */
+int rte_eal_primary_secondary_add_action(const char *action_name,
+					 rte_eal_primary_secondary_t action);
+/**
+ * Unregister an action function for primary/secondary communication.
+ *
+ * Call this function to unregister an action  if the calling component does
+ * not want to response the messages from the corresponding component in its
+ * primary process or secondary processes.
+ *
+ * @param action_name
+ *   The action_name argument plays as the nonredundant key to find the action.
+ *
+ */
+void rte_eal_primary_secondary_del_action(const char *name);
+
+/**
+ * Send a message to the primary process or the secondary processes.
+ *
+ * This function will send a message which will be responsed by the action
+ * identified by action_name of the process on the other side.
+ *
+ * @param action_name
+ *   The action_name argument is used to identify which action will be used.
+ *
+ * @param params
+ *   The params argument contains the customized message.
+ *
+ * @param len_params
+ *   The len_params argument is the length of the customized message.
+ *
+ * @param fds
+ *   The fds argument is an array of fds sent with sendmsg.
+ *
+ * @param fds_num
+ *   The fds_num argument is number of fds to be sent with sendmsg.
+ *
+ * @return
+ *  - (>=0) on success.
+ *  - (<0) on failure.
+ */
+int
+rte_eal_primary_secondary_sendmsg(const char *action_name,
+				  const void *params,
+				  int len_params,
+				  int fds[],
+				  int fds_num);
+
+/**
  * Usage function typedef used by the application usage function.
  *
  * Use this function typedef to define and call rte_set_applcation_usage_hook()
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 48f12f4..237c0b1 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -873,6 +873,12 @@ rte_eal_init(int argc, char **argv)
 
 	eal_check_mem_on_local_socket();
 
+	if (rte_eal_primary_secondary_channel_init() < 0) {
+		rte_eal_init_alert("Cannot create unix channel.");
+		rte_errno = EFAULT;
+		return -1;
+	}
+
 	if (eal_plugins_init() < 0)
 		rte_eal_init_alert("Cannot init plugins\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 3a8f154..c618aec 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -242,3 +242,11 @@ EXPERIMENTAL {
 	rte_service_unregister;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eal_primary_secondary_add_action;
+	rte_eal_primary_secondary_del_action;
+	rte_eal_primary_secondary_sendmsg;
+} DPDK_17.11;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 07/12] bus/vdev: scan and probe vdev in secondary processes
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (5 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 06/12] eal: add channel for primary/secondary communication Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-08-25  9:40 ` [PATCH 08/12] ethdev: support attach vdev in secondary process Jianfeng Tan
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Base on primary/secondary communication channel, we add vdev action
to scan virtual devices in secondary processes.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index cde2a3c..c3e97fb 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -252,12 +252,105 @@ rte_vdev_uninit(const char *name)
 	return 0;
 }
 
+struct vdev_action_params {
+#define VDEV_SCAN_REQUEST	1
+#define VDEV_SCAN_RESPONSE	2
+	int type;
+	char name[32];
+};
+
+static int vdev_plug(struct rte_device *dev);
+
+static int
+vdev_action(const char *params, int len,
+	    int fds[] __rte_unused,
+	    int fds_num __rte_unused)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	const struct vdev_action_params *in_params;
+	struct vdev_action_params ou_params;
+
+	in_params = (const struct vdev_action_params *)params;
+	switch (in_params->type) {
+	case VDEV_SCAN_REQUEST:
+		ou_params.type = VDEV_SCAN_RESPONSE;
+		TAILQ_FOREACH(dev, &vdev_device_list, next) {
+			strncpy(ou_params.name, dev->device.name, 32);
+			rte_eal_primary_secondary_sendmsg("vdev", &ou_params,
+							  len, NULL, 0);
+		}
+		break;
+	case VDEV_SCAN_RESPONSE:
+		if (strlen(in_params->name) == 0) {
+			VDEV_LOG(ERR, "invalid name was passed");
+			break;
+		}
+
+		dev = find_vdev(in_params->name);
+		if (dev) {
+			VDEV_LOG(ERR, "vdev already exists: %s",
+				 in_params->name);
+			break;
+		}
+
+		devargs = alloc_devargs(in_params->name, NULL);
+		if (!devargs) {
+			VDEV_LOG(ERR, "failed to allocate memory");
+			break;
+		}
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev) {
+			VDEV_LOG(ERR, "failed to allocate memory");
+			free(devargs);
+			break;
+		}
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = 0; /* to be corrected in probe() */
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+
+		if (vdev_plug(&dev->device) < 0) {
+			VDEV_LOG(ERR, "failed to plug device");
+			free(devargs);
+			free(dev);
+		}
+
+		VDEV_LOG(INFO, "plug in device: %s", in_params->name);
+
+		break;
+	default:
+		VDEV_LOG(ERR, "vdev cannot recognize this message\n");
+	}
+
+	return 0;
+}
+
 static int
 vdev_scan(void)
 {
 	struct rte_vdev_device *dev;
 	struct rte_devargs *devargs;
 
+	if (rte_eal_primary_secondary_add_action("vdev", vdev_action) < 0) {
+		VDEV_LOG(ERR, "vdev fails to add action\n");
+		return -1;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		struct vdev_action_params params;
+
+		params.type = VDEV_SCAN_REQUEST;
+		rte_eal_primary_secondary_sendmsg("vdev", &params,
+						  sizeof(params), NULL, 0);
+
+		return 0;
+	}
+
 	/* for virtual devices we scan the devargs_list populated via cmdline */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
 
@@ -287,6 +380,9 @@ vdev_probe(void)
 {
 	struct rte_vdev_device *dev;
 
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return 0;
+
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(dev, &vdev_device_list, next) {
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 08/12] ethdev: support attach vdev in secondary process
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (6 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 07/12] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-08-25  9:40 ` [PATCH 09/12] vhost: allocate virtio_net in memzone Jianfeng Tan
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

When vdev driver requests an ethdev entry in secondary process,
we will identify the correct entry in rte_eth_dev_data array
and return the correct entry in the rte_eth_devices arrays.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev_vdev.h | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev_vdev.h b/lib/librte_ether/rte_ethdev_vdev.h
index 4d2c3e2..460749b 100644
--- a/lib/librte_ether/rte_ethdev_vdev.h
+++ b/lib/librte_ether/rte_ethdev_vdev.h
@@ -58,25 +58,29 @@ rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size)
 	struct rte_eth_dev *eth_dev;
 	const char *name = rte_vdev_device_name(dev);
 
-	eth_dev = rte_eth_dev_allocate(name);
-	if (!eth_dev)
-		return NULL;
-
-	if (private_data_size) {
-		eth_dev->data->dev_private = rte_zmalloc_socket(name,
-			private_data_size, RTE_CACHE_LINE_SIZE,
-			dev->device.numa_node);
-		if (!eth_dev->data->dev_private) {
-			rte_eth_dev_release_port(eth_dev);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev = rte_eth_dev_allocate(name);
+		if (!eth_dev)
 			return NULL;
+
+		if (private_data_size) {
+			eth_dev->data->dev_private = rte_zmalloc_socket(name,
+					private_data_size, RTE_CACHE_LINE_SIZE,
+					dev->device.numa_node);
+			if (!eth_dev->data->dev_private) {
+				rte_eth_dev_release_port(eth_dev);
+				return NULL;
+			}
 		}
+	} else {
+		eth_dev = rte_eth_dev_attach_secondary(name);
 	}
 
 	eth_dev->device = &dev->device;
 	eth_dev->intr_handle = NULL;
-
 	eth_dev->data->kdrv = RTE_KDRV_NONE;
 	eth_dev->data->numa_node = dev->device.numa_node;
+
 	return eth_dev;
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 09/12] vhost: allocate virtio_net in memzone
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (7 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 08/12] ethdev: support attach vdev in secondary process Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-08-25  9:40 ` [PATCH 10/12] vhost: support to kick in secondary process Jianfeng Tan
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Instead of allocate on the stack, change to allocate in memzone
so that we can retrieve them in secondary processes.

TODO: numa awareness.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_vhost/socket.c |  2 ++
 lib/librte_vhost/vhost.c  | 34 ++++++++++++++++++++++++++++++++--
 lib/librte_vhost/vhost.h  |  4 +++-
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 41aa3f9..35b9751 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -606,6 +606,8 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
 	int ret = -1;
 	struct vhost_user_socket *vsocket;
 
+	alloc_vhost_devices();
+
 	if (!path)
 		return -1;
 
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 0b6aa1c..2b687ea 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -47,15 +47,45 @@
 #include <rte_memory.h>
 #include <rte_malloc.h>
 #include <rte_vhost.h>
+#include <rte_memzone.h>
 
 #include "vhost.h"
 
-struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+#define MZ_VHOST_DEVICES "mz_vhost_devices"
+struct virtio_net **vhost_devices;
+
+void
+alloc_vhost_devices(void)
+{
+	const struct rte_memzone *mz;
+
+	if (vhost_devices != NULL)
+		return;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		mz = rte_memzone_reserve(MZ_VHOST_DEVICES,
+				MAX_VHOST_DEVICE * sizeof(*vhost_devices),
+				rte_socket_id(), 0);
+	} else
+		mz = rte_memzone_lookup(MZ_VHOST_DEVICES);
+
+	if (mz == NULL)
+		rte_panic("Cannot allocate memzone for vhost_devices\n");
+
+	vhost_devices = mz->addr;
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		memset(vhost_devices, 0,
+		       MAX_VHOST_DEVICE * sizeof(*vhost_devices));
+}
 
 struct virtio_net *
 get_device(int vid)
 {
-	struct virtio_net *dev = vhost_devices[vid];
+	struct virtio_net *dev;
+
+	alloc_vhost_devices();
+
+	dev = vhost_devices[vid];
 
 	if (unlikely(!dev)) {
 		RTE_LOG(ERR, VHOST_CONFIG,
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 6fe72ae..bc1f31e 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -278,7 +278,7 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
 
 extern uint64_t VHOST_FEATURES;
 #define MAX_VHOST_DEVICE	1024
-extern struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+extern struct virtio_net **vhost_devices;
 
 /* Convert guest physical address to host physical address */
 static __rte_always_inline phys_addr_t
@@ -300,6 +300,8 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size)
 	return 0;
 }
 
+
+void alloc_vhost_devices(void);
 struct virtio_net *get_device(int vid);
 
 int vhost_new_device(void);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 10/12] vhost: support to kick in secondary process
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (8 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 09/12] vhost: allocate virtio_net in memzone Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-09-21  3:33   ` Yuanhan Liu
  2017-08-25  9:40 ` [PATCH 11/12] net/vhost: support to run in the " Jianfeng Tan
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

To support kick in secondary process, we propose callfd_pri and
kickfd_pri to store the value in primary process; and by a new
API, rte_vhost_set_vring_effective_fd(), we can set effective
callfd and kickfd which can be used by secondary process.

Note in this case, either primary process or the secondary process
can kick the frontend; that is, they cannot kick a vring at the
same time.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_vhost/rte_vhost.h  |  3 +++
 lib/librte_vhost/vhost.c      | 27 +++++++++++++++++++++++++--
 lib/librte_vhost/vhost.h      |  3 +++
 lib/librte_vhost/vhost_user.c |  4 ++--
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 8c974eb..c82f249 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -432,6 +432,9 @@ int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 			      struct rte_vhost_vring *vring);
 
+int rte_vhost_set_vring_effective_fd(int vid, uint16_t vring_idx,
+				     int callfd, int kickfd);
+
 /**
  * Get vhost RX queue avail count.
  *
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 2b687ea..d2e4500 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -435,13 +435,36 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 	vring->used  = vq->used;
 	vring->log_guest_addr  = vq->log_guest_addr;
 
-	vring->callfd  = vq->callfd;
-	vring->kickfd  = vq->kickfd;
+	vring->callfd  = vq->callfd_pri;
+	vring->kickfd  = vq->kickfd_pri;
 	vring->size    = vq->size;
 
 	return 0;
 }
 
+int
+rte_vhost_set_vring_effective_fd(int vid, uint16_t vring_idx,
+				 int callfd, int kickfd)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (!dev)
+		return -1;
+
+	if (vring_idx >= VHOST_MAX_VRING)
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (!vq)
+		return -1;
+
+	vq->callfd = callfd;
+	vq->kickfd = kickfd;
+
+	return 0;
+}
 uint16_t
 rte_vhost_avail_entries(int vid, uint16_t queue_id)
 {
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index bc1f31e..be57c52 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -98,9 +98,12 @@ struct vhost_virtqueue {
 	/* Backend value to determine if device should started/stopped */
 	int			backend;
 	/* Used to notify the guest (trigger interrupt) */
+	int			callfd_pri;
 	int			callfd;
 	/* Currently unused as polling mode is enabled */
+	int			kickfd_pri;
 	int			kickfd;
+
 	int			enabled;
 
 	/* Physical address of used ring, for logging */
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index ad2e8d3..72f2b40 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -664,7 +664,7 @@ vhost_user_set_vring_call(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 	if (vq->callfd >= 0)
 		close(vq->callfd);
 
-	vq->callfd = file.fd;
+	vq->callfd_pri = vq->callfd = file.fd;
 }
 
 static void
@@ -684,7 +684,7 @@ vhost_user_set_vring_kick(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 	vq = dev->virtqueue[file.index];
 	if (vq->kickfd >= 0)
 		close(vq->kickfd);
-	vq->kickfd = file.fd;
+	vq->kickfd_pri = vq->kickfd = file.fd;
 }
 
 static void
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 11/12] net/vhost: support to run in the secondary process
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (9 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 10/12] vhost: support to kick in secondary process Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-09-21  4:29   ` Yuanhan Liu
  2017-08-25  9:40 ` [PATCH 12/12] examples/helloworld: do not exit automatically Jianfeng Tan
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Support to run vhost-pmd vdev in the secondary process. We obtain
information, like memory regions, kickfd, callfd, through
primary/secondary communication channel.

And by invoking rte_vhost_set_vring_effective_fd, we can set the
kickfd which can be recognized by the secondary process.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vhost/rte_eth_vhost.c | 158 +++++++++++++++++++++++++++++++++++---
 1 file changed, 146 insertions(+), 12 deletions(-)

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 0dac5e6..7120105 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -33,6 +33,7 @@
 #include <unistd.h>
 #include <pthread.h>
 #include <stdbool.h>
+#include <sys/mman.h>
 
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
@@ -46,6 +47,16 @@
 
 #include "rte_eth_vhost.h"
 
+#define VHOST_MSG_TYPE_REGIONS	1
+#define VHOST_MSG_TYPE_SET_FDS	2
+
+struct vhost_params {
+	int type;
+	int vid;
+	int vring_idx;
+	struct rte_vhost_mem_region regions[0];
+};
+
 enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM};
 
 #define ETH_VHOST_IFACE_ARG		"iface"
@@ -550,6 +561,67 @@ update_queuing_status(struct rte_eth_dev *dev)
 }
 
 static int
+share_device(int vid)
+{
+	uint32_t i, vring_num;
+	int len;
+	int fds[8];
+	struct rte_vhost_memory *mem;
+	struct vhost_params *params;
+	struct rte_vhost_vring vring;
+
+	/* share mem table */
+	if (rte_vhost_get_mem_table(vid, &mem) < 0) {
+		printf("Failed to get mem table\n");
+		return 0;
+	}
+	for (i = 0; i < mem->nregions; ++i)
+		fds[i] = mem->regions[i].fd;
+
+	len = sizeof(struct rte_vhost_mem_region) * mem->nregions;
+	params = malloc(sizeof(*params) + len);
+	if (params == NULL) {
+		printf("Failed to allocate memory\n");
+		return -1;
+	}
+
+	params->type = VHOST_MSG_TYPE_REGIONS;
+	params->vid = vid;
+	memcpy(params->regions, mem->regions, len);
+
+	if (rte_eal_primary_secondary_sendmsg("vhost pmd", params,
+					      sizeof(*params) + len,
+					      fds, mem->nregions) < 0) {
+		printf("Failed to share mem table\n");
+		free(params);
+		return -1;
+	}
+
+	/* share callfd and kickfd */
+	params->type = VHOST_MSG_TYPE_SET_FDS;
+	vring_num = rte_vhost_get_vring_num(vid);
+	for (i = 0; i < vring_num; i++) {
+		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
+			printf("Failed to get vring, idx = %d\n", i);
+			free(params);
+			return -1;
+		}
+
+		params->vring_idx = i;
+		fds[0] = vring.callfd;
+		fds[1] = vring.kickfd;
+		if (rte_eal_primary_secondary_sendmsg("vhost pmd", params,
+					sizeof(*params),
+					fds, 2) < 0) {
+			printf("Failed to set fds\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int
 new_device(int vid)
 {
 	struct rte_eth_dev *eth_dev;
@@ -610,6 +682,8 @@ new_device(int vid)
 	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
 				      NULL, NULL);
 
+	share_device(vid);
+
 	return 0;
 }
 
@@ -1025,13 +1099,6 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	RTE_LOG(INFO, PMD, "Creating VHOST-USER backend on numa socket %u\n",
 		numa_node);
 
-	/* now do all data allocation - for eth_dev structure and internal
-	 * (private) data
-	 */
-	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
-	if (data == NULL)
-		goto error;
-
 	list = rte_zmalloc_socket(name, sizeof(*list), 0, numa_node);
 	if (list == NULL)
 		goto error;
@@ -1073,11 +1140,7 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	rte_spinlock_init(&vring_state->lock);
 	vring_states[eth_dev->data->port_id] = vring_state;
 
-	/* We'll replace the 'data' originally allocated by eth_dev. So the
-	 * vhost PMD resources won't be shared between multi processes.
-	 */
-	rte_memcpy(data, eth_dev->data, sizeof(*data));
-	eth_dev->data = data;
+	data = eth_dev->data;
 
 	data->nb_rx_queues = queues;
 	data->nb_tx_queues = queues;
@@ -1125,6 +1188,33 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	return -1;
 }
 
+static int
+eth_dev_vhost_attach(struct rte_vdev_device *dev)
+{
+	struct rte_eth_dev *eth_dev = NULL;
+	struct rte_eth_dev_data *data = NULL;
+
+	RTE_LOG(INFO, PMD, "Attach vhost user port\n");
+
+	/* reserve an ethdev entry */
+	eth_dev = rte_eth_vdev_allocate(dev, sizeof(struct pmd_internal));
+	if (eth_dev == NULL)
+		goto error;
+
+	eth_dev->dev_ops = &ops;
+
+	/* finally assign rx and tx ops */
+	eth_dev->rx_pkt_burst = eth_vhost_rx;
+	eth_dev->tx_pkt_burst = eth_vhost_tx;
+
+	data = eth_dev->data;
+
+	return data->port_id;
+
+error:
+	return -1;
+}
+
 static inline int
 open_iface(const char *key __rte_unused, const char *value, void *extra_args)
 {
@@ -1154,6 +1244,39 @@ open_int(const char *key __rte_unused, const char *value, void *extra_args)
 }
 
 static int
+vhost_pmd_action(const char *params, int len __rte_unused,
+		 int fds[], int fds_num)
+{
+	int i;
+	void *base_addr;
+	const struct vhost_params *p = (const struct vhost_params *)params;
+	const struct rte_vhost_mem_region *regions;
+
+	switch (p->type) {
+	case VHOST_MSG_TYPE_REGIONS:
+		regions = (const void *)p->regions;
+		for (i = 0; i < fds_num; ++i) {
+			base_addr = mmap(regions[i].mmap_addr,
+					 regions[i].mmap_size,
+					 PROT_READ | PROT_WRITE,
+					 MAP_FIXED | MAP_SHARED, fds[i], 0);
+			if (base_addr != regions[i].mmap_addr) {
+				RTE_LOG(INFO, PMD, "mmap error");
+				break;
+			}
+		}
+		break;
+	case VHOST_MSG_TYPE_SET_FDS:
+		rte_vhost_set_vring_effective_fd(p->vid,
+						 p->vring_idx,
+			       			 fds[0], fds[1]);
+		break;
+	}
+
+	return 0;
+}
+
+static int
 rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 {
 	struct rte_kvargs *kvlist = NULL;
@@ -1167,6 +1290,17 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 	RTE_LOG(INFO, PMD, "Initializing pmd_vhost for %s\n",
 		rte_vdev_device_name(dev));
 
+	if (rte_eal_primary_secondary_add_action("vhost pmd",
+						 vhost_pmd_action) < 0) {
+		RTE_LOG(ERR, PMD, "vhost fails to add action\n");
+		return -1;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		ret = eth_dev_vhost_attach(dev);
+	       	return	(ret >= 0) ? 0 : -1;
+	}
+
 	kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_arguments);
 	if (kvlist == NULL)
 		return -1;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH 12/12] examples/helloworld: do not exit automatically
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (10 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 11/12] net/vhost: support to run in the " Jianfeng Tan
@ 2017-08-25  9:40 ` Jianfeng Tan
  2017-09-18 11:44   ` De Lara Guarch, Pablo
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
  13 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-08-25  9:40 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 examples/helloworld/main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/examples/helloworld/main.c b/examples/helloworld/main.c
index 8b7a2de..35b70da 100644
--- a/examples/helloworld/main.c
+++ b/examples/helloworld/main.c
@@ -36,6 +36,7 @@
 #include <stdint.h>
 #include <errno.h>
 #include <sys/queue.h>
+#include <unistd.h>
 
 #include <rte_memory.h>
 #include <rte_memzone.h>
@@ -72,6 +73,8 @@ main(int argc, char **argv)
 	/* call it on master lcore too */
 	lcore_hello(NULL);
 
+	while (1) sleep(5);
+
 	rte_eal_mp_wait_lcore();
 	return 0;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH 02/12] eal: avoid calling rte_vdev_init()
  2017-08-25  9:40 ` [PATCH 02/12] eal: avoid calling rte_vdev_init() Jianfeng Tan
@ 2017-08-29 12:50   ` Gaëtan Rivet
  2017-08-29 22:25     ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Gaëtan Rivet @ 2017-08-29 12:50 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

Hi,

On Fri, Aug 25, 2017 at 09:40:42AM +0000, Jianfeng Tan wrote:
> We can call bus->plug() to avoid calling rte_vdev_init() explicitly.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_eal/common/eal_common_dev.c | 21 +++++----------------
>  1 file changed, 5 insertions(+), 16 deletions(-)
> 
> diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
> index e251275..066dfbf 100644
> --- a/lib/librte_eal/common/eal_common_dev.c
> +++ b/lib/librte_eal/common/eal_common_dev.c
> @@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
>  int rte_eal_dev_attach(const char *name, const char *devargs)
>  {
>  	struct rte_bus *bus;
> -	int ret;
>  
>  	if (name == NULL || devargs == NULL) {
>  		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
> @@ -80,22 +79,12 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
>  			name);
>  		return -EINVAL;
>  	}
> -	if (strcmp(bus->name, "pci") == 0)
> -		return rte_eal_hotplug_add("pci", name, devargs);
> -	if (strcmp(bus->name, "vdev") != 0) {
> -		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
> -		return -ENOTSUP;
> -	}
> +	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") != 0)

It seems to be a copy / paste error, it should probably be:

+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)

Now, one could question the relevancy of keeping this API
(rte_eal_dev_attach / detach), but I guess this is beyond the scope of
this series.

> +		return rte_eal_hotplug_add(bus->name, name, devargs);
>  
> -	/*
> -	 * If we haven't found a bus device the user meant to "hotplug" a
> -	 * virtual device instead.
> -	 */
> -	ret = rte_vdev_init(name, devargs);
> -	if (ret)
> -		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
> -			name);
> -	return ret;
> +	RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
> +
> +	return -ENOTSUP;
>  }
>  
>  int rte_eal_dev_detach(struct rte_device *dev)
> -- 
> 2.7.4
> 

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 05/12] bus/vdev: change log type from EAL to PMD
  2017-08-25  9:40 ` [PATCH 05/12] bus/vdev: change log type from EAL to PMD Jianfeng Tan
@ 2017-08-29 12:54   ` Gaëtan Rivet
  2017-08-29 22:27     ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Gaëtan Rivet @ 2017-08-29 12:54 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

On Fri, Aug 25, 2017 at 09:40:45AM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/bus/vdev/vdev.c      | 10 ++++++----
>  drivers/bus/vdev/vdev_logs.h | 40 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 46 insertions(+), 4 deletions(-)
>  create mode 100644 drivers/bus/vdev/vdev_logs.h
> 
> diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
> index f7e547a..cde2a3c 100644
> --- a/drivers/bus/vdev/vdev.c
> +++ b/drivers/bus/vdev/vdev.c
> @@ -47,6 +47,8 @@
>  #include <rte_memory.h>
>  #include <rte_errno.h>
>  
> +#include "vdev_logs.h"
> +
>  /* Forward declare to access virtual bus name */
>  static struct rte_bus rte_vdev_bus;
>  
> @@ -102,7 +104,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
>  
>  	name = rte_vdev_device_name(dev);
>  
> -	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
> +	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
>  		rte_vdev_device_name(dev));
>  
>  	if (vdev_parse(name, &driver))
> @@ -188,7 +190,7 @@ rte_vdev_init(const char *name, const char *args)
>  	ret = vdev_probe_all_drivers(dev);
>  	if (ret) {
>  		if (ret > 0)
> -			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
> +			VDEV_LOG(ERR, "no driver found for %s\n", name);
>  		goto fail;
>  	}
>  
> @@ -211,7 +213,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
>  	const struct rte_vdev_driver *driver;
>  
>  	if (!dev->device.driver) {
> -		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
> +		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
>  		return 1;
>  	}
>  
> @@ -292,7 +294,7 @@ vdev_probe(void)
>  			continue;
>  
>  		if (vdev_probe_all_drivers(dev)) {
> -			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
> +			VDEV_LOG(ERR, "failed to initialize %s device\n",
>  				rte_vdev_device_name(dev));
>  			return -1;
>  		}
> diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
> new file mode 100644
> index 0000000..7a2d811
> --- /dev/null
> +++ b/drivers/bus/vdev/vdev_logs.h
> @@ -0,0 +1,40 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _VDEV_LOGS_H_
> +#define _VDEV_LOGS_H_
> +
> +#define VDEV_LOG(level, fmt, args...) \
> +	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)

With the multiplication of bus implementations, wouldn't it be interesting
to introduce an RTE_LOGTYPE_BUS?

> +
> +#endif /* _VDEV_LOGS_H_ */
> -- 
> 2.7.4
> 

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 04/12] vdev: move to drivers/bus
  2017-08-25  9:40 ` [PATCH 04/12] vdev: move to drivers/bus Jianfeng Tan
@ 2017-08-29 13:04   ` Gaëtan Rivet
  2017-08-29 22:47     ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Gaëtan Rivet @ 2017-08-29 13:04 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

On Fri, Aug 25, 2017 at 09:40:44AM +0000, Jianfeng Tan wrote:
> Move the vdev bus from lib/librte_eal to drivers/bus.
> 
> As the crypto vdev helper function refers to data structure
> in rte_vdev.h, so we move those helper function into drivers/bus
> too.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  config/common_base                        |   5 +
>  drivers/bus/Makefile                      |   2 +
>  drivers/bus/vdev/Makefile                 |  57 +++++
>  drivers/bus/vdev/rte_bus_vdev_version.map |  10 +
>  drivers/bus/vdev/rte_cryptodev_vdev.c     | 154 ++++++++++++++
>  drivers/bus/vdev/rte_cryptodev_vdev.h     | 100 +++++++++
>  drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
>  drivers/bus/vdev/vdev.c                   | 342 ++++++++++++++++++++++++++++++
>  lib/librte_cryptodev/Makefile             |   2 -
>  lib/librte_cryptodev/rte_cryptodev_vdev.c | 154 --------------
>  lib/librte_cryptodev/rte_cryptodev_vdev.h | 100 ---------
>  lib/librte_eal/bsdapp/eal/Makefile        |   1 -
>  lib/librte_eal/common/Makefile            |   2 +-
>  lib/librte_eal/common/eal_common_vdev.c   | 342 ------------------------------
>  lib/librte_eal/common/include/rte_dev.h   |  24 +--
>  lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
>  lib/librte_eal/linuxapp/eal/Makefile      |   1 -
>  mk/rte.app.mk                             |   1 +
>  18 files changed, 826 insertions(+), 755 deletions(-)
>  create mode 100644 drivers/bus/vdev/Makefile
>  create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
>  create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.c
>  create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.h
>  create mode 100644 drivers/bus/vdev/rte_vdev.h
>  create mode 100644 drivers/bus/vdev/vdev.c
>  delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.c
>  delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.h
>  delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
>  delete mode 100644 lib/librte_eal/common/include/rte_vdev.h
> 
> diff --git a/config/common_base b/config/common_base
> index 5e97a08..aca0994 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -750,3 +750,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
>  # Compile the eventdev application
>  #
>  CONFIG_RTE_APP_EVENTDEV=y
> +
> +#
> +# Compile the vdev bus
> +#
> +CONFIG_RTE_LIBRTE_VDEV=y

Why not CONFIG_RTE_LIBRTE_VDEV_BUS?
It would seem more consistent.

> diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
> index 0224214..9b6d45e 100644
> --- a/drivers/bus/Makefile
> +++ b/drivers/bus/Makefile
> @@ -35,4 +35,6 @@ core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
>  DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
>  DEPDIRS-fslmc = $(core-libs)
>  
> +DIRS-$(CONFIG_RTE_LIBRTE_VDEV) += vdev
> +
>  include $(RTE_SDK)/mk/rte.subdir.mk
> diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
> new file mode 100644
> index 0000000..30c4813
> --- /dev/null
> +++ b/drivers/bus/vdev/Makefile
> @@ -0,0 +1,57 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2017 Intel Corporation. All rights reserved.
> +#   All rights reserved.
> +#
> +#   Redistribution and use in source and binary forms, with or without
> +#   modification, are permitted provided that the following conditions
> +#   are met:
> +#
> +#     * Redistributions of source code must retain the above copyright
> +#       notice, this list of conditions and the following disclaimer.
> +#     * Redistributions in binary form must reproduce the above copyright
> +#       notice, this list of conditions and the following disclaimer in
> +#       the documentation and/or other materials provided with the
> +#       distribution.
> +#     * Neither the name of Intel Corporation nor the names of its
> +#       contributors may be used to endorse or promote products derived
> +#       from this software without specific prior written permission.
> +#
> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +#
> +# library name
> +#
> +LIB = librte_bus_vdev.a
> +
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +
> +# versioning export map
> +EXPORT_MAP := rte_bus_vdev_version.map
> +
> +# library version
> +LIBABIVER := 1
> +
> +SRCS-y += vdev.c
> +SRCS-y += rte_cryptodev_vdev.c
> +
> +#
> +# Export include files
> +#
> +SYMLINK-y-include += rte_vdev.h
> +SYMLINK-y-include += rte_cryptodev_vdev.h
> +

Let's say the cryptodev lib must be updated.
I understand the need to move rte_cryptodev_vdev.h outside
librte_cryptodev, but I guess this exposes the vdev bus to ABI / API
instability due to a third-party subsystem?

I did something somewhat similar for PCI:
http://dpdk.org/ml/archives/dev/2017-August/073525.html

I don't know which solution is best, but something certainly needs to be
done.

---

Beside the `why`, about the `how`: shouldn't this file compilation and
symlink be conditioned to CONFIG_RTE_LIBRTE_CRYPTODEV=y?

i.e.: SYMLINK-$(CONFIG_RTE_LIBRTE_CRYPTODEV)-include += rte_cryptodev_vdev.h

> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
> new file mode 100644
> index 0000000..69740c3
> --- /dev/null
> +++ b/drivers/bus/vdev/rte_bus_vdev_version.map
> @@ -0,0 +1,10 @@
> +DPDK_17.11 {
> +	global:
> +
> +	rte_vdev_init;
> +	rte_vdev_register;
> +	rte_vdev_uninit;
> +	rte_vdev_unregister;
> +	rte_cryptodev_vdev_pmd_init
> +	rte_cryptodev_vdev_parse_init_params
> +};
> diff --git a/drivers/bus/vdev/rte_cryptodev_vdev.c b/drivers/bus/vdev/rte_cryptodev_vdev.c
> new file mode 100644
> index 0000000..fd308b4
> --- /dev/null
> +++ b/drivers/bus/vdev/rte_cryptodev_vdev.c
> @@ -0,0 +1,154 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of the copyright holder nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include "rte_cryptodev_vdev.h"
> +#include "rte_cryptodev_pci.h"
> +#include "rte_cryptodev_pmd.h"
> +
> +/**
> + * Parse name from argument
> + */
> +static int
> +rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
> +		const char *value, void *extra_args)
> +{
> +	struct rte_crypto_vdev_init_params *params = extra_args;
> +
> +	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
> +		CDEV_LOG_ERR("Invalid name %s, should be less than "
> +				"%u bytes", value,
> +				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
> +		return -1;
> +	}
> +
> +	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
> +
> +	return 0;
> +}
> +
> +/**
> + * Parse integer from argument
> + */
> +static int
> +rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
> +		const char *value, void *extra_args)
> +{
> +	int *i = extra_args;
> +
> +	*i = atoi(value);
> +	if (*i < 0) {
> +		CDEV_LOG_ERR("Argument has to be positive.");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +struct rte_cryptodev *
> +rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
> +		int socket_id, struct rte_vdev_device *vdev)
> +{
> +	struct rte_cryptodev *cryptodev;
> +
> +	/* allocate device structure */
> +	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
> +	if (cryptodev == NULL)
> +		return NULL;
> +
> +	/* allocate private device structure */
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		cryptodev->data->dev_private =
> +				rte_zmalloc_socket("cryptodev device private",
> +						dev_private_size,
> +						RTE_CACHE_LINE_SIZE,
> +						socket_id);
> +
> +		if (cryptodev->data->dev_private == NULL)
> +			rte_panic("Cannot allocate memzone for private device"
> +					" data");
> +	}
> +
> +	cryptodev->device = &vdev->device;
> +
> +	/* initialise user call-back tail queue */
> +	TAILQ_INIT(&(cryptodev->link_intr_cbs));
> +
> +	return cryptodev;
> +}
> +
> +int
> +rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
> +		const char *input_args)
> +{
> +	struct rte_kvargs *kvlist = NULL;
> +	int ret = 0;
> +
> +	if (params == NULL)
> +		return -EINVAL;
> +
> +	if (input_args) {
> +		kvlist = rte_kvargs_parse(input_args,
> +				cryptodev_vdev_valid_params);
> +		if (kvlist == NULL)
> +			return -1;
> +
> +		ret = rte_kvargs_process(kvlist,
> +					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
> +					&rte_cryptodev_vdev_parse_integer_arg,
> +					&params->max_nb_queue_pairs);
> +		if (ret < 0)
> +			goto free_kvlist;
> +
> +		ret = rte_kvargs_process(kvlist,
> +					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
> +					&rte_cryptodev_vdev_parse_integer_arg,
> +					&params->max_nb_sessions);
> +		if (ret < 0)
> +			goto free_kvlist;
> +
> +		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
> +					&rte_cryptodev_vdev_parse_integer_arg,
> +					&params->socket_id);
> +		if (ret < 0)
> +			goto free_kvlist;
> +
> +		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
> +					&rte_cryptodev_vdev_parse_name_arg,
> +					params);
> +		if (ret < 0)
> +			goto free_kvlist;
> +	}
> +
> +free_kvlist:
> +	rte_kvargs_free(kvlist);
> +	return ret;
> +}
> diff --git a/drivers/bus/vdev/rte_cryptodev_vdev.h b/drivers/bus/vdev/rte_cryptodev_vdev.h
> new file mode 100644
> index 0000000..94ab9d3
> --- /dev/null
> +++ b/drivers/bus/vdev/rte_cryptodev_vdev.h
> @@ -0,0 +1,100 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of the copyright holder nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _RTE_CRYPTODEV_VDEV_H_
> +#define _RTE_CRYPTODEV_VDEV_H_
> +
> +#include <rte_vdev.h>
> +#include <inttypes.h>
> +
> +#include "rte_cryptodev.h"
> +
> +#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS	8
> +#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS	2048
> +
> +#define RTE_CRYPTODEV_VDEV_NAME				("name")
> +#define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG		("max_nb_queue_pairs")
> +#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG		("max_nb_sessions")
> +#define RTE_CRYPTODEV_VDEV_SOCKET_ID			("socket_id")
> +
> +static const char * const cryptodev_vdev_valid_params[] = {
> +	RTE_CRYPTODEV_VDEV_NAME,
> +	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
> +	RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
> +	RTE_CRYPTODEV_VDEV_SOCKET_ID
> +};
> +
> +/**
> + * @internal
> + * Initialisation parameters for virtual crypto devices
> + */
> +struct rte_crypto_vdev_init_params {
> +	unsigned int max_nb_queue_pairs;
> +	unsigned int max_nb_sessions;
> +	uint8_t socket_id;
> +	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
> +};
> +
> +/**
> + * @internal
> + * Creates a new virtual crypto device and returns the pointer
> + * to that device.
> + *
> + * @param	name			PMD type name
> + * @param	dev_private_size	Size of crypto PMDs private data
> + * @param	socket_id		Socket to allocate resources on.
> + * @param	vdev			Pointer to virtual device structure.
> + *
> + * @return
> + *   - Cryptodev pointer if device is successfully created.
> + *   - NULL if device cannot be created.
> + */
> +struct rte_cryptodev *
> +rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
> +		int socket_id, struct rte_vdev_device *vdev);
> +
> +/**
> + * @internal
> + * Parse virtual device initialisation parameters input arguments
> + *
> + * @params	params		Initialisation parameters with defaults set.
> + * @params	input_args	Command line arguments
> + *
> + * @return
> + * 0 on successful parse
> + * <0 on failure to parse
> + */
> +int
> +rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
> +		const char *input_args);
> +
> +#endif /* _RTE_CRYPTODEV_VDEV_H_ */
> diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
> new file mode 100644
> index 0000000..41762b8
> --- /dev/null
> +++ b/drivers/bus/vdev/rte_vdev.h
> @@ -0,0 +1,153 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of RehiveTech nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef RTE_VDEV_H
> +#define RTE_VDEV_H
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <sys/queue.h>
> +#include <rte_dev.h>
> +#include <rte_devargs.h>
> +
> +struct rte_vdev_device {
> +	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
> +	struct rte_device device;               /**< Inherit core device */
> +};
> +
> +/**
> + * @internal
> + * Helper macro for drivers that need to convert to struct rte_vdev_device.
> + */
> +#define RTE_DEV_TO_VDEV(ptr) \
> +	container_of(ptr, struct rte_vdev_device, device)
> +
> +static inline const char *
> +rte_vdev_device_name(const struct rte_vdev_device *dev)
> +{
> +	if (dev && dev->device.name)
> +		return dev->device.name;
> +	return NULL;
> +}
> +
> +static inline const char *
> +rte_vdev_device_args(const struct rte_vdev_device *dev)
> +{
> +	if (dev && dev->device.devargs)
> +		return dev->device.devargs->args;
> +	return "";
> +}
> +
> +/** Double linked list of virtual device drivers. */
> +TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
> +
> +/**
> + * Probe function called for each virtual device driver once.
> + */
> +typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
> +
> +/**
> + * Remove function called for each virtual device driver once.
> + */
> +typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
> +
> +/**
> + * A virtual device driver abstraction.
> + */
> +struct rte_vdev_driver {
> +	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
> +	struct rte_driver driver;      /**< Inherited general driver. */
> +	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
> +	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
> +};
> +
> +/**
> + * Register a virtual device driver.
> + *
> + * @param driver
> + *   A pointer to a rte_vdev_driver structure describing the driver
> + *   to be registered.
> + */
> +void rte_vdev_register(struct rte_vdev_driver *driver);
> +
> +/**
> + * Unregister a virtual device driver.
> + *
> + * @param driver
> + *   A pointer to a rte_vdev_driver structure describing the driver
> + *   to be unregistered.
> + */
> +void rte_vdev_unregister(struct rte_vdev_driver *driver);
> +
> +#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
> +RTE_INIT(vdrvinitfn_ ##vdrv);\
> +static const char *vdrvinit_ ## nm ## _alias;\
> +static void vdrvinitfn_ ##vdrv(void)\
> +{\
> +	(vdrv).driver.name = RTE_STR(nm);\
> +	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
> +	rte_vdev_register(&vdrv);\
> +} \
> +RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
> +
> +#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
> +static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
> +
> +/**
> + * Initialize a driver specified by name.
> + *
> + * @param name
> + *   The pointer to a driver name to be initialized.
> + * @param args
> + *   The pointer to arguments used by driver initialization.
> + * @return
> + *  0 on success, negative on error
> + */
> +int rte_vdev_init(const char *name, const char *args);
> +
> +/**
> + * Uninitalize a driver specified by name.
> + *
> + * @param name
> + *   The pointer to a driver name to be initialized.
> + * @return
> + *  0 on success, negative on error
> + */
> +int rte_vdev_uninit(const char *name);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif
> diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
> new file mode 100644
> index 0000000..f7e547a
> --- /dev/null
> +++ b/drivers/bus/vdev/vdev.c
> @@ -0,0 +1,342 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of RehiveTech nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <string.h>
> +#include <inttypes.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <sys/queue.h>
> +
> +#include <rte_eal.h>
> +#include <rte_dev.h>
> +#include <rte_bus.h>
> +#include <rte_vdev.h>
> +#include <rte_common.h>
> +#include <rte_devargs.h>
> +#include <rte_memory.h>
> +#include <rte_errno.h>
> +
> +/* Forward declare to access virtual bus name */
> +static struct rte_bus rte_vdev_bus;
> +
> +/** Double linked list of virtual device drivers. */
> +TAILQ_HEAD(vdev_device_list, rte_vdev_device);
> +
> +static struct vdev_device_list vdev_device_list =
> +	TAILQ_HEAD_INITIALIZER(vdev_device_list);
> +struct vdev_driver_list vdev_driver_list =
> +	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
> +
> +/* register a driver */
> +void
> +rte_vdev_register(struct rte_vdev_driver *driver)
> +{
> +	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
> +}
> +
> +/* unregister a driver */
> +void
> +rte_vdev_unregister(struct rte_vdev_driver *driver)
> +{
> +	TAILQ_REMOVE(&vdev_driver_list, driver, next);
> +}
> +
> +static int
> +vdev_parse(const char *name, void *addr)
> +{
> +	struct rte_vdev_driver **out = addr;
> +	struct rte_vdev_driver *driver = NULL;
> +
> +	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
> +		if (strncmp(driver->driver.name, name,
> +			    strlen(driver->driver.name)) == 0)
> +			break;
> +		if (driver->driver.alias &&
> +		    strncmp(driver->driver.alias, name,
> +			    strlen(driver->driver.alias)) == 0)
> +			break;
> +	}
> +	if (driver != NULL &&
> +	    addr != NULL)
> +		*out = driver;
> +	return driver == NULL;
> +}
> +
> +static int
> +vdev_probe_all_drivers(struct rte_vdev_device *dev)
> +{
> +	const char *name;
> +	struct rte_vdev_driver *driver;
> +	int ret;
> +
> +	name = rte_vdev_device_name(dev);
> +
> +	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
> +		rte_vdev_device_name(dev));
> +
> +	if (vdev_parse(name, &driver))
> +		return -1;
> +	dev->device.driver = &driver->driver;
> +	ret = driver->probe(dev);
> +	if (ret)
> +		dev->device.driver = NULL;
> +	return ret;
> +}
> +
> +static struct rte_vdev_device *
> +find_vdev(const char *name)
> +{
> +	struct rte_vdev_device *dev;
> +
> +	if (!name)
> +		return NULL;
> +
> +	TAILQ_FOREACH(dev, &vdev_device_list, next) {
> +		const char *devname = rte_vdev_device_name(dev);
> +		if (!strncmp(devname, name, strlen(name)))
> +			return dev;
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct rte_devargs *
> +alloc_devargs(const char *name, const char *args)
> +{
> +	struct rte_devargs *devargs;
> +	int ret;
> +
> +	devargs = calloc(1, sizeof(*devargs));
> +	if (!devargs)
> +		return NULL;
> +
> +	devargs->bus = &rte_vdev_bus;
> +	if (args)
> +		devargs->args = strdup(args);
> +	else
> +		devargs->args = strdup("");
> +
> +	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
> +	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
> +		free(devargs->args);
> +		free(devargs);
> +		return NULL;
> +	}
> +
> +	return devargs;
> +}
> +
> +int
> +rte_vdev_init(const char *name, const char *args)
> +{
> +	struct rte_vdev_device *dev;
> +	struct rte_devargs *devargs;
> +	int ret;
> +
> +	if (name == NULL)
> +		return -EINVAL;
> +
> +	dev = find_vdev(name);
> +	if (dev)
> +		return -EEXIST;
> +
> +	devargs = alloc_devargs(name, args);
> +	if (!devargs)
> +		return -ENOMEM;
> +
> +	dev = calloc(1, sizeof(*dev));
> +	if (!dev) {
> +		ret = -ENOMEM;
> +		goto fail;
> +	}
> +
> +	dev->device.devargs = devargs;
> +	dev->device.numa_node = SOCKET_ID_ANY;
> +	dev->device.name = devargs->name;
> +
> +	ret = vdev_probe_all_drivers(dev);
> +	if (ret) {
> +		if (ret > 0)
> +			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
> +		goto fail;
> +	}
> +
> +	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
> +
> +	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
> +	return 0;
> +
> +fail:
> +	free(devargs->args);
> +	free(devargs);
> +	free(dev);
> +	return ret;
> +}
> +
> +static int
> +vdev_remove_driver(struct rte_vdev_device *dev)
> +{
> +	const char *name = rte_vdev_device_name(dev);
> +	const struct rte_vdev_driver *driver;
> +
> +	if (!dev->device.driver) {
> +		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
> +		return 1;
> +	}
> +
> +	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
> +		driver);
> +	return driver->remove(dev);
> +}
> +
> +int
> +rte_vdev_uninit(const char *name)
> +{
> +	struct rte_vdev_device *dev;
> +	struct rte_devargs *devargs;
> +	int ret;
> +
> +	if (name == NULL)
> +		return -EINVAL;
> +
> +	dev = find_vdev(name);
> +	if (!dev)
> +		return -ENOENT;
> +
> +	devargs = dev->device.devargs;
> +
> +	ret = vdev_remove_driver(dev);
> +	if (ret)
> +		return ret;
> +
> +	TAILQ_REMOVE(&vdev_device_list, dev, next);
> +
> +	TAILQ_REMOVE(&devargs_list, devargs, next);
> +
> +	free(devargs->args);
> +	free(devargs);
> +	free(dev);
> +	return 0;
> +}
> +
> +static int
> +vdev_scan(void)
> +{
> +	struct rte_vdev_device *dev;
> +	struct rte_devargs *devargs;
> +
> +	/* for virtual devices we scan the devargs_list populated via cmdline */
> +	TAILQ_FOREACH(devargs, &devargs_list, next) {
> +
> +		if (devargs->bus != &rte_vdev_bus)
> +			continue;
> +
> +		dev = find_vdev(devargs->name);
> +		if (dev)
> +			continue;
> +
> +		dev = calloc(1, sizeof(*dev));
> +		if (!dev)
> +			return -1;
> +
> +		dev->device.devargs = devargs;
> +		dev->device.numa_node = SOCKET_ID_ANY;
> +		dev->device.name = devargs->name;
> +
> +		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +vdev_probe(void)
> +{
> +	struct rte_vdev_device *dev;
> +
> +	/* call the init function for each virtual device */
> +	TAILQ_FOREACH(dev, &vdev_device_list, next) {
> +
> +		if (dev->device.driver)
> +			continue;
> +
> +		if (vdev_probe_all_drivers(dev)) {
> +			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
> +				rte_vdev_device_name(dev));
> +			return -1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static struct rte_device *
> +vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
> +		 const void *data)
> +{
> +	struct rte_vdev_device *dev;
> +
> +	TAILQ_FOREACH(dev, &vdev_device_list, next) {
> +		if (start && &dev->device == start) {
> +			start = NULL;
> +			continue;
> +		}
> +		if (cmp(&dev->device, data) == 0)
> +			return &dev->device;
> +	}
> +	return NULL;
> +}
> +
> +static int
> +vdev_plug(struct rte_device *dev)
> +{
> +	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
> +}
> +
> +static int
> +vdev_unplug(struct rte_device *dev)
> +{
> +	return rte_vdev_uninit(dev->name);
> +}
> +
> +static struct rte_bus rte_vdev_bus = {
> +	.scan = vdev_scan,
> +	.probe = vdev_probe,
> +	.find_device = vdev_find_device,
> +	.plug = vdev_plug,
> +	.unplug = vdev_unplug,
> +	.parse = vdev_parse,
> +};
> +
> +RTE_REGISTER_BUS(vdev, rte_vdev_bus);
> diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
> index 301c78d..4f70719 100644
> --- a/lib/librte_cryptodev/Makefile
> +++ b/lib/librte_cryptodev/Makefile
> @@ -42,14 +42,12 @@ CFLAGS += $(WERROR_FLAGS)
>  
>  # library source files
>  SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c
> -SRCS-y += rte_cryptodev_vdev.c
>  
>  # export include files
>  SYMLINK-y-include += rte_crypto.h
>  SYMLINK-y-include += rte_crypto_sym.h
>  SYMLINK-y-include += rte_cryptodev.h
>  SYMLINK-y-include += rte_cryptodev_pmd.h
> -SYMLINK-y-include += rte_cryptodev_vdev.h
>  SYMLINK-y-include += rte_cryptodev_pci.h
>  
>  # versioning export map
> diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.c b/lib/librte_cryptodev/rte_cryptodev_vdev.c
> deleted file mode 100644
> index fd308b4..0000000
> --- a/lib/librte_cryptodev/rte_cryptodev_vdev.c
> +++ /dev/null
> @@ -1,154 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of the copyright holder nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include "rte_cryptodev_vdev.h"
> -#include "rte_cryptodev_pci.h"
> -#include "rte_cryptodev_pmd.h"
> -
> -/**
> - * Parse name from argument
> - */
> -static int
> -rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
> -		const char *value, void *extra_args)
> -{
> -	struct rte_crypto_vdev_init_params *params = extra_args;
> -
> -	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
> -		CDEV_LOG_ERR("Invalid name %s, should be less than "
> -				"%u bytes", value,
> -				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
> -		return -1;
> -	}
> -
> -	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
> -
> -	return 0;
> -}
> -
> -/**
> - * Parse integer from argument
> - */
> -static int
> -rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
> -		const char *value, void *extra_args)
> -{
> -	int *i = extra_args;
> -
> -	*i = atoi(value);
> -	if (*i < 0) {
> -		CDEV_LOG_ERR("Argument has to be positive.");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -struct rte_cryptodev *
> -rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
> -		int socket_id, struct rte_vdev_device *vdev)
> -{
> -	struct rte_cryptodev *cryptodev;
> -
> -	/* allocate device structure */
> -	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
> -	if (cryptodev == NULL)
> -		return NULL;
> -
> -	/* allocate private device structure */
> -	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> -		cryptodev->data->dev_private =
> -				rte_zmalloc_socket("cryptodev device private",
> -						dev_private_size,
> -						RTE_CACHE_LINE_SIZE,
> -						socket_id);
> -
> -		if (cryptodev->data->dev_private == NULL)
> -			rte_panic("Cannot allocate memzone for private device"
> -					" data");
> -	}
> -
> -	cryptodev->device = &vdev->device;
> -
> -	/* initialise user call-back tail queue */
> -	TAILQ_INIT(&(cryptodev->link_intr_cbs));
> -
> -	return cryptodev;
> -}
> -
> -int
> -rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
> -		const char *input_args)
> -{
> -	struct rte_kvargs *kvlist = NULL;
> -	int ret = 0;
> -
> -	if (params == NULL)
> -		return -EINVAL;
> -
> -	if (input_args) {
> -		kvlist = rte_kvargs_parse(input_args,
> -				cryptodev_vdev_valid_params);
> -		if (kvlist == NULL)
> -			return -1;
> -
> -		ret = rte_kvargs_process(kvlist,
> -					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
> -					&rte_cryptodev_vdev_parse_integer_arg,
> -					&params->max_nb_queue_pairs);
> -		if (ret < 0)
> -			goto free_kvlist;
> -
> -		ret = rte_kvargs_process(kvlist,
> -					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
> -					&rte_cryptodev_vdev_parse_integer_arg,
> -					&params->max_nb_sessions);
> -		if (ret < 0)
> -			goto free_kvlist;
> -
> -		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
> -					&rte_cryptodev_vdev_parse_integer_arg,
> -					&params->socket_id);
> -		if (ret < 0)
> -			goto free_kvlist;
> -
> -		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
> -					&rte_cryptodev_vdev_parse_name_arg,
> -					params);
> -		if (ret < 0)
> -			goto free_kvlist;
> -	}
> -
> -free_kvlist:
> -	rte_kvargs_free(kvlist);
> -	return ret;
> -}
> diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.h b/lib/librte_cryptodev/rte_cryptodev_vdev.h
> deleted file mode 100644
> index 94ab9d3..0000000
> --- a/lib/librte_cryptodev/rte_cryptodev_vdev.h
> +++ /dev/null
> @@ -1,100 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of the copyright holder nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#ifndef _RTE_CRYPTODEV_VDEV_H_
> -#define _RTE_CRYPTODEV_VDEV_H_
> -
> -#include <rte_vdev.h>
> -#include <inttypes.h>
> -
> -#include "rte_cryptodev.h"
> -
> -#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS	8
> -#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS	2048
> -
> -#define RTE_CRYPTODEV_VDEV_NAME				("name")
> -#define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG		("max_nb_queue_pairs")
> -#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG		("max_nb_sessions")
> -#define RTE_CRYPTODEV_VDEV_SOCKET_ID			("socket_id")
> -
> -static const char * const cryptodev_vdev_valid_params[] = {
> -	RTE_CRYPTODEV_VDEV_NAME,
> -	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
> -	RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
> -	RTE_CRYPTODEV_VDEV_SOCKET_ID
> -};
> -
> -/**
> - * @internal
> - * Initialisation parameters for virtual crypto devices
> - */
> -struct rte_crypto_vdev_init_params {
> -	unsigned int max_nb_queue_pairs;
> -	unsigned int max_nb_sessions;
> -	uint8_t socket_id;
> -	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
> -};
> -
> -/**
> - * @internal
> - * Creates a new virtual crypto device and returns the pointer
> - * to that device.
> - *
> - * @param	name			PMD type name
> - * @param	dev_private_size	Size of crypto PMDs private data
> - * @param	socket_id		Socket to allocate resources on.
> - * @param	vdev			Pointer to virtual device structure.
> - *
> - * @return
> - *   - Cryptodev pointer if device is successfully created.
> - *   - NULL if device cannot be created.
> - */
> -struct rte_cryptodev *
> -rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
> -		int socket_id, struct rte_vdev_device *vdev);
> -
> -/**
> - * @internal
> - * Parse virtual device initialisation parameters input arguments
> - *
> - * @params	params		Initialisation parameters with defaults set.
> - * @params	input_args	Command line arguments
> - *
> - * @return
> - * 0 on successful parse
> - * <0 on failure to parse
> - */
> -int
> -rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
> -		const char *input_args);
> -
> -#endif /* _RTE_CRYPTODEV_VDEV_H_ */
> diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
> index 005019e..6fee587 100644
> --- a/lib/librte_eal/bsdapp/eal/Makefile
> +++ b/lib/librte_eal/bsdapp/eal/Makefile
> @@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
> -SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
> diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
> index e8fd67a..7eeb06a 100644
> --- a/lib/librte_eal/common/Makefile
> +++ b/lib/librte_eal/common/Makefile
> @@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
>  INC += rte_tailq.h rte_interrupts.h rte_alarm.h
>  INC += rte_string_fns.h rte_version.h
>  INC += rte_eal_memconfig.h rte_malloc_heap.h
> -INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
> +INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
>  INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
>  INC += rte_malloc.h rte_keepalive.h rte_time.h
>  INC += rte_service.h rte_service_component.h
> diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
> deleted file mode 100644
> index f7e547a..0000000
> --- a/lib/librte_eal/common/eal_common_vdev.c
> +++ /dev/null
> @@ -1,342 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2016 RehiveTech. All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of RehiveTech nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <string.h>
> -#include <inttypes.h>
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <stdint.h>
> -#include <stdbool.h>
> -#include <sys/queue.h>
> -
> -#include <rte_eal.h>
> -#include <rte_dev.h>
> -#include <rte_bus.h>
> -#include <rte_vdev.h>
> -#include <rte_common.h>
> -#include <rte_devargs.h>
> -#include <rte_memory.h>
> -#include <rte_errno.h>
> -
> -/* Forward declare to access virtual bus name */
> -static struct rte_bus rte_vdev_bus;
> -
> -/** Double linked list of virtual device drivers. */
> -TAILQ_HEAD(vdev_device_list, rte_vdev_device);
> -
> -static struct vdev_device_list vdev_device_list =
> -	TAILQ_HEAD_INITIALIZER(vdev_device_list);
> -struct vdev_driver_list vdev_driver_list =
> -	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
> -
> -/* register a driver */
> -void
> -rte_vdev_register(struct rte_vdev_driver *driver)
> -{
> -	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
> -}
> -
> -/* unregister a driver */
> -void
> -rte_vdev_unregister(struct rte_vdev_driver *driver)
> -{
> -	TAILQ_REMOVE(&vdev_driver_list, driver, next);
> -}
> -
> -static int
> -vdev_parse(const char *name, void *addr)
> -{
> -	struct rte_vdev_driver **out = addr;
> -	struct rte_vdev_driver *driver = NULL;
> -
> -	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
> -		if (strncmp(driver->driver.name, name,
> -			    strlen(driver->driver.name)) == 0)
> -			break;
> -		if (driver->driver.alias &&
> -		    strncmp(driver->driver.alias, name,
> -			    strlen(driver->driver.alias)) == 0)
> -			break;
> -	}
> -	if (driver != NULL &&
> -	    addr != NULL)
> -		*out = driver;
> -	return driver == NULL;
> -}
> -
> -static int
> -vdev_probe_all_drivers(struct rte_vdev_device *dev)
> -{
> -	const char *name;
> -	struct rte_vdev_driver *driver;
> -	int ret;
> -
> -	name = rte_vdev_device_name(dev);
> -
> -	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
> -		rte_vdev_device_name(dev));
> -
> -	if (vdev_parse(name, &driver))
> -		return -1;
> -	dev->device.driver = &driver->driver;
> -	ret = driver->probe(dev);
> -	if (ret)
> -		dev->device.driver = NULL;
> -	return ret;
> -}
> -
> -static struct rte_vdev_device *
> -find_vdev(const char *name)
> -{
> -	struct rte_vdev_device *dev;
> -
> -	if (!name)
> -		return NULL;
> -
> -	TAILQ_FOREACH(dev, &vdev_device_list, next) {
> -		const char *devname = rte_vdev_device_name(dev);
> -		if (!strncmp(devname, name, strlen(name)))
> -			return dev;
> -	}
> -
> -	return NULL;
> -}
> -
> -static struct rte_devargs *
> -alloc_devargs(const char *name, const char *args)
> -{
> -	struct rte_devargs *devargs;
> -	int ret;
> -
> -	devargs = calloc(1, sizeof(*devargs));
> -	if (!devargs)
> -		return NULL;
> -
> -	devargs->bus = &rte_vdev_bus;
> -	if (args)
> -		devargs->args = strdup(args);
> -	else
> -		devargs->args = strdup("");
> -
> -	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
> -	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
> -		free(devargs->args);
> -		free(devargs);
> -		return NULL;
> -	}
> -
> -	return devargs;
> -}
> -
> -int
> -rte_vdev_init(const char *name, const char *args)
> -{
> -	struct rte_vdev_device *dev;
> -	struct rte_devargs *devargs;
> -	int ret;
> -
> -	if (name == NULL)
> -		return -EINVAL;
> -
> -	dev = find_vdev(name);
> -	if (dev)
> -		return -EEXIST;
> -
> -	devargs = alloc_devargs(name, args);
> -	if (!devargs)
> -		return -ENOMEM;
> -
> -	dev = calloc(1, sizeof(*dev));
> -	if (!dev) {
> -		ret = -ENOMEM;
> -		goto fail;
> -	}
> -
> -	dev->device.devargs = devargs;
> -	dev->device.numa_node = SOCKET_ID_ANY;
> -	dev->device.name = devargs->name;
> -
> -	ret = vdev_probe_all_drivers(dev);
> -	if (ret) {
> -		if (ret > 0)
> -			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
> -		goto fail;
> -	}
> -
> -	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
> -
> -	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
> -	return 0;
> -
> -fail:
> -	free(devargs->args);
> -	free(devargs);
> -	free(dev);
> -	return ret;
> -}
> -
> -static int
> -vdev_remove_driver(struct rte_vdev_device *dev)
> -{
> -	const char *name = rte_vdev_device_name(dev);
> -	const struct rte_vdev_driver *driver;
> -
> -	if (!dev->device.driver) {
> -		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
> -		return 1;
> -	}
> -
> -	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
> -		driver);
> -	return driver->remove(dev);
> -}
> -
> -int
> -rte_vdev_uninit(const char *name)
> -{
> -	struct rte_vdev_device *dev;
> -	struct rte_devargs *devargs;
> -	int ret;
> -
> -	if (name == NULL)
> -		return -EINVAL;
> -
> -	dev = find_vdev(name);
> -	if (!dev)
> -		return -ENOENT;
> -
> -	devargs = dev->device.devargs;
> -
> -	ret = vdev_remove_driver(dev);
> -	if (ret)
> -		return ret;
> -
> -	TAILQ_REMOVE(&vdev_device_list, dev, next);
> -
> -	TAILQ_REMOVE(&devargs_list, devargs, next);
> -
> -	free(devargs->args);
> -	free(devargs);
> -	free(dev);
> -	return 0;
> -}
> -
> -static int
> -vdev_scan(void)
> -{
> -	struct rte_vdev_device *dev;
> -	struct rte_devargs *devargs;
> -
> -	/* for virtual devices we scan the devargs_list populated via cmdline */
> -	TAILQ_FOREACH(devargs, &devargs_list, next) {
> -
> -		if (devargs->bus != &rte_vdev_bus)
> -			continue;
> -
> -		dev = find_vdev(devargs->name);
> -		if (dev)
> -			continue;
> -
> -		dev = calloc(1, sizeof(*dev));
> -		if (!dev)
> -			return -1;
> -
> -		dev->device.devargs = devargs;
> -		dev->device.numa_node = SOCKET_ID_ANY;
> -		dev->device.name = devargs->name;
> -
> -		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
> -	}
> -
> -	return 0;
> -}
> -
> -static int
> -vdev_probe(void)
> -{
> -	struct rte_vdev_device *dev;
> -
> -	/* call the init function for each virtual device */
> -	TAILQ_FOREACH(dev, &vdev_device_list, next) {
> -
> -		if (dev->device.driver)
> -			continue;
> -
> -		if (vdev_probe_all_drivers(dev)) {
> -			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
> -				rte_vdev_device_name(dev));
> -			return -1;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -static struct rte_device *
> -vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
> -		 const void *data)
> -{
> -	struct rte_vdev_device *dev;
> -
> -	TAILQ_FOREACH(dev, &vdev_device_list, next) {
> -		if (start && &dev->device == start) {
> -			start = NULL;
> -			continue;
> -		}
> -		if (cmp(&dev->device, data) == 0)
> -			return &dev->device;
> -	}
> -	return NULL;
> -}
> -
> -static int
> -vdev_plug(struct rte_device *dev)
> -{
> -	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
> -}
> -
> -static int
> -vdev_unplug(struct rte_device *dev)
> -{
> -	return rte_vdev_uninit(dev->name);
> -}
> -
> -static struct rte_bus rte_vdev_bus = {
> -	.scan = vdev_scan,
> -	.probe = vdev_probe,
> -	.find_device = vdev_find_device,
> -	.plug = vdev_plug,
> -	.unplug = vdev_unplug,
> -	.parse = vdev_parse,
> -};
> -
> -RTE_REGISTER_BUS(vdev, rte_vdev_bus);
> diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
> index 5386d3a..8bfc343 100644
> --- a/lib/librte_eal/common/include/rte_dev.h
> +++ b/lib/librte_eal/common/include/rte_dev.h
> @@ -166,28 +166,6 @@ struct rte_device {
>  };
>  
>  /**
> - * Initialize a driver specified by name.
> - *
> - * @param name
> - *   The pointer to a driver name to be initialized.
> - * @param args
> - *   The pointer to arguments used by driver initialization.
> - * @return
> - *  0 on success, negative on error
> - */
> -int rte_vdev_init(const char *name, const char *args);
> -
> -/**
> - * Uninitalize a driver specified by name.
> - *
> - * @param name
> - *   The pointer to a driver name to be initialized.
> - * @return
> - *  0 on success, negative on error
> - */
> -int rte_vdev_uninit(const char *name);
> -
> -/**
>   * Attach a device to a registered driver.
>   *
>   * @param name
> @@ -312,4 +290,4 @@ __attribute__((used)) = str
>  }
>  #endif
>  
> -#endif /* _RTE_VDEV_H_ */
> +#endif /* _RTE_DEV_H_ */
> diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
> deleted file mode 100644
> index 29f5a52..0000000
> --- a/lib/librte_eal/common/include/rte_vdev.h
> +++ /dev/null
> @@ -1,131 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2016 RehiveTech. All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of RehiveTech nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#ifndef RTE_VDEV_H
> -#define RTE_VDEV_H
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -#include <sys/queue.h>
> -#include <rte_dev.h>
> -#include <rte_devargs.h>
> -
> -struct rte_vdev_device {
> -	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
> -	struct rte_device device;               /**< Inherit core device */
> -};
> -
> -/**
> - * @internal
> - * Helper macro for drivers that need to convert to struct rte_vdev_device.
> - */
> -#define RTE_DEV_TO_VDEV(ptr) \
> -	container_of(ptr, struct rte_vdev_device, device)
> -
> -static inline const char *
> -rte_vdev_device_name(const struct rte_vdev_device *dev)
> -{
> -	if (dev && dev->device.name)
> -		return dev->device.name;
> -	return NULL;
> -}
> -
> -static inline const char *
> -rte_vdev_device_args(const struct rte_vdev_device *dev)
> -{
> -	if (dev && dev->device.devargs)
> -		return dev->device.devargs->args;
> -	return "";
> -}
> -
> -/** Double linked list of virtual device drivers. */
> -TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
> -
> -/**
> - * Probe function called for each virtual device driver once.
> - */
> -typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
> -
> -/**
> - * Remove function called for each virtual device driver once.
> - */
> -typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
> -
> -/**
> - * A virtual device driver abstraction.
> - */
> -struct rte_vdev_driver {
> -	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
> -	struct rte_driver driver;      /**< Inherited general driver. */
> -	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
> -	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
> -};
> -
> -/**
> - * Register a virtual device driver.
> - *
> - * @param driver
> - *   A pointer to a rte_vdev_driver structure describing the driver
> - *   to be registered.
> - */
> -void rte_vdev_register(struct rte_vdev_driver *driver);
> -
> -/**
> - * Unregister a virtual device driver.
> - *
> - * @param driver
> - *   A pointer to a rte_vdev_driver structure describing the driver
> - *   to be unregistered.
> - */
> -void rte_vdev_unregister(struct rte_vdev_driver *driver);
> -
> -#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
> -RTE_INIT(vdrvinitfn_ ##vdrv);\
> -static const char *vdrvinit_ ## nm ## _alias;\
> -static void vdrvinitfn_ ##vdrv(void)\
> -{\
> -	(vdrv).driver.name = RTE_STR(nm);\
> -	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
> -	rte_vdev_register(&vdrv);\
> -} \
> -RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
> -
> -#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
> -static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif
> diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
> index 90bca4d..33faa18 100644
> --- a/lib/librte_eal/linuxapp/eal/Makefile
> +++ b/lib/librte_eal/linuxapp/eal/Makefile
> @@ -80,7 +80,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
> -SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index c25fdd9..c423bf8 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -97,6 +97,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
>  _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV)           += -lrte_bus_vdev
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
>  
> -- 
> 2.7.4
> 

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 02/12] eal: avoid calling rte_vdev_init()
  2017-08-29 12:50   ` Gaëtan Rivet
@ 2017-08-29 22:25     ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-08-29 22:25 UTC (permalink / raw)
  To: Gaëtan Rivet
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

Hi Gaetan,


On 8/29/2017 5:50 AM, Gaëtan Rivet wrote:
> Hi,
>
> On Fri, Aug 25, 2017 at 09:40:42AM +0000, Jianfeng Tan wrote:
>> We can call bus->plug() to avoid calling rte_vdev_init() explicitly.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   lib/librte_eal/common/eal_common_dev.c | 21 +++++----------------
>>   1 file changed, 5 insertions(+), 16 deletions(-)
>>
>> diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
>> index e251275..066dfbf 100644
>> --- a/lib/librte_eal/common/eal_common_dev.c
>> +++ b/lib/librte_eal/common/eal_common_dev.c
>> @@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
>>   int rte_eal_dev_attach(const char *name, const char *devargs)
>>   {
>>   	struct rte_bus *bus;
>> -	int ret;
>>   
>>   	if (name == NULL || devargs == NULL) {
>>   		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
>> @@ -80,22 +79,12 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
>>   			name);
>>   		return -EINVAL;
>>   	}
>> -	if (strcmp(bus->name, "pci") == 0)
>> -		return rte_eal_hotplug_add("pci", name, devargs);
>> -	if (strcmp(bus->name, "vdev") != 0) {
>> -		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
>> -		return -ENOTSUP;
>> -	}
>> +	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") != 0)
> It seems to be a copy / paste error, it should probably be:
>
> +	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)

Nice catch. Will fix it in next version.

>
> Now, one could question the relevancy of keeping this API
> (rte_eal_dev_attach / detach), but I guess this is beyond the scope of
> this series.

This is a valid ask. It seems a duplication of 
rte_eal_hotplug_add()/rte_eal_hotplug_remove().

Thanks,
Jianfeng

>> +		return rte_eal_hotplug_add(bus->name, name, devargs);
>>   
>> -	/*
>> -	 * If we haven't found a bus device the user meant to "hotplug" a
>> -	 * virtual device instead.
>> -	 */
>> -	ret = rte_vdev_init(name, devargs);
>> -	if (ret)
>> -		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
>> -			name);
>> -	return ret;
>> +	RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
>> +
>> +	return -ENOTSUP;
>>   }
>>   
>>   int rte_eal_dev_detach(struct rte_device *dev)
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 05/12] bus/vdev: change log type from EAL to PMD
  2017-08-29 12:54   ` Gaëtan Rivet
@ 2017-08-29 22:27     ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-08-29 22:27 UTC (permalink / raw)
  To: Gaëtan Rivet
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit



On 8/29/2017 5:54 AM, Gaëtan Rivet wrote:
> On Fri, Aug 25, 2017 at 09:40:45AM +0000, Jianfeng Tan wrote:
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   drivers/bus/vdev/vdev.c      | 10 ++++++----
>>   drivers/bus/vdev/vdev_logs.h | 40 ++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 46 insertions(+), 4 deletions(-)
>>   create mode 100644 drivers/bus/vdev/vdev_logs.h
[...]
>> +
>> +#ifndef _VDEV_LOGS_H_
>> +#define _VDEV_LOGS_H_
>> +
>> +#define VDEV_LOG(level, fmt, args...) \
>> +	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)
> With the multiplication of bus implementations, wouldn't it be interesting
> to introduce an RTE_LOGTYPE_BUS?

Interesting! Let me try to do that in the next version.

Thanks,
Jianfeng

>> +
>> +#endif /* _VDEV_LOGS_H_ */
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 04/12] vdev: move to drivers/bus
  2017-08-29 13:04   ` Gaëtan Rivet
@ 2017-08-29 22:47     ` Tan, Jianfeng
  2017-09-18 11:47       ` De Lara Guarch, Pablo
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-08-29 22:47 UTC (permalink / raw)
  To: Gaëtan Rivet
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

Hi Gaetan,


On 8/29/2017 6:04 AM, Gaëtan Rivet wrote:
> On Fri, Aug 25, 2017 at 09:40:44AM +0000, Jianfeng Tan wrote:
>> Move the vdev bus from lib/librte_eal to drivers/bus.
>>
>> As the crypto vdev helper function refers to data structure
>> in rte_vdev.h, so we move those helper function into drivers/bus
>> too.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   config/common_base                        |   5 +
>>   drivers/bus/Makefile                      |   2 +
>>   drivers/bus/vdev/Makefile                 |  57 +++++
>>   drivers/bus/vdev/rte_bus_vdev_version.map |  10 +
>>   drivers/bus/vdev/rte_cryptodev_vdev.c     | 154 ++++++++++++++
>>   drivers/bus/vdev/rte_cryptodev_vdev.h     | 100 +++++++++
>>   drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
>>   drivers/bus/vdev/vdev.c                   | 342 ++++++++++++++++++++++++++++++
>>   lib/librte_cryptodev/Makefile             |   2 -
>>   lib/librte_cryptodev/rte_cryptodev_vdev.c | 154 --------------
>>   lib/librte_cryptodev/rte_cryptodev_vdev.h | 100 ---------
>>   lib/librte_eal/bsdapp/eal/Makefile        |   1 -
>>   lib/librte_eal/common/Makefile            |   2 +-
>>   lib/librte_eal/common/eal_common_vdev.c   | 342 ------------------------------
>>   lib/librte_eal/common/include/rte_dev.h   |  24 +--
>>   lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
>>   lib/librte_eal/linuxapp/eal/Makefile      |   1 -
>>   mk/rte.app.mk                             |   1 +
>>   18 files changed, 826 insertions(+), 755 deletions(-)
>>   create mode 100644 drivers/bus/vdev/Makefile
>>   create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
>>   create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.c
>>   create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.h
>>   create mode 100644 drivers/bus/vdev/rte_vdev.h
>>   create mode 100644 drivers/bus/vdev/vdev.c
>>   delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.c
>>   delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.h
>>   delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
>>   delete mode 100644 lib/librte_eal/common/include/rte_vdev.h
>>
>> diff --git a/config/common_base b/config/common_base
>> index 5e97a08..aca0994 100644
>> --- a/config/common_base
>> +++ b/config/common_base
>> @@ -750,3 +750,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
>>   # Compile the eventdev application
>>   #
>>   CONFIG_RTE_APP_EVENTDEV=y
>> +
>> +#
>> +# Compile the vdev bus
>> +#
>> +CONFIG_RTE_LIBRTE_VDEV=y
> Why not CONFIG_RTE_LIBRTE_VDEV_BUS?
> It would seem more consistent.

Was trying to be consistent with the directory name, drivers/bus/vdev. 
Do you think that directory should also be renamed?

>
>> diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
>> index 0224214..9b6d45e 100644
>> --- a/drivers/bus/Makefile
>> +++ b/drivers/bus/Makefile
>> @@ -35,4 +35,6 @@ core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
>>   DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
>>   DEPDIRS-fslmc = $(core-libs)
>>   
>> +DIRS-$(CONFIG_RTE_LIBRTE_VDEV) += vdev
>> +
>>   include $(RTE_SDK)/mk/rte.subdir.mk
>> diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
>> new file mode 100644
>> index 0000000..30c4813
>> --- /dev/null
>> +++ b/drivers/bus/vdev/Makefile
>> @@ -0,0 +1,57 @@
>> +#   BSD LICENSE
>> +#
>> +#   Copyright(c) 2017 Intel Corporation. All rights reserved.
>> +#   All rights reserved.
>> +#
>> +#   Redistribution and use in source and binary forms, with or without
>> +#   modification, are permitted provided that the following conditions
>> +#   are met:
>> +#
>> +#     * Redistributions of source code must retain the above copyright
>> +#       notice, this list of conditions and the following disclaimer.
>> +#     * Redistributions in binary form must reproduce the above copyright
>> +#       notice, this list of conditions and the following disclaimer in
>> +#       the documentation and/or other materials provided with the
>> +#       distribution.
>> +#     * Neither the name of Intel Corporation nor the names of its
>> +#       contributors may be used to endorse or promote products derived
>> +#       from this software without specific prior written permission.
>> +#
>> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> +
>> +include $(RTE_SDK)/mk/rte.vars.mk
>> +
>> +#
>> +# library name
>> +#
>> +LIB = librte_bus_vdev.a
>> +
>> +CFLAGS += -O3
>> +CFLAGS += $(WERROR_FLAGS)
>> +
>> +# versioning export map
>> +EXPORT_MAP := rte_bus_vdev_version.map
>> +
>> +# library version
>> +LIBABIVER := 1
>> +
>> +SRCS-y += vdev.c
>> +SRCS-y += rte_cryptodev_vdev.c
>> +
>> +#
>> +# Export include files
>> +#
>> +SYMLINK-y-include += rte_vdev.h
>> +SYMLINK-y-include += rte_cryptodev_vdev.h
>> +
> Let's say the cryptodev lib must be updated.
> I understand the need to move rte_cryptodev_vdev.h outside
> librte_cryptodev, but I guess this exposes the vdev bus to ABI / API
> instability due to a third-party subsystem?

Thank you for bringing up this question. I really don't want to move 
these crypto-specific files into bus/vdev/. It's just some helper 
functions to be called by crypto vdev drivers. And what's more, the only 
dependence on vdev is that the API rte_cryptodev_vdev_pmd_init() has a 
parameter of struct rte_vdev_device, which is totally not necessary, as 
it only needs a struct rte_device parameter.

In all, I'd prefer to change this specific API and move those 
crypto-specific files back to lib/librte_crypto (just like ether dev and 
eventdev); but it needs API change announcement.

Any thoughts?

>
> I did something somewhat similar for PCI:
> http://dpdk.org/ml/archives/dev/2017-August/073525.html

I prefer your way to move those things to specific dev folder.

>
> I don't know which solution is best, but something certainly needs to be
> done.
>
> ---
>
> Beside the `why`, about the `how`: shouldn't this file compilation and
> symlink be conditioned to CONFIG_RTE_LIBRTE_CRYPTODEV=y?
>
> i.e.: SYMLINK-$(CONFIG_RTE_LIBRTE_CRYPTODEV)-include += rte_cryptodev_vdev.h

Yes, make sense.

Thanks,
Jianfeng


>
>> +include $(RTE_SDK)/mk/rte.lib.mk
>> diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
>> new file mode 100644
>> index 0000000..69740c3
>> --- /dev/null
>> +++ b/drivers/bus/vdev/rte_bus_vdev_version.map
>> @@ -0,0 +1,10 @@
>> +DPDK_17.11 {
>> +	global:
>> +
>> +	rte_vdev_init;
>> +	rte_vdev_register;
>> +	rte_vdev_uninit;
>> +	rte_vdev_unregister;
>> +	rte_cryptodev_vdev_pmd_init
>> +	rte_cryptodev_vdev_parse_init_params
>> +};
>> diff --git a/drivers/bus/vdev/rte_cryptodev_vdev.c b/drivers/bus/vdev/rte_cryptodev_vdev.c
>> new file mode 100644
>> index 0000000..fd308b4
>> --- /dev/null
>> +++ b/drivers/bus/vdev/rte_cryptodev_vdev.c
>> @@ -0,0 +1,154 @@
>> +/*-
>> + *   BSD LICENSE
>> + *
>> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
>> + *
>> + *   Redistribution and use in source and binary forms, with or without
>> + *   modification, are permitted provided that the following conditions
>> + *   are met:
>> + *
>> + *     * Redistributions of source code must retain the above copyright
>> + *       notice, this list of conditions and the following disclaimer.
>> + *     * Redistributions in binary form must reproduce the above copyright
>> + *       notice, this list of conditions and the following disclaimer in
>> + *       the documentation and/or other materials provided with the
>> + *       distribution.
>> + *     * Neither the name of the copyright holder nor the names of its
>> + *       contributors may be used to endorse or promote products derived
>> + *       from this software without specific prior written permission.
>> + *
>> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>> +
>> +#include "rte_cryptodev_vdev.h"
>> +#include "rte_cryptodev_pci.h"
>> +#include "rte_cryptodev_pmd.h"
>> +
>> +/**
>> + * Parse name from argument
>> + */
>> +static int
>> +rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
>> +		const char *value, void *extra_args)
>> +{
>> +	struct rte_crypto_vdev_init_params *params = extra_args;
>> +
>> +	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
>> +		CDEV_LOG_ERR("Invalid name %s, should be less than "
>> +				"%u bytes", value,
>> +				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
>> +		return -1;
>> +	}
>> +
>> +	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * Parse integer from argument
>> + */
>> +static int
>> +rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
>> +		const char *value, void *extra_args)
>> +{
>> +	int *i = extra_args;
>> +
>> +	*i = atoi(value);
>> +	if (*i < 0) {
>> +		CDEV_LOG_ERR("Argument has to be positive.");
>> +		return -1;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +struct rte_cryptodev *
>> +rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
>> +		int socket_id, struct rte_vdev_device *vdev)
>> +{
>> +	struct rte_cryptodev *cryptodev;
>> +
>> +	/* allocate device structure */
>> +	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
>> +	if (cryptodev == NULL)
>> +		return NULL;
>> +
>> +	/* allocate private device structure */
>> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
>> +		cryptodev->data->dev_private =
>> +				rte_zmalloc_socket("cryptodev device private",
>> +						dev_private_size,
>> +						RTE_CACHE_LINE_SIZE,
>> +						socket_id);
>> +
>> +		if (cryptodev->data->dev_private == NULL)
>> +			rte_panic("Cannot allocate memzone for private device"
>> +					" data");
>> +	}
>> +
>> +	cryptodev->device = &vdev->device;
>> +
>> +	/* initialise user call-back tail queue */
>> +	TAILQ_INIT(&(cryptodev->link_intr_cbs));
>> +
>> +	return cryptodev;
>> +}
>> +
>> +int
>> +rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
>> +		const char *input_args)
>> +{
>> +	struct rte_kvargs *kvlist = NULL;
>> +	int ret = 0;
>> +
>> +	if (params == NULL)
>> +		return -EINVAL;
>> +
>> +	if (input_args) {
>> +		kvlist = rte_kvargs_parse(input_args,
>> +				cryptodev_vdev_valid_params);
>> +		if (kvlist == NULL)
>> +			return -1;
>> +
>> +		ret = rte_kvargs_process(kvlist,
>> +					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
>> +					&rte_cryptodev_vdev_parse_integer_arg,
>> +					&params->max_nb_queue_pairs);
>> +		if (ret < 0)
>> +			goto free_kvlist;
>> +
>> +		ret = rte_kvargs_process(kvlist,
>> +					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
>> +					&rte_cryptodev_vdev_parse_integer_arg,
>> +					&params->max_nb_sessions);
>> +		if (ret < 0)
>> +			goto free_kvlist;
>> +
>> +		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
>> +					&rte_cryptodev_vdev_parse_integer_arg,
>> +					&params->socket_id);
>> +		if (ret < 0)
>> +			goto free_kvlist;
>> +
>> +		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
>> +					&rte_cryptodev_vdev_parse_name_arg,
>> +					params);
>> +		if (ret < 0)
>> +			goto free_kvlist;
>> +	}
>> +
>> +free_kvlist:
>> +	rte_kvargs_free(kvlist);
>> +	return ret;
>> +}
>> diff --git a/drivers/bus/vdev/rte_cryptodev_vdev.h b/drivers/bus/vdev/rte_cryptodev_vdev.h
>> new file mode 100644
>> index 0000000..94ab9d3
>> --- /dev/null
>> +++ b/drivers/bus/vdev/rte_cryptodev_vdev.h
>> @@ -0,0 +1,100 @@
>> +/*-
>> + *   BSD LICENSE
>> + *
>> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
>> + *
>> + *   Redistribution and use in source and binary forms, with or without
>> + *   modification, are permitted provided that the following conditions
>> + *   are met:
>> + *
>> + *     * Redistributions of source code must retain the above copyright
>> + *       notice, this list of conditions and the following disclaimer.
>> + *     * Redistributions in binary form must reproduce the above copyright
>> + *       notice, this list of conditions and the following disclaimer in
>> + *       the documentation and/or other materials provided with the
>> + *       distribution.
>> + *     * Neither the name of the copyright holder nor the names of its
>> + *       contributors may be used to endorse or promote products derived
>> + *       from this software without specific prior written permission.
>> + *
>> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>> +
>> +#ifndef _RTE_CRYPTODEV_VDEV_H_
>> +#define _RTE_CRYPTODEV_VDEV_H_
>> +
>> +#include <rte_vdev.h>
>> +#include <inttypes.h>
>> +
>> +#include "rte_cryptodev.h"
>> +
>> +#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS	8
>> +#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS	2048
>> +
>> +#define RTE_CRYPTODEV_VDEV_NAME				("name")
>> +#define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG		("max_nb_queue_pairs")
>> +#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG		("max_nb_sessions")
>> +#define RTE_CRYPTODEV_VDEV_SOCKET_ID			("socket_id")
>> +
>> +static const char * const cryptodev_vdev_valid_params[] = {
>> +	RTE_CRYPTODEV_VDEV_NAME,
>> +	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
>> +	RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
>> +	RTE_CRYPTODEV_VDEV_SOCKET_ID
>> +};
>> +
>> +/**
>> + * @internal
>> + * Initialisation parameters for virtual crypto devices
>> + */
>> +struct rte_crypto_vdev_init_params {
>> +	unsigned int max_nb_queue_pairs;
>> +	unsigned int max_nb_sessions;
>> +	uint8_t socket_id;
>> +	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
>> +};
>> +
>> +/**
>> + * @internal
>> + * Creates a new virtual crypto device and returns the pointer
>> + * to that device.
>> + *
>> + * @param	name			PMD type name
>> + * @param	dev_private_size	Size of crypto PMDs private data
>> + * @param	socket_id		Socket to allocate resources on.
>> + * @param	vdev			Pointer to virtual device structure.
>> + *
>> + * @return
>> + *   - Cryptodev pointer if device is successfully created.
>> + *   - NULL if device cannot be created.
>> + */
>> +struct rte_cryptodev *
>> +rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
>> +		int socket_id, struct rte_vdev_device *vdev);
>> +
>> +/**
>> + * @internal
>> + * Parse virtual device initialisation parameters input arguments
>> + *
>> + * @params	params		Initialisation parameters with defaults set.
>> + * @params	input_args	Command line arguments
>> + *
>> + * @return
>> + * 0 on successful parse
>> + * <0 on failure to parse
>> + */
>> +int
>> +rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
>> +		const char *input_args);
>> +
>> +#endif /* _RTE_CRYPTODEV_VDEV_H_ */
>> diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
>> new file mode 100644
>> index 0000000..41762b8
>> --- /dev/null
>> +++ b/drivers/bus/vdev/rte_vdev.h
>> @@ -0,0 +1,153 @@
>> +/*-
>> + *   BSD LICENSE
>> + *
>> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
>> + *
>> + *   Redistribution and use in source and binary forms, with or without
>> + *   modification, are permitted provided that the following conditions
>> + *   are met:
>> + *
>> + *     * Redistributions of source code must retain the above copyright
>> + *       notice, this list of conditions and the following disclaimer.
>> + *     * Redistributions in binary form must reproduce the above copyright
>> + *       notice, this list of conditions and the following disclaimer in
>> + *       the documentation and/or other materials provided with the
>> + *       distribution.
>> + *     * Neither the name of RehiveTech nor the names of its
>> + *       contributors may be used to endorse or promote products derived
>> + *       from this software without specific prior written permission.
>> + *
>> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>> +
>> +#ifndef RTE_VDEV_H
>> +#define RTE_VDEV_H
>> +
>> +#ifdef __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +#include <sys/queue.h>
>> +#include <rte_dev.h>
>> +#include <rte_devargs.h>
>> +
>> +struct rte_vdev_device {
>> +	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
>> +	struct rte_device device;               /**< Inherit core device */
>> +};
>> +
>> +/**
>> + * @internal
>> + * Helper macro for drivers that need to convert to struct rte_vdev_device.
>> + */
>> +#define RTE_DEV_TO_VDEV(ptr) \
>> +	container_of(ptr, struct rte_vdev_device, device)
>> +
>> +static inline const char *
>> +rte_vdev_device_name(const struct rte_vdev_device *dev)
>> +{
>> +	if (dev && dev->device.name)
>> +		return dev->device.name;
>> +	return NULL;
>> +}
>> +
>> +static inline const char *
>> +rte_vdev_device_args(const struct rte_vdev_device *dev)
>> +{
>> +	if (dev && dev->device.devargs)
>> +		return dev->device.devargs->args;
>> +	return "";
>> +}
>> +
>> +/** Double linked list of virtual device drivers. */
>> +TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
>> +
>> +/**
>> + * Probe function called for each virtual device driver once.
>> + */
>> +typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
>> +
>> +/**
>> + * Remove function called for each virtual device driver once.
>> + */
>> +typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
>> +
>> +/**
>> + * A virtual device driver abstraction.
>> + */
>> +struct rte_vdev_driver {
>> +	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
>> +	struct rte_driver driver;      /**< Inherited general driver. */
>> +	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
>> +	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
>> +};
>> +
>> +/**
>> + * Register a virtual device driver.
>> + *
>> + * @param driver
>> + *   A pointer to a rte_vdev_driver structure describing the driver
>> + *   to be registered.
>> + */
>> +void rte_vdev_register(struct rte_vdev_driver *driver);
>> +
>> +/**
>> + * Unregister a virtual device driver.
>> + *
>> + * @param driver
>> + *   A pointer to a rte_vdev_driver structure describing the driver
>> + *   to be unregistered.
>> + */
>> +void rte_vdev_unregister(struct rte_vdev_driver *driver);
>> +
>> +#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
>> +RTE_INIT(vdrvinitfn_ ##vdrv);\
>> +static const char *vdrvinit_ ## nm ## _alias;\
>> +static void vdrvinitfn_ ##vdrv(void)\
>> +{\
>> +	(vdrv).driver.name = RTE_STR(nm);\
>> +	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
>> +	rte_vdev_register(&vdrv);\
>> +} \
>> +RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
>> +
>> +#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
>> +static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
>> +
>> +/**
>> + * Initialize a driver specified by name.
>> + *
>> + * @param name
>> + *   The pointer to a driver name to be initialized.
>> + * @param args
>> + *   The pointer to arguments used by driver initialization.
>> + * @return
>> + *  0 on success, negative on error
>> + */
>> +int rte_vdev_init(const char *name, const char *args);
>> +
>> +/**
>> + * Uninitalize a driver specified by name.
>> + *
>> + * @param name
>> + *   The pointer to a driver name to be initialized.
>> + * @return
>> + *  0 on success, negative on error
>> + */
>> +int rte_vdev_uninit(const char *name);
>> +
>> +#ifdef __cplusplus
>> +}
>> +#endif
>> +
>> +#endif
>> diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
>> new file mode 100644
>> index 0000000..f7e547a
>> --- /dev/null
>> +++ b/drivers/bus/vdev/vdev.c
>> @@ -0,0 +1,342 @@
>> +/*-
>> + *   BSD LICENSE
>> + *
>> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
>> + *
>> + *   Redistribution and use in source and binary forms, with or without
>> + *   modification, are permitted provided that the following conditions
>> + *   are met:
>> + *
>> + *     * Redistributions of source code must retain the above copyright
>> + *       notice, this list of conditions and the following disclaimer.
>> + *     * Redistributions in binary form must reproduce the above copyright
>> + *       notice, this list of conditions and the following disclaimer in
>> + *       the documentation and/or other materials provided with the
>> + *       distribution.
>> + *     * Neither the name of RehiveTech nor the names of its
>> + *       contributors may be used to endorse or promote products derived
>> + *       from this software without specific prior written permission.
>> + *
>> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>> +
>> +#include <string.h>
>> +#include <inttypes.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <stdint.h>
>> +#include <stdbool.h>
>> +#include <sys/queue.h>
>> +
>> +#include <rte_eal.h>
>> +#include <rte_dev.h>
>> +#include <rte_bus.h>
>> +#include <rte_vdev.h>
>> +#include <rte_common.h>
>> +#include <rte_devargs.h>
>> +#include <rte_memory.h>
>> +#include <rte_errno.h>
>> +
>> +/* Forward declare to access virtual bus name */
>> +static struct rte_bus rte_vdev_bus;
>> +
>> +/** Double linked list of virtual device drivers. */
>> +TAILQ_HEAD(vdev_device_list, rte_vdev_device);
>> +
>> +static struct vdev_device_list vdev_device_list =
>> +	TAILQ_HEAD_INITIALIZER(vdev_device_list);
>> +struct vdev_driver_list vdev_driver_list =
>> +	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
>> +
>> +/* register a driver */
>> +void
>> +rte_vdev_register(struct rte_vdev_driver *driver)
>> +{
>> +	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
>> +}
>> +
>> +/* unregister a driver */
>> +void
>> +rte_vdev_unregister(struct rte_vdev_driver *driver)
>> +{
>> +	TAILQ_REMOVE(&vdev_driver_list, driver, next);
>> +}
>> +
>> +static int
>> +vdev_parse(const char *name, void *addr)
>> +{
>> +	struct rte_vdev_driver **out = addr;
>> +	struct rte_vdev_driver *driver = NULL;
>> +
>> +	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
>> +		if (strncmp(driver->driver.name, name,
>> +			    strlen(driver->driver.name)) == 0)
>> +			break;
>> +		if (driver->driver.alias &&
>> +		    strncmp(driver->driver.alias, name,
>> +			    strlen(driver->driver.alias)) == 0)
>> +			break;
>> +	}
>> +	if (driver != NULL &&
>> +	    addr != NULL)
>> +		*out = driver;
>> +	return driver == NULL;
>> +}
>> +
>> +static int
>> +vdev_probe_all_drivers(struct rte_vdev_device *dev)
>> +{
>> +	const char *name;
>> +	struct rte_vdev_driver *driver;
>> +	int ret;
>> +
>> +	name = rte_vdev_device_name(dev);
>> +
>> +	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
>> +		rte_vdev_device_name(dev));
>> +
>> +	if (vdev_parse(name, &driver))
>> +		return -1;
>> +	dev->device.driver = &driver->driver;
>> +	ret = driver->probe(dev);
>> +	if (ret)
>> +		dev->device.driver = NULL;
>> +	return ret;
>> +}
>> +
>> +static struct rte_vdev_device *
>> +find_vdev(const char *name)
>> +{
>> +	struct rte_vdev_device *dev;
>> +
>> +	if (!name)
>> +		return NULL;
>> +
>> +	TAILQ_FOREACH(dev, &vdev_device_list, next) {
>> +		const char *devname = rte_vdev_device_name(dev);
>> +		if (!strncmp(devname, name, strlen(name)))
>> +			return dev;
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +static struct rte_devargs *
>> +alloc_devargs(const char *name, const char *args)
>> +{
>> +	struct rte_devargs *devargs;
>> +	int ret;
>> +
>> +	devargs = calloc(1, sizeof(*devargs));
>> +	if (!devargs)
>> +		return NULL;
>> +
>> +	devargs->bus = &rte_vdev_bus;
>> +	if (args)
>> +		devargs->args = strdup(args);
>> +	else
>> +		devargs->args = strdup("");
>> +
>> +	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
>> +	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
>> +		free(devargs->args);
>> +		free(devargs);
>> +		return NULL;
>> +	}
>> +
>> +	return devargs;
>> +}
>> +
>> +int
>> +rte_vdev_init(const char *name, const char *args)
>> +{
>> +	struct rte_vdev_device *dev;
>> +	struct rte_devargs *devargs;
>> +	int ret;
>> +
>> +	if (name == NULL)
>> +		return -EINVAL;
>> +
>> +	dev = find_vdev(name);
>> +	if (dev)
>> +		return -EEXIST;
>> +
>> +	devargs = alloc_devargs(name, args);
>> +	if (!devargs)
>> +		return -ENOMEM;
>> +
>> +	dev = calloc(1, sizeof(*dev));
>> +	if (!dev) {
>> +		ret = -ENOMEM;
>> +		goto fail;
>> +	}
>> +
>> +	dev->device.devargs = devargs;
>> +	dev->device.numa_node = SOCKET_ID_ANY;
>> +	dev->device.name = devargs->name;
>> +
>> +	ret = vdev_probe_all_drivers(dev);
>> +	if (ret) {
>> +		if (ret > 0)
>> +			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
>> +		goto fail;
>> +	}
>> +
>> +	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
>> +
>> +	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
>> +	return 0;
>> +
>> +fail:
>> +	free(devargs->args);
>> +	free(devargs);
>> +	free(dev);
>> +	return ret;
>> +}
>> +
>> +static int
>> +vdev_remove_driver(struct rte_vdev_device *dev)
>> +{
>> +	const char *name = rte_vdev_device_name(dev);
>> +	const struct rte_vdev_driver *driver;
>> +
>> +	if (!dev->device.driver) {
>> +		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
>> +		return 1;
>> +	}
>> +
>> +	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
>> +		driver);
>> +	return driver->remove(dev);
>> +}
>> +
>> +int
>> +rte_vdev_uninit(const char *name)
>> +{
>> +	struct rte_vdev_device *dev;
>> +	struct rte_devargs *devargs;
>> +	int ret;
>> +
>> +	if (name == NULL)
>> +		return -EINVAL;
>> +
>> +	dev = find_vdev(name);
>> +	if (!dev)
>> +		return -ENOENT;
>> +
>> +	devargs = dev->device.devargs;
>> +
>> +	ret = vdev_remove_driver(dev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	TAILQ_REMOVE(&vdev_device_list, dev, next);
>> +
>> +	TAILQ_REMOVE(&devargs_list, devargs, next);
>> +
>> +	free(devargs->args);
>> +	free(devargs);
>> +	free(dev);
>> +	return 0;
>> +}
>> +
>> +static int
>> +vdev_scan(void)
>> +{
>> +	struct rte_vdev_device *dev;
>> +	struct rte_devargs *devargs;
>> +
>> +	/* for virtual devices we scan the devargs_list populated via cmdline */
>> +	TAILQ_FOREACH(devargs, &devargs_list, next) {
>> +
>> +		if (devargs->bus != &rte_vdev_bus)
>> +			continue;
>> +
>> +		dev = find_vdev(devargs->name);
>> +		if (dev)
>> +			continue;
>> +
>> +		dev = calloc(1, sizeof(*dev));
>> +		if (!dev)
>> +			return -1;
>> +
>> +		dev->device.devargs = devargs;
>> +		dev->device.numa_node = SOCKET_ID_ANY;
>> +		dev->device.name = devargs->name;
>> +
>> +		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int
>> +vdev_probe(void)
>> +{
>> +	struct rte_vdev_device *dev;
>> +
>> +	/* call the init function for each virtual device */
>> +	TAILQ_FOREACH(dev, &vdev_device_list, next) {
>> +
>> +		if (dev->device.driver)
>> +			continue;
>> +
>> +		if (vdev_probe_all_drivers(dev)) {
>> +			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
>> +				rte_vdev_device_name(dev));
>> +			return -1;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static struct rte_device *
>> +vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
>> +		 const void *data)
>> +{
>> +	struct rte_vdev_device *dev;
>> +
>> +	TAILQ_FOREACH(dev, &vdev_device_list, next) {
>> +		if (start && &dev->device == start) {
>> +			start = NULL;
>> +			continue;
>> +		}
>> +		if (cmp(&dev->device, data) == 0)
>> +			return &dev->device;
>> +	}
>> +	return NULL;
>> +}
>> +
>> +static int
>> +vdev_plug(struct rte_device *dev)
>> +{
>> +	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
>> +}
>> +
>> +static int
>> +vdev_unplug(struct rte_device *dev)
>> +{
>> +	return rte_vdev_uninit(dev->name);
>> +}
>> +
>> +static struct rte_bus rte_vdev_bus = {
>> +	.scan = vdev_scan,
>> +	.probe = vdev_probe,
>> +	.find_device = vdev_find_device,
>> +	.plug = vdev_plug,
>> +	.unplug = vdev_unplug,
>> +	.parse = vdev_parse,
>> +};
>> +
>> +RTE_REGISTER_BUS(vdev, rte_vdev_bus);
>> diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
>> index 301c78d..4f70719 100644
>> --- a/lib/librte_cryptodev/Makefile
>> +++ b/lib/librte_cryptodev/Makefile
>> @@ -42,14 +42,12 @@ CFLAGS += $(WERROR_FLAGS)
>>   
>>   # library source files
>>   SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c
>> -SRCS-y += rte_cryptodev_vdev.c
>>   
>>   # export include files
>>   SYMLINK-y-include += rte_crypto.h
>>   SYMLINK-y-include += rte_crypto_sym.h
>>   SYMLINK-y-include += rte_cryptodev.h
>>   SYMLINK-y-include += rte_cryptodev_pmd.h
>> -SYMLINK-y-include += rte_cryptodev_vdev.h
>>   SYMLINK-y-include += rte_cryptodev_pci.h
>>   
>>   # versioning export map
>> diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.c b/lib/librte_cryptodev/rte_cryptodev_vdev.c
>> deleted file mode 100644
>> index fd308b4..0000000
>> --- a/lib/librte_cryptodev/rte_cryptodev_vdev.c
>> +++ /dev/null
>> @@ -1,154 +0,0 @@
>> -/*-
>> - *   BSD LICENSE
>> - *
>> - *   Copyright(c) 2017 Intel Corporation. All rights reserved.
>> - *
>> - *   Redistribution and use in source and binary forms, with or without
>> - *   modification, are permitted provided that the following conditions
>> - *   are met:
>> - *
>> - *     * Redistributions of source code must retain the above copyright
>> - *       notice, this list of conditions and the following disclaimer.
>> - *     * Redistributions in binary form must reproduce the above copyright
>> - *       notice, this list of conditions and the following disclaimer in
>> - *       the documentation and/or other materials provided with the
>> - *       distribution.
>> - *     * Neither the name of the copyright holder nor the names of its
>> - *       contributors may be used to endorse or promote products derived
>> - *       from this software without specific prior written permission.
>> - *
>> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> - */
>> -
>> -#include "rte_cryptodev_vdev.h"
>> -#include "rte_cryptodev_pci.h"
>> -#include "rte_cryptodev_pmd.h"
>> -
>> -/**
>> - * Parse name from argument
>> - */
>> -static int
>> -rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
>> -		const char *value, void *extra_args)
>> -{
>> -	struct rte_crypto_vdev_init_params *params = extra_args;
>> -
>> -	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
>> -		CDEV_LOG_ERR("Invalid name %s, should be less than "
>> -				"%u bytes", value,
>> -				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
>> -		return -1;
>> -	}
>> -
>> -	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
>> -
>> -	return 0;
>> -}
>> -
>> -/**
>> - * Parse integer from argument
>> - */
>> -static int
>> -rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
>> -		const char *value, void *extra_args)
>> -{
>> -	int *i = extra_args;
>> -
>> -	*i = atoi(value);
>> -	if (*i < 0) {
>> -		CDEV_LOG_ERR("Argument has to be positive.");
>> -		return -1;
>> -	}
>> -
>> -	return 0;
>> -}
>> -
>> -struct rte_cryptodev *
>> -rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
>> -		int socket_id, struct rte_vdev_device *vdev)
>> -{
>> -	struct rte_cryptodev *cryptodev;
>> -
>> -	/* allocate device structure */
>> -	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
>> -	if (cryptodev == NULL)
>> -		return NULL;
>> -
>> -	/* allocate private device structure */
>> -	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
>> -		cryptodev->data->dev_private =
>> -				rte_zmalloc_socket("cryptodev device private",
>> -						dev_private_size,
>> -						RTE_CACHE_LINE_SIZE,
>> -						socket_id);
>> -
>> -		if (cryptodev->data->dev_private == NULL)
>> -			rte_panic("Cannot allocate memzone for private device"
>> -					" data");
>> -	}
>> -
>> -	cryptodev->device = &vdev->device;
>> -
>> -	/* initialise user call-back tail queue */
>> -	TAILQ_INIT(&(cryptodev->link_intr_cbs));
>> -
>> -	return cryptodev;
>> -}
>> -
>> -int
>> -rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
>> -		const char *input_args)
>> -{
>> -	struct rte_kvargs *kvlist = NULL;
>> -	int ret = 0;
>> -
>> -	if (params == NULL)
>> -		return -EINVAL;
>> -
>> -	if (input_args) {
>> -		kvlist = rte_kvargs_parse(input_args,
>> -				cryptodev_vdev_valid_params);
>> -		if (kvlist == NULL)
>> -			return -1;
>> -
>> -		ret = rte_kvargs_process(kvlist,
>> -					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
>> -					&rte_cryptodev_vdev_parse_integer_arg,
>> -					&params->max_nb_queue_pairs);
>> -		if (ret < 0)
>> -			goto free_kvlist;
>> -
>> -		ret = rte_kvargs_process(kvlist,
>> -					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
>> -					&rte_cryptodev_vdev_parse_integer_arg,
>> -					&params->max_nb_sessions);
>> -		if (ret < 0)
>> -			goto free_kvlist;
>> -
>> -		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
>> -					&rte_cryptodev_vdev_parse_integer_arg,
>> -					&params->socket_id);
>> -		if (ret < 0)
>> -			goto free_kvlist;
>> -
>> -		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
>> -					&rte_cryptodev_vdev_parse_name_arg,
>> -					params);
>> -		if (ret < 0)
>> -			goto free_kvlist;
>> -	}
>> -
>> -free_kvlist:
>> -	rte_kvargs_free(kvlist);
>> -	return ret;
>> -}
>> diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.h b/lib/librte_cryptodev/rte_cryptodev_vdev.h
>> deleted file mode 100644
>> index 94ab9d3..0000000
>> --- a/lib/librte_cryptodev/rte_cryptodev_vdev.h
>> +++ /dev/null
>> @@ -1,100 +0,0 @@
>> -/*-
>> - *   BSD LICENSE
>> - *
>> - *   Copyright(c) 2017 Intel Corporation. All rights reserved.
>> - *
>> - *   Redistribution and use in source and binary forms, with or without
>> - *   modification, are permitted provided that the following conditions
>> - *   are met:
>> - *
>> - *     * Redistributions of source code must retain the above copyright
>> - *       notice, this list of conditions and the following disclaimer.
>> - *     * Redistributions in binary form must reproduce the above copyright
>> - *       notice, this list of conditions and the following disclaimer in
>> - *       the documentation and/or other materials provided with the
>> - *       distribution.
>> - *     * Neither the name of the copyright holder nor the names of its
>> - *       contributors may be used to endorse or promote products derived
>> - *       from this software without specific prior written permission.
>> - *
>> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> - */
>> -
>> -#ifndef _RTE_CRYPTODEV_VDEV_H_
>> -#define _RTE_CRYPTODEV_VDEV_H_
>> -
>> -#include <rte_vdev.h>
>> -#include <inttypes.h>
>> -
>> -#include "rte_cryptodev.h"
>> -
>> -#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS	8
>> -#define RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS	2048
>> -
>> -#define RTE_CRYPTODEV_VDEV_NAME				("name")
>> -#define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG		("max_nb_queue_pairs")
>> -#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG		("max_nb_sessions")
>> -#define RTE_CRYPTODEV_VDEV_SOCKET_ID			("socket_id")
>> -
>> -static const char * const cryptodev_vdev_valid_params[] = {
>> -	RTE_CRYPTODEV_VDEV_NAME,
>> -	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
>> -	RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
>> -	RTE_CRYPTODEV_VDEV_SOCKET_ID
>> -};
>> -
>> -/**
>> - * @internal
>> - * Initialisation parameters for virtual crypto devices
>> - */
>> -struct rte_crypto_vdev_init_params {
>> -	unsigned int max_nb_queue_pairs;
>> -	unsigned int max_nb_sessions;
>> -	uint8_t socket_id;
>> -	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
>> -};
>> -
>> -/**
>> - * @internal
>> - * Creates a new virtual crypto device and returns the pointer
>> - * to that device.
>> - *
>> - * @param	name			PMD type name
>> - * @param	dev_private_size	Size of crypto PMDs private data
>> - * @param	socket_id		Socket to allocate resources on.
>> - * @param	vdev			Pointer to virtual device structure.
>> - *
>> - * @return
>> - *   - Cryptodev pointer if device is successfully created.
>> - *   - NULL if device cannot be created.
>> - */
>> -struct rte_cryptodev *
>> -rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
>> -		int socket_id, struct rte_vdev_device *vdev);
>> -
>> -/**
>> - * @internal
>> - * Parse virtual device initialisation parameters input arguments
>> - *
>> - * @params	params		Initialisation parameters with defaults set.
>> - * @params	input_args	Command line arguments
>> - *
>> - * @return
>> - * 0 on successful parse
>> - * <0 on failure to parse
>> - */
>> -int
>> -rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
>> -		const char *input_args);
>> -
>> -#endif /* _RTE_CRYPTODEV_VDEV_H_ */
>> diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
>> index 005019e..6fee587 100644
>> --- a/lib/librte_eal/bsdapp/eal/Makefile
>> +++ b/lib/librte_eal/bsdapp/eal/Makefile
>> @@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
>> -SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
>> diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
>> index e8fd67a..7eeb06a 100644
>> --- a/lib/librte_eal/common/Makefile
>> +++ b/lib/librte_eal/common/Makefile
>> @@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
>>   INC += rte_tailq.h rte_interrupts.h rte_alarm.h
>>   INC += rte_string_fns.h rte_version.h
>>   INC += rte_eal_memconfig.h rte_malloc_heap.h
>> -INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
>> +INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
>>   INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
>>   INC += rte_malloc.h rte_keepalive.h rte_time.h
>>   INC += rte_service.h rte_service_component.h
>> diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
>> deleted file mode 100644
>> index f7e547a..0000000
>> --- a/lib/librte_eal/common/eal_common_vdev.c
>> +++ /dev/null
>> @@ -1,342 +0,0 @@
>> -/*-
>> - *   BSD LICENSE
>> - *
>> - *   Copyright(c) 2016 RehiveTech. All rights reserved.
>> - *
>> - *   Redistribution and use in source and binary forms, with or without
>> - *   modification, are permitted provided that the following conditions
>> - *   are met:
>> - *
>> - *     * Redistributions of source code must retain the above copyright
>> - *       notice, this list of conditions and the following disclaimer.
>> - *     * Redistributions in binary form must reproduce the above copyright
>> - *       notice, this list of conditions and the following disclaimer in
>> - *       the documentation and/or other materials provided with the
>> - *       distribution.
>> - *     * Neither the name of RehiveTech nor the names of its
>> - *       contributors may be used to endorse or promote products derived
>> - *       from this software without specific prior written permission.
>> - *
>> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> - */
>> -
>> -#include <string.h>
>> -#include <inttypes.h>
>> -#include <stdio.h>
>> -#include <stdlib.h>
>> -#include <stdint.h>
>> -#include <stdbool.h>
>> -#include <sys/queue.h>
>> -
>> -#include <rte_eal.h>
>> -#include <rte_dev.h>
>> -#include <rte_bus.h>
>> -#include <rte_vdev.h>
>> -#include <rte_common.h>
>> -#include <rte_devargs.h>
>> -#include <rte_memory.h>
>> -#include <rte_errno.h>
>> -
>> -/* Forward declare to access virtual bus name */
>> -static struct rte_bus rte_vdev_bus;
>> -
>> -/** Double linked list of virtual device drivers. */
>> -TAILQ_HEAD(vdev_device_list, rte_vdev_device);
>> -
>> -static struct vdev_device_list vdev_device_list =
>> -	TAILQ_HEAD_INITIALIZER(vdev_device_list);
>> -struct vdev_driver_list vdev_driver_list =
>> -	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
>> -
>> -/* register a driver */
>> -void
>> -rte_vdev_register(struct rte_vdev_driver *driver)
>> -{
>> -	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
>> -}
>> -
>> -/* unregister a driver */
>> -void
>> -rte_vdev_unregister(struct rte_vdev_driver *driver)
>> -{
>> -	TAILQ_REMOVE(&vdev_driver_list, driver, next);
>> -}
>> -
>> -static int
>> -vdev_parse(const char *name, void *addr)
>> -{
>> -	struct rte_vdev_driver **out = addr;
>> -	struct rte_vdev_driver *driver = NULL;
>> -
>> -	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
>> -		if (strncmp(driver->driver.name, name,
>> -			    strlen(driver->driver.name)) == 0)
>> -			break;
>> -		if (driver->driver.alias &&
>> -		    strncmp(driver->driver.alias, name,
>> -			    strlen(driver->driver.alias)) == 0)
>> -			break;
>> -	}
>> -	if (driver != NULL &&
>> -	    addr != NULL)
>> -		*out = driver;
>> -	return driver == NULL;
>> -}
>> -
>> -static int
>> -vdev_probe_all_drivers(struct rte_vdev_device *dev)
>> -{
>> -	const char *name;
>> -	struct rte_vdev_driver *driver;
>> -	int ret;
>> -
>> -	name = rte_vdev_device_name(dev);
>> -
>> -	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
>> -		rte_vdev_device_name(dev));
>> -
>> -	if (vdev_parse(name, &driver))
>> -		return -1;
>> -	dev->device.driver = &driver->driver;
>> -	ret = driver->probe(dev);
>> -	if (ret)
>> -		dev->device.driver = NULL;
>> -	return ret;
>> -}
>> -
>> -static struct rte_vdev_device *
>> -find_vdev(const char *name)
>> -{
>> -	struct rte_vdev_device *dev;
>> -
>> -	if (!name)
>> -		return NULL;
>> -
>> -	TAILQ_FOREACH(dev, &vdev_device_list, next) {
>> -		const char *devname = rte_vdev_device_name(dev);
>> -		if (!strncmp(devname, name, strlen(name)))
>> -			return dev;
>> -	}
>> -
>> -	return NULL;
>> -}
>> -
>> -static struct rte_devargs *
>> -alloc_devargs(const char *name, const char *args)
>> -{
>> -	struct rte_devargs *devargs;
>> -	int ret;
>> -
>> -	devargs = calloc(1, sizeof(*devargs));
>> -	if (!devargs)
>> -		return NULL;
>> -
>> -	devargs->bus = &rte_vdev_bus;
>> -	if (args)
>> -		devargs->args = strdup(args);
>> -	else
>> -		devargs->args = strdup("");
>> -
>> -	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
>> -	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
>> -		free(devargs->args);
>> -		free(devargs);
>> -		return NULL;
>> -	}
>> -
>> -	return devargs;
>> -}
>> -
>> -int
>> -rte_vdev_init(const char *name, const char *args)
>> -{
>> -	struct rte_vdev_device *dev;
>> -	struct rte_devargs *devargs;
>> -	int ret;
>> -
>> -	if (name == NULL)
>> -		return -EINVAL;
>> -
>> -	dev = find_vdev(name);
>> -	if (dev)
>> -		return -EEXIST;
>> -
>> -	devargs = alloc_devargs(name, args);
>> -	if (!devargs)
>> -		return -ENOMEM;
>> -
>> -	dev = calloc(1, sizeof(*dev));
>> -	if (!dev) {
>> -		ret = -ENOMEM;
>> -		goto fail;
>> -	}
>> -
>> -	dev->device.devargs = devargs;
>> -	dev->device.numa_node = SOCKET_ID_ANY;
>> -	dev->device.name = devargs->name;
>> -
>> -	ret = vdev_probe_all_drivers(dev);
>> -	if (ret) {
>> -		if (ret > 0)
>> -			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
>> -		goto fail;
>> -	}
>> -
>> -	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
>> -
>> -	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
>> -	return 0;
>> -
>> -fail:
>> -	free(devargs->args);
>> -	free(devargs);
>> -	free(dev);
>> -	return ret;
>> -}
>> -
>> -static int
>> -vdev_remove_driver(struct rte_vdev_device *dev)
>> -{
>> -	const char *name = rte_vdev_device_name(dev);
>> -	const struct rte_vdev_driver *driver;
>> -
>> -	if (!dev->device.driver) {
>> -		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
>> -		return 1;
>> -	}
>> -
>> -	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
>> -		driver);
>> -	return driver->remove(dev);
>> -}
>> -
>> -int
>> -rte_vdev_uninit(const char *name)
>> -{
>> -	struct rte_vdev_device *dev;
>> -	struct rte_devargs *devargs;
>> -	int ret;
>> -
>> -	if (name == NULL)
>> -		return -EINVAL;
>> -
>> -	dev = find_vdev(name);
>> -	if (!dev)
>> -		return -ENOENT;
>> -
>> -	devargs = dev->device.devargs;
>> -
>> -	ret = vdev_remove_driver(dev);
>> -	if (ret)
>> -		return ret;
>> -
>> -	TAILQ_REMOVE(&vdev_device_list, dev, next);
>> -
>> -	TAILQ_REMOVE(&devargs_list, devargs, next);
>> -
>> -	free(devargs->args);
>> -	free(devargs);
>> -	free(dev);
>> -	return 0;
>> -}
>> -
>> -static int
>> -vdev_scan(void)
>> -{
>> -	struct rte_vdev_device *dev;
>> -	struct rte_devargs *devargs;
>> -
>> -	/* for virtual devices we scan the devargs_list populated via cmdline */
>> -	TAILQ_FOREACH(devargs, &devargs_list, next) {
>> -
>> -		if (devargs->bus != &rte_vdev_bus)
>> -			continue;
>> -
>> -		dev = find_vdev(devargs->name);
>> -		if (dev)
>> -			continue;
>> -
>> -		dev = calloc(1, sizeof(*dev));
>> -		if (!dev)
>> -			return -1;
>> -
>> -		dev->device.devargs = devargs;
>> -		dev->device.numa_node = SOCKET_ID_ANY;
>> -		dev->device.name = devargs->name;
>> -
>> -		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
>> -	}
>> -
>> -	return 0;
>> -}
>> -
>> -static int
>> -vdev_probe(void)
>> -{
>> -	struct rte_vdev_device *dev;
>> -
>> -	/* call the init function for each virtual device */
>> -	TAILQ_FOREACH(dev, &vdev_device_list, next) {
>> -
>> -		if (dev->device.driver)
>> -			continue;
>> -
>> -		if (vdev_probe_all_drivers(dev)) {
>> -			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
>> -				rte_vdev_device_name(dev));
>> -			return -1;
>> -		}
>> -	}
>> -
>> -	return 0;
>> -}
>> -
>> -static struct rte_device *
>> -vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
>> -		 const void *data)
>> -{
>> -	struct rte_vdev_device *dev;
>> -
>> -	TAILQ_FOREACH(dev, &vdev_device_list, next) {
>> -		if (start && &dev->device == start) {
>> -			start = NULL;
>> -			continue;
>> -		}
>> -		if (cmp(&dev->device, data) == 0)
>> -			return &dev->device;
>> -	}
>> -	return NULL;
>> -}
>> -
>> -static int
>> -vdev_plug(struct rte_device *dev)
>> -{
>> -	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
>> -}
>> -
>> -static int
>> -vdev_unplug(struct rte_device *dev)
>> -{
>> -	return rte_vdev_uninit(dev->name);
>> -}
>> -
>> -static struct rte_bus rte_vdev_bus = {
>> -	.scan = vdev_scan,
>> -	.probe = vdev_probe,
>> -	.find_device = vdev_find_device,
>> -	.plug = vdev_plug,
>> -	.unplug = vdev_unplug,
>> -	.parse = vdev_parse,
>> -};
>> -
>> -RTE_REGISTER_BUS(vdev, rte_vdev_bus);
>> diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
>> index 5386d3a..8bfc343 100644
>> --- a/lib/librte_eal/common/include/rte_dev.h
>> +++ b/lib/librte_eal/common/include/rte_dev.h
>> @@ -166,28 +166,6 @@ struct rte_device {
>>   };
>>   
>>   /**
>> - * Initialize a driver specified by name.
>> - *
>> - * @param name
>> - *   The pointer to a driver name to be initialized.
>> - * @param args
>> - *   The pointer to arguments used by driver initialization.
>> - * @return
>> - *  0 on success, negative on error
>> - */
>> -int rte_vdev_init(const char *name, const char *args);
>> -
>> -/**
>> - * Uninitalize a driver specified by name.
>> - *
>> - * @param name
>> - *   The pointer to a driver name to be initialized.
>> - * @return
>> - *  0 on success, negative on error
>> - */
>> -int rte_vdev_uninit(const char *name);
>> -
>> -/**
>>    * Attach a device to a registered driver.
>>    *
>>    * @param name
>> @@ -312,4 +290,4 @@ __attribute__((used)) = str
>>   }
>>   #endif
>>   
>> -#endif /* _RTE_VDEV_H_ */
>> +#endif /* _RTE_DEV_H_ */
>> diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
>> deleted file mode 100644
>> index 29f5a52..0000000
>> --- a/lib/librte_eal/common/include/rte_vdev.h
>> +++ /dev/null
>> @@ -1,131 +0,0 @@
>> -/*-
>> - *   BSD LICENSE
>> - *
>> - *   Copyright(c) 2016 RehiveTech. All rights reserved.
>> - *
>> - *   Redistribution and use in source and binary forms, with or without
>> - *   modification, are permitted provided that the following conditions
>> - *   are met:
>> - *
>> - *     * Redistributions of source code must retain the above copyright
>> - *       notice, this list of conditions and the following disclaimer.
>> - *     * Redistributions in binary form must reproduce the above copyright
>> - *       notice, this list of conditions and the following disclaimer in
>> - *       the documentation and/or other materials provided with the
>> - *       distribution.
>> - *     * Neither the name of RehiveTech nor the names of its
>> - *       contributors may be used to endorse or promote products derived
>> - *       from this software without specific prior written permission.
>> - *
>> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> - */
>> -
>> -#ifndef RTE_VDEV_H
>> -#define RTE_VDEV_H
>> -
>> -#ifdef __cplusplus
>> -extern "C" {
>> -#endif
>> -
>> -#include <sys/queue.h>
>> -#include <rte_dev.h>
>> -#include <rte_devargs.h>
>> -
>> -struct rte_vdev_device {
>> -	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
>> -	struct rte_device device;               /**< Inherit core device */
>> -};
>> -
>> -/**
>> - * @internal
>> - * Helper macro for drivers that need to convert to struct rte_vdev_device.
>> - */
>> -#define RTE_DEV_TO_VDEV(ptr) \
>> -	container_of(ptr, struct rte_vdev_device, device)
>> -
>> -static inline const char *
>> -rte_vdev_device_name(const struct rte_vdev_device *dev)
>> -{
>> -	if (dev && dev->device.name)
>> -		return dev->device.name;
>> -	return NULL;
>> -}
>> -
>> -static inline const char *
>> -rte_vdev_device_args(const struct rte_vdev_device *dev)
>> -{
>> -	if (dev && dev->device.devargs)
>> -		return dev->device.devargs->args;
>> -	return "";
>> -}
>> -
>> -/** Double linked list of virtual device drivers. */
>> -TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
>> -
>> -/**
>> - * Probe function called for each virtual device driver once.
>> - */
>> -typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
>> -
>> -/**
>> - * Remove function called for each virtual device driver once.
>> - */
>> -typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
>> -
>> -/**
>> - * A virtual device driver abstraction.
>> - */
>> -struct rte_vdev_driver {
>> -	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
>> -	struct rte_driver driver;      /**< Inherited general driver. */
>> -	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
>> -	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
>> -};
>> -
>> -/**
>> - * Register a virtual device driver.
>> - *
>> - * @param driver
>> - *   A pointer to a rte_vdev_driver structure describing the driver
>> - *   to be registered.
>> - */
>> -void rte_vdev_register(struct rte_vdev_driver *driver);
>> -
>> -/**
>> - * Unregister a virtual device driver.
>> - *
>> - * @param driver
>> - *   A pointer to a rte_vdev_driver structure describing the driver
>> - *   to be unregistered.
>> - */
>> -void rte_vdev_unregister(struct rte_vdev_driver *driver);
>> -
>> -#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
>> -RTE_INIT(vdrvinitfn_ ##vdrv);\
>> -static const char *vdrvinit_ ## nm ## _alias;\
>> -static void vdrvinitfn_ ##vdrv(void)\
>> -{\
>> -	(vdrv).driver.name = RTE_STR(nm);\
>> -	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
>> -	rte_vdev_register(&vdrv);\
>> -} \
>> -RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
>> -
>> -#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
>> -static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
>> -
>> -#ifdef __cplusplus
>> -}
>> -#endif
>> -
>> -#endif
>> diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
>> index 90bca4d..33faa18 100644
>> --- a/lib/librte_eal/linuxapp/eal/Makefile
>> +++ b/lib/librte_eal/linuxapp/eal/Makefile
>> @@ -80,7 +80,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
>> -SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
>>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
>> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
>> index c25fdd9..c423bf8 100644
>> --- a/mk/rte.app.mk
>> +++ b/mk/rte.app.mk
>> @@ -97,6 +97,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
>>   _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
>>   _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
>>   _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
>> +_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV)           += -lrte_bus_vdev
>>   _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
>>   _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
>>   
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 12/12] examples/helloworld: do not exit automatically
  2017-08-25  9:40 ` [PATCH 12/12] examples/helloworld: do not exit automatically Jianfeng Tan
@ 2017-09-18 11:44   ` De Lara Guarch, Pablo
  2017-09-19  5:07     ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: De Lara Guarch, Pablo @ 2017-09-18 11:44 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, August 25, 2017 10:41 AM
> To: dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh <ferruh.yigit@intel.com>; Tan,
> Jianfeng <jianfeng.tan@intel.com>
> Subject: [PATCH 12/12] examples/helloworld: do not exit automatically
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  examples/helloworld/main.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/examples/helloworld/main.c b/examples/helloworld/main.c
> index 8b7a2de..35b70da 100644
> --- a/examples/helloworld/main.c
> +++ b/examples/helloworld/main.c
> @@ -36,6 +36,7 @@
>  #include <stdint.h>
>  #include <errno.h>
>  #include <sys/queue.h>
> +#include <unistd.h>
> 
>  #include <rte_memory.h>
>  #include <rte_memzone.h>
> @@ -72,6 +73,8 @@ main(int argc, char **argv)
>  	/* call it on master lcore too */
>  	lcore_hello(NULL);
> 
> +	while (1) sleep(5);
> +
>  	rte_eal_mp_wait_lcore();
>  	return 0;
>  }
> --
> 2.7.4

I think this patch should not be in this patchset, as it looks that
it does not have any relation with the other patches.
Am I missing something?

Pablo

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 04/12] vdev: move to drivers/bus
  2017-08-29 22:47     ` Tan, Jianfeng
@ 2017-09-18 11:47       ` De Lara Guarch, Pablo
  2017-09-19  6:01         ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: De Lara Guarch, Pablo @ 2017-09-18 11:47 UTC (permalink / raw)
  To: Tan, Jianfeng, Gaëtan Rivet
  Cc: dev, Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Tuesday, August 29, 2017 11:48 PM
> To: Gaëtan Rivet <gaetan.rivet@6wind.com>
> Cc: dev@dpdk.org; Richardson, Bruce <bruce.richardson@intel.com>;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>; De Lara Guarch,
> Pablo <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 04/12] vdev: move to drivers/bus
> 
> Hi Gaetan,
> 
> 
> On 8/29/2017 6:04 AM, Gaëtan Rivet wrote:
> > On Fri, Aug 25, 2017 at 09:40:44AM +0000, Jianfeng Tan wrote:
> >> Move the vdev bus from lib/librte_eal to drivers/bus.
> >>
> >> As the crypto vdev helper function refers to data structure
> >> in rte_vdev.h, so we move those helper function into drivers/bus
> >> too.
> >>
> >> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> >> ---
> >>   config/common_base                        |   5 +
> >>   drivers/bus/Makefile                      |   2 +
> >>   drivers/bus/vdev/Makefile                 |  57 +++++
> >>   drivers/bus/vdev/rte_bus_vdev_version.map |  10 +
> >>   drivers/bus/vdev/rte_cryptodev_vdev.c     | 154 ++++++++++++++
> >>   drivers/bus/vdev/rte_cryptodev_vdev.h     | 100 +++++++++
> >>   drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
> >>   drivers/bus/vdev/vdev.c                   | 342
> ++++++++++++++++++++++++++++++
> >>   lib/librte_cryptodev/Makefile             |   2 -
> >>   lib/librte_cryptodev/rte_cryptodev_vdev.c | 154 --------------
> >>   lib/librte_cryptodev/rte_cryptodev_vdev.h | 100 ---------
> >>   lib/librte_eal/bsdapp/eal/Makefile        |   1 -
> >>   lib/librte_eal/common/Makefile            |   2 +-
> >>   lib/librte_eal/common/eal_common_vdev.c   | 342 --------------------------
> ----
> >>   lib/librte_eal/common/include/rte_dev.h   |  24 +--
> >>   lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
> >>   lib/librte_eal/linuxapp/eal/Makefile      |   1 -
> >>   mk/rte.app.mk                             |   1 +
> >>   18 files changed, 826 insertions(+), 755 deletions(-)
> >>   create mode 100644 drivers/bus/vdev/Makefile
> >>   create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
> >>   create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.c
> >>   create mode 100644 drivers/bus/vdev/rte_cryptodev_vdev.h
> >>   create mode 100644 drivers/bus/vdev/rte_vdev.h
> >>   create mode 100644 drivers/bus/vdev/vdev.c
> >>   delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.c
> >>   delete mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.h
> >>   delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
> >>   delete mode 100644 lib/librte_eal/common/include/rte_vdev.h
> >>
> >> diff --git a/config/common_base b/config/common_base
> >> index 5e97a08..aca0994 100644
> >> --- a/config/common_base
> >> +++ b/config/common_base
> >> @@ -750,3 +750,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
> >>   # Compile the eventdev application
> >>   #
> >>   CONFIG_RTE_APP_EVENTDEV=y
> >> +
> >> +#
> >> +# Compile the vdev bus
> >> +#
> >> +CONFIG_RTE_LIBRTE_VDEV=y
> > Why not CONFIG_RTE_LIBRTE_VDEV_BUS?
> > It would seem more consistent.
> 
> Was trying to be consistent with the directory name, drivers/bus/vdev.
> Do you think that directory should also be renamed?
> 
> >
> >> diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
> >> index 0224214..9b6d45e 100644
> >> --- a/drivers/bus/Makefile
> >> +++ b/drivers/bus/Makefile
> >> @@ -35,4 +35,6 @@ core-libs := librte_eal librte_mbuf librte_mempool
> librte_ring librte_ether
> >>   DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
> >>   DEPDIRS-fslmc = $(core-libs)
> >>
> >> +DIRS-$(CONFIG_RTE_LIBRTE_VDEV) += vdev
> >> +
> >>   include $(RTE_SDK)/mk/rte.subdir.mk
> >> diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
> >> new file mode 100644
> >> index 0000000..30c4813
> >> --- /dev/null
> >> +++ b/drivers/bus/vdev/Makefile
> >> @@ -0,0 +1,57 @@
> >> +#   BSD LICENSE
> >> +#
> >> +#   Copyright(c) 2017 Intel Corporation. All rights reserved.
> >> +#   All rights reserved.
> >> +#
> >> +#   Redistribution and use in source and binary forms, with or without
> >> +#   modification, are permitted provided that the following conditions
> >> +#   are met:
> >> +#
> >> +#     * Redistributions of source code must retain the above copyright
> >> +#       notice, this list of conditions and the following disclaimer.
> >> +#     * Redistributions in binary form must reproduce the above
> copyright
> >> +#       notice, this list of conditions and the following disclaimer in
> >> +#       the documentation and/or other materials provided with the
> >> +#       distribution.
> >> +#     * Neither the name of Intel Corporation nor the names of its
> >> +#       contributors may be used to endorse or promote products
> derived
> >> +#       from this software without specific prior written permission.
> >> +#
> >> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> >> +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
> BUT NOT
> >> +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR
> >> +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT
> >> +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL,
> >> +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
> BUT NOT
> >> +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> LOSS OF USE,
> >> +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
> AND ON ANY
> >> +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> >> +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> OF THE USE
> >> +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> >> +
> >> +include $(RTE_SDK)/mk/rte.vars.mk
> >> +
> >> +#
> >> +# library name
> >> +#
> >> +LIB = librte_bus_vdev.a
> >> +
> >> +CFLAGS += -O3
> >> +CFLAGS += $(WERROR_FLAGS)
> >> +
> >> +# versioning export map
> >> +EXPORT_MAP := rte_bus_vdev_version.map
> >> +
> >> +# library version
> >> +LIBABIVER := 1
> >> +
> >> +SRCS-y += vdev.c
> >> +SRCS-y += rte_cryptodev_vdev.c
> >> +
> >> +#
> >> +# Export include files
> >> +#
> >> +SYMLINK-y-include += rte_vdev.h
> >> +SYMLINK-y-include += rte_cryptodev_vdev.h
> >> +
> > Let's say the cryptodev lib must be updated.
> > I understand the need to move rte_cryptodev_vdev.h outside
> > librte_cryptodev, but I guess this exposes the vdev bus to ABI / API
> > instability due to a third-party subsystem?
> 
> Thank you for bringing up this question. I really don't want to move
> these crypto-specific files into bus/vdev/. It's just some helper
> functions to be called by crypto vdev drivers. And what's more, the only
> dependence on vdev is that the API rte_cryptodev_vdev_pmd_init() has a
> parameter of struct rte_vdev_device, which is totally not necessary, as
> it only needs a struct rte_device parameter.
> 
> In all, I'd prefer to change this specific API and move those
> crypto-specific files back to lib/librte_crypto (just like ether dev and
> eventdev); but it needs API change announcement.
> 
> Any thoughts?

I think we should keep this API in cryptodev. It looks strange to have some
Crypto specific functions in a file like this that should contain generic vdev
functions.

> 
> >
> > I did something somewhat similar for PCI:
> > http://dpdk.org/ml/archives/dev/2017-August/073525.html
> 
> I prefer your way to move those things to specific dev folder.
> 
> >
> > I don't know which solution is best, but something certainly needs to be
> > done.
> >
> > ---
> >
> > Beside the `why`, about the `how`: shouldn't this file compilation and
> > symlink be conditioned to CONFIG_RTE_LIBRTE_CRYPTODEV=y?
> >
> > i.e.: SYMLINK-$(CONFIG_RTE_LIBRTE_CRYPTODEV)-include +=
> rte_cryptodev_vdev.h
> 
> Yes, make sense.
> 
> Thanks,
> Jianfeng
> 
> 

Btw, for future times, strip out all the text where there are no comments,
so it is easier to review by others.

Thanks,
Pablo

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 01/12] cryptodev: remove crypto vdev init
  2017-08-25  9:40 ` [PATCH 01/12] cryptodev: remove crypto vdev init Jianfeng Tan
@ 2017-09-18 11:48   ` De Lara Guarch, Pablo
  0 siblings, 0 replies; 158+ messages in thread
From: De Lara Guarch, Pablo @ 2017-09-18 11:48 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, August 25, 2017 10:41 AM
> To: dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh <ferruh.yigit@intel.com>; Tan,
> Jianfeng <jianfeng.tan@intel.com>
> Subject: [PATCH 01/12] cryptodev: remove crypto vdev init
> 
> CC: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 03/12] crypto: move vdev helper functions into dedicated file
  2017-08-25  9:40 ` [PATCH 03/12] crypto: move vdev helper functions into dedicated file Jianfeng Tan
@ 2017-09-18 11:51   ` De Lara Guarch, Pablo
  0 siblings, 0 replies; 158+ messages in thread
From: De Lara Guarch, Pablo @ 2017-09-18 11:51 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, August 25, 2017 10:41 AM
> To: dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh <ferruh.yigit@intel.com>; Tan,
> Jianfeng <jianfeng.tan@intel.com>
> Subject: [PATCH 03/12] crypto: move vdev helper functions into dedicated
> file
> 

Title should start with "cryptodev: ..."

Also, it is missing the "Signed-off" line.

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-08-25  9:40 ` [PATCH 06/12] eal: add channel for primary/secondary communication Jianfeng Tan
@ 2017-09-18 13:49   ` Jiayu Hu
  2017-09-21  6:11     ` Tan, Jianfeng
  2017-09-20  3:00   ` Jiayu Hu
  2017-09-27 12:19   ` Yuanhan Liu
  2 siblings, 1 reply; 158+ messages in thread
From: Jiayu Hu @ 2017-09-18 13:49 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

Hi Jianfeng,


On Fri, Aug 25, 2017 at 09:40:46AM +0000, Jianfeng Tan wrote:
> Previouly, there is only one way for primary/secondary to exchange
> messages, that is, primary process writes info into some predefind
> file, and secondary process reads info out. That cannot address
> the requirements:
>   a. Secondary wants to send info to primary.
>   b. Sending info at any time, instead of just initialization time.
>   c. Share FD with the other side.

If you can explain more about why the above three characters are required
for enabling vdev in the secondary process here, that would be better. For
example, vdev may hot plugin or remove, so the primary and the secondary
process need to exchange data bidirectionally and dynamically.

> 
> This patch proposes to create a communication channel (as an unix
> socket connection) for above requirements.

Can you give more explainations about how the channel works? Like both
the primary and the secondary register actions for specific messages, and
another thread is created to listen and react incoming messages.

> 
> Three new APIs are added:
> 
>   1. rte_eal_primary_secondary_add_action is used to register an action,
> if the calling component wants to response the messages from the
> corresponding component in its primary process or secondary processes.
>   2. rte_eal_primary_secondary_del_action is used to unregister the
> action if the calling component does not want to response the messages.
>   3. rte_eal_primary_secondary_sendmsg is used to send a message.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
>  lib/librte_eal/common/eal_common_proc.c         | 454 ++++++++++++++++++++++++
>  lib/librte_eal/common/eal_filesystem.h          |  18 +
>  lib/librte_eal/common/eal_private.h             |  10 +
>  lib/librte_eal/common/include/rte_eal.h         |  74 ++++
>  lib/librte_eal/linuxapp/eal/eal.c               |   6 +
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
>  7 files changed, 578 insertions(+)
> 
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index aac6fd7..f4ff29f 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -237,3 +237,11 @@ EXPERIMENTAL {
>  	rte_service_unregister;
>  
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_eal_primary_secondary_add_action;
> +	rte_eal_primary_secondary_del_action;
> +	rte_eal_primary_secondary_sendmsg;
> +} DPDK_17.11;
> diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
> index 60526ca..fa316bf 100644
> --- a/lib/librte_eal/common/eal_common_proc.c
> +++ b/lib/librte_eal/common/eal_common_proc.c
> @@ -33,8 +33,20 @@
>  #include <stdio.h>
>  #include <fcntl.h>
>  #include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <sys/epoll.h>
> +#include <limits.h>
> +#include <unistd.h>
> +#include <sys/un.h>
> +#include <errno.h>
> +#include <pthread.h>
> +
> +#include <rte_log.h>
>  #include <rte_eal.h>
> +#include <rte_lcore.h>
>  
> +#include "eal_private.h"
>  #include "eal_filesystem.h"
>  #include "eal_internal_cfg.h"
>  
> @@ -59,3 +71,445 @@ rte_eal_primary_proc_alive(const char *config_file_path)
>  
>  	return !!ret;
>  }
> +
> +struct action_entry {
> +	TAILQ_ENTRY(action_entry) next;      /**< Next attached action entry*/
> +
> +#define MAX_ACTION_NAME_LEN	64
> +	char action_name[MAX_ACTION_NAME_LEN];
> +	rte_eal_primary_secondary_t *action;
> +};
> +
> +/** Double linked list of actions. */
> +TAILQ_HEAD(action_entry_list, action_entry);
> +
> +static struct action_entry_list action_entry_list =
> +	TAILQ_HEAD_INITIALIZER(action_entry_list);
> +
> +static struct action_entry *
> +find_action_entry_by_name(const char *name)
> +{
> +	int len = strlen(name);
> +	struct action_entry *entry;
> +
> +	TAILQ_FOREACH(entry, &action_entry_list, next) {
> +		if (strncmp(entry->action_name, name, len) == 0)
> +				break;
> +	}
> +
> +	return entry;
> +}
> +
> +int
> +rte_eal_primary_secondary_add_action(const char *action_name,
> +				     rte_eal_primary_secondary_t action)
> +{
> +	struct action_entry *entry = malloc(sizeof(struct action_entry));
> +
> +	if (entry == NULL)
> +		return -ENOMEM;
> +
> +	strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
> +	entry->action = action;

In struct action_entry, the type of action is 'rte_eal_primary_secondary_t *',
but you assign an object to action here.

> +	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);

What would happen if register two actions for a same message name?

> +	return 0;
> +}
> +
> +void
> +rte_eal_primary_secondary_del_action(const char *name)
> +{
> +	struct action_entry *entry = find_action_entry_by_name(name);
> +
> +	TAILQ_REMOVE(&action_entry_list, entry, next);
> +	free(entry);
> +}
> +
> +#define MAX_SECONDARY_PROCS	8

A simple question: why the max number is 8?

> +
> +static int efd_pri_sec; /* epoll fd for primary/secondary channel thread */
> +static int fd_listen;   /* unix listen socket by primary */
> +static int fd_to_pri;   /* only used by secondary process */
> +static int fds_to_sec[MAX_SECONDARY_PROCS];
> +
> +struct msg_hdr {
> +	char action_name[MAX_ACTION_NAME_LEN];
> +	int fds_num;
> +	char params[0];
> +} __rte_packed;
> +
> +static int
> +add_sec_proc(int fd)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +		if (fds_to_sec[i] == -1)
> +			break;
> +
> +	if (i >= MAX_SECONDARY_PROCS)
> +		return -1;
> +
> +	fds_to_sec[i] = fd;
> +
> +	return i;
> +}
> +
> +static void
> +del_sec_proc(int fd)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
> +		if (fds_to_sec[i] == fd) {
> +			fds_to_sec[i] = -1;
> +			break;
> +		}
> +	}
> +}
> +
> +static int
> +read_msg(int sockfd, char *buf, int buflen, int *fds, int fds_num)
> +{
> +	struct iovec iov;
> +	struct msghdr msgh;
> +	size_t fdsize = fds_num * sizeof(int);
> +	char control[CMSG_SPACE(fdsize)];
> +	struct cmsghdr *cmsg;
> +	int ret;
> +
> +	memset(&msgh, 0, sizeof(msgh));
> +	iov.iov_base = buf;
> +	iov.iov_len  = buflen;
> +
> +	msgh.msg_iov = &iov;
> +	msgh.msg_iovlen = 1;
> +	msgh.msg_control = control;
> +	msgh.msg_controllen = sizeof(control);
> +
> +	ret = recvmsg(sockfd, &msgh, 0);
> +	if (ret <= 0) {
> +		RTE_LOG(ERR, EAL, "recvmsg failed\n");
> +		return ret;
> +	}
> +
> +	if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
> +		RTE_LOG(ERR, EAL, "truncted msg\n");
> +		return -1;
> +	}
> +
> +	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
> +		cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
> +		if ((cmsg->cmsg_level == SOL_SOCKET) &&
> +			(cmsg->cmsg_type == SCM_RIGHTS)) {
> +			memcpy(fds, CMSG_DATA(cmsg), fdsize);
> +			break;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +process_msg(int fd)
> +{
> +	int len;
> +	int params_len;
> +	char buf[1024];
> +	int fds[8]; /* accept at most 8 FDs per message */
> +	struct msg_hdr *hdr;
> +	struct action_entry *entry;
> +
> +	len = read_msg(fd, buf, 1024, fds, 8);
> +	if (len < 0) {
> +		RTE_LOG(ERR, EAL, "failed to read message: %s\n",
> +			strerror(errno));
> +		return -1;
> +	}
> +
> +	hdr = (struct msg_hdr *) buf;
> +
> +	entry = find_action_entry_by_name(hdr->action_name);
> +	if (entry == NULL) {
> +		RTE_LOG(ERR, EAL, "cannot find action by: %s\n",
> +			hdr->action_name);
> +		return -1;
> +	}
> +
> +	params_len = len - sizeof(struct msg_hdr);
> +	return entry->action(hdr->params, params_len, fds, hdr->fds_num);
> +}
> +
> +static void *
> +thread_primary(__attribute__((unused)) void *arg)
> +{
> +	int fd;
> +	int i, n;
> +	struct epoll_event event;
> +	struct epoll_event *events;
> +
> +	event.events = EPOLLIN | EPOLLRDHUP;
> +	event.data.fd = fd_listen;
> +	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_listen, &event) < 0) {
> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n",
> +			strerror(errno));
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	events = calloc(20, sizeof event);
> +
> +	while (1) {
> +		n = epoll_wait(efd_pri_sec, events, 20, -1);
> +		for (i = 0; i < n; i++) {
> +			if (events[i].data.fd == fd_listen) {
> +				if (events[i].events != EPOLLIN) {
> +					RTE_LOG(ERR, EAL, "what happens?\n");
> +					exit(EXIT_FAILURE);
> +				}
> +
> +				fd = accept(fd_listen, NULL, NULL);
> +				if (fd < 0) {
> +					RTE_LOG(ERR, EAL, "primary failed to accept: %s\n",
> +						strerror(errno));
> +					continue;
> +				}
> +
> +				event.data.fd = fd;
> +				if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd, &event) < 0) {
> +					RTE_LOG(ERR, EAL, "failed to add secondary: %s\n",
> +						strerror(errno));
> +					continue;
> +				}
> +				if (add_sec_proc(fd) < 0)
> +					RTE_LOG(ERR, EAL, "too many secondary processes\n");
> +
> +				continue;
> +			}
> +
> +			fd = events[i].data.fd;
> +
> +			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
> +				RTE_LOG(ERR, EAL,
> +					"secondary process exit: %d\n", fd);
> +				epoll_ctl(efd_pri_sec, EPOLL_CTL_DEL, fd, NULL);
> +				del_sec_proc(fd);
> +				continue;
> +			}
> +
> +			if ((events[i].events & EPOLLIN)) {
> +				RTE_LOG(INFO, EAL,
> +					"recv msg from secondary process\n");
> +
> +				process_msg(fd);
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +static void *
> +thread_secondary(__attribute__((unused)) void *arg)
> +{
> +	int fd;
> +	int i, n;
> +	struct epoll_event event;
> +	struct epoll_event *events;
> +
> +	event.events = EPOLLIN | EPOLLRDHUP;
> +	event.data.fd = fd_to_pri;
> +	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_to_pri, &event) < 0) {
> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n", strerror(errno));
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	events = calloc(20, sizeof event);
> +
> +	while (1) {
> +		n = epoll_wait(efd_pri_sec, events, 20, -1);
> +		for (i = 0; i < n; i++) {
> +
> +			fd = events[i].data.fd;
> +
> +			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
> +				RTE_LOG(ERR, EAL, "primary exits, so do I\n");
> +				/* Do we need exit secondary when primary exits? */
> +				exit(EXIT_FAILURE);
> +			}
> +
> +			if ((events[i].events & EPOLLIN)) {
> +				RTE_LOG(INFO, EAL,
> +					"recv msg from primary process\n");
> +				process_msg(fd);
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +int
> +rte_eal_primary_secondary_channel_init(void)
> +{
> +	int i, fd, ret;
> +	const char *path;
> +	struct sockaddr_un un;
> +	pthread_t tid;
> +	void*(*fn)(void *);
> +	char thread_name[RTE_MAX_THREAD_NAME_LEN];
> +
> +	efd_pri_sec = epoll_create1(0);
> +	if (efd_pri_sec < 0) {
> +		RTE_LOG(ERR, EAL, "epoll_create1 failed\n");
> +		return -1;
> +	}
> +
> +	fd = socket(AF_UNIX, SOCK_STREAM, 0);
> +	if (fd < 0) {
> +		RTE_LOG(ERR, EAL, "Failed to create unix socket");
> +		return -1;
> +	}
> +
> +	memset(&un, 0, sizeof(un));
> +	un.sun_family = AF_UNIX;
> +	path = eal_primary_secondary_unix_path();
> +	strncpy(un.sun_path, path, sizeof(un.sun_path));
> +	un.sun_path[sizeof(un.sun_path) - 1] = '\0';
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +
> +		for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +			fds_to_sec[i] = -1;
> +
> +		if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
> +			RTE_LOG(ERR, EAL, "cannot set nonblocking mode\n");
> +			close(fd);
> +			return -1;
> +		}
> +
> +		/* The file still exists since last run */
> +		unlink(path);
> +
> +		ret = bind(fd, (struct sockaddr *)&un, sizeof(un));
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to bind to %s: %s\n",
> +				path, strerror(errno));
> +			close(fd);
> +			return -1;
> +		}
> +		RTE_LOG(INFO, EAL, "primary bind to %s\n", path);
> +
> +		ret = listen(fd, 1024);
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to listen: %s", strerror(errno));
> +			close(fd);
> +			return -1;
> +		}
> +
> +		fn = thread_primary;
> +		fd_listen = fd;
> +	} else {
> +		ret = connect(fd, (struct sockaddr *)&un, sizeof(un));
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to connect primary\n");
> +			return -1;
> +		}
> +		fn = thread_secondary;
> +		fd_to_pri = fd;
> +	}
> +
> +	ret = pthread_create(&tid, NULL, fn, NULL);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, EAL, "failed to create thead: %s\n",
> +			strerror(errno));
> +		close(fd);
> +		close(efd_pri_sec);
> +		return -1;
> +	}
> +
> +	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
> +		 "ps_channel");
> +	ret = rte_thread_setname(tid, thread_name);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, EAL, "failed to set thead name\n");
> +		close(fd);
> +		close(efd_pri_sec);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +send_msg(int fd, struct msghdr *p_msgh)
> +{
> +	int ret;
> +
> +	do {
> +		ret = sendmsg(fd, p_msgh, 0);
> +	} while (ret < 0 && errno == EINTR);
> +
> +	return ret;
> +}
> +
> +int
> +rte_eal_primary_secondary_sendmsg(const char *action_name,
> +				  const void *params,
> +				  int len_params,
> +				  int fds[],
> +				  int fds_num)
> +{
> +	int i;
> +	int ret = 0;
> +	struct msghdr msgh;
> +	struct iovec iov;
> +	size_t fd_size = fds_num * sizeof(int);
> +	char control[CMSG_SPACE(fd_size)];
> +	struct cmsghdr *cmsg;
> +	struct msg_hdr *msg;
> +	int len_msg;
> +
> +	len_msg = sizeof(struct msg_hdr) + len_params;
> +	msg = malloc(len_msg);
> +	if (!msg) {
> +		RTE_LOG(ERR, EAL, "Cannot alloc memory for msg");
> +		return -ENOMEM;
> +	}
> +	memset(msg, 0, len_msg);
> +	strcpy(msg->action_name, action_name);
> +	msg->fds_num = fds_num;
> +	memcpy(msg->params, params, len_params);
> +
> +	memset(&msgh, 0, sizeof(msgh));
> +	memset(control, 0, sizeof(control));
> +
> +	iov.iov_base = (uint8_t *)msg;
> +	iov.iov_len = len_msg;
> +
> +	msgh.msg_iov = &iov;
> +	msgh.msg_iovlen = 1;
> +	msgh.msg_control = control;
> +	msgh.msg_controllen = sizeof(control);
> +
> +	cmsg = CMSG_FIRSTHDR(&msgh);
> +	cmsg->cmsg_len = CMSG_LEN(fd_size);
> +	cmsg->cmsg_level = SOL_SOCKET;
> +	cmsg->cmsg_type = SCM_RIGHTS;
> +	memcpy(CMSG_DATA(cmsg), fds, fd_size);
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
> +			if (fds_to_sec[i] == -1)
> +				continue;
> +
> +			ret = send_msg(fds_to_sec[i], &msgh);
> +			if (ret < 0)
> +				break;
> +		}
> +	} else {
> +		ret = send_msg(fd_to_pri, &msgh);
> +	}
> +
> +	free(msg);
> +
> +	return ret;
> +}
> diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
> index 8acbd99..78bb4fb 100644
> --- a/lib/librte_eal/common/eal_filesystem.h
> +++ b/lib/librte_eal/common/eal_filesystem.h
> @@ -67,6 +67,24 @@ eal_runtime_config_path(void)
>  	return buffer;
>  }
>  
> +/** Path of primary/secondary communication unix socket file. */
> +#define PRIMARY_SECONDARY_UNIX_PATH_FMT "%s/.%s_unix"
> +static inline const char *
> +eal_primary_secondary_unix_path(void)
> +{
> +	static char buffer[PATH_MAX]; /* static so auto-zeroed */
> +	const char *directory = default_config_dir;
> +	const char *home_dir = getenv("HOME");
> +
> +	if (getuid() != 0 && home_dir != NULL)
> +		directory = home_dir;
> +	snprintf(buffer, sizeof(buffer) - 1, PRIMARY_SECONDARY_UNIX_PATH_FMT,
> +		 directory, internal_config.hugefile_prefix);
> +
> +	return buffer;
> +
> +}
> +
>  /** Path of hugepage info file. */
>  #define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
>  
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 597d82e..719b160 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -355,4 +355,14 @@ bool rte_eal_using_phys_addrs(void);
>   */
>  struct rte_bus *rte_bus_find_by_device_name(const char *str);
>  
> +/**
> + * Create the unix channel for primary/secondary communication.
> + *
> + * @return
> + *   0 on success;
> + *   (<0) on failure.
> + */
> +
> +int rte_eal_primary_secondary_channel_init(void);
> +
>  #endif /* _EAL_PRIVATE_H_ */
> diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
> index 0e7363d..6cfc9d6 100644
> --- a/lib/librte_eal/common/include/rte_eal.h
> +++ b/lib/librte_eal/common/include/rte_eal.h
> @@ -210,6 +210,80 @@ int rte_eal_init(int argc, char **argv);
>  int rte_eal_primary_proc_alive(const char *config_file_path);
>  
>  /**
> + * Action function typedef used by other components.
> + *
> + * As we create unix socket channel for primary/secondary communication, use
> + * this function typedef to register action for coming messages.
> + */
> +typedef int (rte_eal_primary_secondary_t)(const char *params,
> +					  int len,
> +					  int fds[],
> +					  int fds_num);
> +/**
> + * Register an action function for primary/secondary communication.
> + *
> + * Call this function to register an action, if the calling component wants
> + * to response the messages from the corresponding component in its primary
> + * process or secondary processes.
> + *
> + * @param action_name
> + *   The action_name argument plays as the nonredundant key to find the action.
> + *
> + * @param action
> + *   The action argument is the function pointer to the action function.
> + *
> + * @return
> + *  - 0 on success.
> + *  - (<0) on failure.
> + */
> +int rte_eal_primary_secondary_add_action(const char *action_name,
> +					 rte_eal_primary_secondary_t action);
> +/**
> + * Unregister an action function for primary/secondary communication.
> + *
> + * Call this function to unregister an action  if the calling component does
> + * not want to response the messages from the corresponding component in its
> + * primary process or secondary processes.
> + *
> + * @param action_name
> + *   The action_name argument plays as the nonredundant key to find the action.
> + *
> + */
> +void rte_eal_primary_secondary_del_action(const char *name);
> +
> +/**
> + * Send a message to the primary process or the secondary processes.
> + *
> + * This function will send a message which will be responsed by the action
> + * identified by action_name of the process on the other side.
> + *
> + * @param action_name
> + *   The action_name argument is used to identify which action will be used.
> + *
> + * @param params
> + *   The params argument contains the customized message.
> + *
> + * @param len_params
> + *   The len_params argument is the length of the customized message.
> + *
> + * @param fds
> + *   The fds argument is an array of fds sent with sendmsg.
> + *
> + * @param fds_num
> + *   The fds_num argument is number of fds to be sent with sendmsg.
> + *
> + * @return
> + *  - (>=0) on success.
> + *  - (<0) on failure.
> + */
> +int
> +rte_eal_primary_secondary_sendmsg(const char *action_name,
> +				  const void *params,
> +				  int len_params,
> +				  int fds[],
> +				  int fds_num);
> +
> +/**
>   * Usage function typedef used by the application usage function.
>   *
>   * Use this function typedef to define and call rte_set_applcation_usage_hook()
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 48f12f4..237c0b1 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -873,6 +873,12 @@ rte_eal_init(int argc, char **argv)
>  
>  	eal_check_mem_on_local_socket();
>  
> +	if (rte_eal_primary_secondary_channel_init() < 0) {
> +		rte_eal_init_alert("Cannot create unix channel.");
> +		rte_errno = EFAULT;
> +		return -1;
> +	}
> +
>  	if (eal_plugins_init() < 0)
>  		rte_eal_init_alert("Cannot init plugins\n");
>  
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 3a8f154..c618aec 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -242,3 +242,11 @@ EXPERIMENTAL {
>  	rte_service_unregister;
>  
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_eal_primary_secondary_add_action;
> +	rte_eal_primary_secondary_del_action;
> +	rte_eal_primary_secondary_sendmsg;
> +} DPDK_17.11;
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 12/12] examples/helloworld: do not exit automatically
  2017-09-18 11:44   ` De Lara Guarch, Pablo
@ 2017-09-19  5:07     ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-19  5:07 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, dev
  Cc: Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh

Hi Pablo,

> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Monday, September 18, 2017 7:44 PM
> To: Tan, Jianfeng; dev@dpdk.org
> Cc: Richardson, Bruce; Ananyev, Konstantin; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com;
> Yigit, Ferruh
> Subject: RE: [PATCH 12/12] examples/helloworld: do not exit automatically
> 
> 
...
> >  #include <rte_memory.h>
> >  #include <rte_memzone.h>
> > @@ -72,6 +73,8 @@ main(int argc, char **argv)
> >  	/* call it on master lcore too */
> >  	lcore_hello(NULL);
> >
> > +	while (1) sleep(5);
> > +
> >  	rte_eal_mp_wait_lcore();
> >  	return 0;
> >  }
> > --
> > 2.7.4
> 
> I think this patch should not be in this patchset, as it looks that
> it does not have any relation with the other patches.
> Am I missing something?

We want to use this example as a *clean* primary process; but without this example, we can still use those examples in examples/multi_process/.

So will drop this patch.

Thanks,
Jianfeng

> 
> Pablo

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 04/12] vdev: move to drivers/bus
  2017-09-18 11:47       ` De Lara Guarch, Pablo
@ 2017-09-19  6:01         ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-19  6:01 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Gaëtan Rivet
  Cc: dev, Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh

Hi Pablo

> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Monday, September 18, 2017 7:48 PM
> To: Tan, Jianfeng; Gaëtan Rivet
> Cc: dev@dpdk.org; Richardson, Bruce; Ananyev, Konstantin;
> thomas@monjalon.net; yliu@fridaylinux.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh
> Subject: RE: [dpdk-dev] [PATCH 04/12] vdev: move to drivers/bus
> 
> 
...
> > > Let's say the cryptodev lib must be updated.
> > > I understand the need to move rte_cryptodev_vdev.h outside
> > > librte_cryptodev, but I guess this exposes the vdev bus to ABI / API
> > > instability due to a third-party subsystem?
> >
> > Thank you for bringing up this question. I really don't want to move
> > these crypto-specific files into bus/vdev/. It's just some helper
> > functions to be called by crypto vdev drivers. And what's more, the only
> > dependence on vdev is that the API rte_cryptodev_vdev_pmd_init() has a
> > parameter of struct rte_vdev_device, which is totally not necessary, as
> > it only needs a struct rte_device parameter.
> >
> > In all, I'd prefer to change this specific API and move those
> > crypto-specific files back to lib/librte_crypto (just like ether dev and
> > eventdev); but it needs API change announcement.
> >
> > Any thoughts?
> 
> I think we should keep this API in cryptodev. It looks strange to have some
> Crypto specific functions in a file like this that should contain generic vdev
> functions.

OK, I'll try to put those files back, see if possible to add a dependency on librte_bus_vdev in lib_cryptodev.

...
> 
> Btw, for future times, strip out all the text where there are no comments,
> so it is easier to review by others.

Thank you for the reminder.

Thanks,
Jianfeng 

> 
> Thanks,
> Pablo

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-08-25  9:40 ` [PATCH 06/12] eal: add channel for primary/secondary communication Jianfeng Tan
  2017-09-18 13:49   ` Jiayu Hu
@ 2017-09-20  3:00   ` Jiayu Hu
  2017-09-21  6:53     ` Tan, Jianfeng
  2017-09-27 12:19   ` Yuanhan Liu
  2 siblings, 1 reply; 158+ messages in thread
From: Jiayu Hu @ 2017-09-20  3:00 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

Hi Jianfeng,

Few questions are inline.

Thanks,
Jiayu

On Fri, Aug 25, 2017 at 09:40:46AM +0000, Jianfeng Tan wrote:
> Previouly, there is only one way for primary/secondary to exchange
> messages, that is, primary process writes info into some predefind
> file, and secondary process reads info out. That cannot address
> the requirements:
>   a. Secondary wants to send info to primary.
>   b. Sending info at any time, instead of just initialization time.
>   c. Share FD with the other side.
> 
> This patch proposes to create a communication channel (as an unix
> socket connection) for above requirements.
> 
> Three new APIs are added:
> 
>   1. rte_eal_primary_secondary_add_action is used to register an action,
> if the calling component wants to response the messages from the
> corresponding component in its primary process or secondary processes.
>   2. rte_eal_primary_secondary_del_action is used to unregister the
> action if the calling component does not want to response the messages.
>   3. rte_eal_primary_secondary_sendmsg is used to send a message.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
>  lib/librte_eal/common/eal_common_proc.c         | 454 ++++++++++++++++++++++++
>  lib/librte_eal/common/eal_filesystem.h          |  18 +
>  lib/librte_eal/common/eal_private.h             |  10 +
>  lib/librte_eal/common/include/rte_eal.h         |  74 ++++
>  lib/librte_eal/linuxapp/eal/eal.c               |   6 +
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
>  7 files changed, 578 insertions(+)
> 
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index aac6fd7..f4ff29f 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -237,3 +237,11 @@ EXPERIMENTAL {
>  	rte_service_unregister;
>  
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_eal_primary_secondary_add_action;
> +	rte_eal_primary_secondary_del_action;
> +	rte_eal_primary_secondary_sendmsg;
> +} DPDK_17.11;
> diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
> index 60526ca..fa316bf 100644
> --- a/lib/librte_eal/common/eal_common_proc.c
> +++ b/lib/librte_eal/common/eal_common_proc.c
> @@ -33,8 +33,20 @@
>  #include <stdio.h>
>  #include <fcntl.h>
>  #include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <sys/epoll.h>
> +#include <limits.h>
> +#include <unistd.h>
> +#include <sys/un.h>
> +#include <errno.h>
> +#include <pthread.h>
> +
> +#include <rte_log.h>
>  #include <rte_eal.h>
> +#include <rte_lcore.h>
>  
> +#include "eal_private.h"
>  #include "eal_filesystem.h"
>  #include "eal_internal_cfg.h"
>  
> @@ -59,3 +71,445 @@ rte_eal_primary_proc_alive(const char *config_file_path)
>  
>  	return !!ret;
>  }
> +
> +struct action_entry {
> +	TAILQ_ENTRY(action_entry) next;      /**< Next attached action entry*/
> +
> +#define MAX_ACTION_NAME_LEN	64
> +	char action_name[MAX_ACTION_NAME_LEN];
> +	rte_eal_primary_secondary_t *action;
> +};
> +
> +/** Double linked list of actions. */
> +TAILQ_HEAD(action_entry_list, action_entry);
> +
> +static struct action_entry_list action_entry_list =
> +	TAILQ_HEAD_INITIALIZER(action_entry_list);
> +
> +static struct action_entry *
> +find_action_entry_by_name(const char *name)
> +{
> +	int len = strlen(name);
> +	struct action_entry *entry;
> +
> +	TAILQ_FOREACH(entry, &action_entry_list, next) {
> +		if (strncmp(entry->action_name, name, len) == 0)
> +				break;
> +	}
> +
> +	return entry;
> +}
> +
> +int
> +rte_eal_primary_secondary_add_action(const char *action_name,
> +				     rte_eal_primary_secondary_t action)
> +{
> +	struct action_entry *entry = malloc(sizeof(struct action_entry));
> +
> +	if (entry == NULL)
> +		return -ENOMEM;
> +
> +	strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
> +	entry->action = action;
> +	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
> +	return 0;
> +}
> +
> +void
> +rte_eal_primary_secondary_del_action(const char *name)
> +{
> +	struct action_entry *entry = find_action_entry_by_name(name);
> +
> +	TAILQ_REMOVE(&action_entry_list, entry, next);
> +	free(entry);
> +}
> +
> +#define MAX_SECONDARY_PROCS	8
> +
> +static int efd_pri_sec; /* epoll fd for primary/secondary channel thread */
> +static int fd_listen;   /* unix listen socket by primary */
> +static int fd_to_pri;   /* only used by secondary process */
> +static int fds_to_sec[MAX_SECONDARY_PROCS];
> +
> +struct msg_hdr {
> +	char action_name[MAX_ACTION_NAME_LEN];
> +	int fds_num;
> +	char params[0];
> +} __rte_packed;
> +
> +static int
> +add_sec_proc(int fd)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +		if (fds_to_sec[i] == -1)
> +			break;
> +
> +	if (i >= MAX_SECONDARY_PROCS)
> +		return -1;
> +
> +	fds_to_sec[i] = fd;
> +
> +	return i;
> +}
> +
> +static void
> +del_sec_proc(int fd)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
> +		if (fds_to_sec[i] == fd) {
> +			fds_to_sec[i] = -1;
> +			break;
> +		}
> +	}
> +}
> +
> +static int
> +read_msg(int sockfd, char *buf, int buflen, int *fds, int fds_num)
> +{
> +	struct iovec iov;
> +	struct msghdr msgh;
> +	size_t fdsize = fds_num * sizeof(int);
> +	char control[CMSG_SPACE(fdsize)];
> +	struct cmsghdr *cmsg;
> +	int ret;
> +
> +	memset(&msgh, 0, sizeof(msgh));
> +	iov.iov_base = buf;
> +	iov.iov_len  = buflen;
> +
> +	msgh.msg_iov = &iov;
> +	msgh.msg_iovlen = 1;
> +	msgh.msg_control = control;
> +	msgh.msg_controllen = sizeof(control);
> +
> +	ret = recvmsg(sockfd, &msgh, 0);
> +	if (ret <= 0) {
> +		RTE_LOG(ERR, EAL, "recvmsg failed\n");
> +		return ret;
> +	}
> +
> +	if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
> +		RTE_LOG(ERR, EAL, "truncted msg\n");
> +		return -1;
> +	}
> +
> +	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
> +		cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
> +		if ((cmsg->cmsg_level == SOL_SOCKET) &&
> +			(cmsg->cmsg_type == SCM_RIGHTS)) {
> +			memcpy(fds, CMSG_DATA(cmsg), fdsize);
> +			break;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +process_msg(int fd)
> +{
> +	int len;
> +	int params_len;
> +	char buf[1024];

The max length of message to receive is 1024 here, but the
senders don't know the limit. It's better to define a macro
for the max message length? 

> +	int fds[8]; /* accept at most 8 FDs per message */
> +	struct msg_hdr *hdr;
> +	struct action_entry *entry;
> +
> +	len = read_msg(fd, buf, 1024, fds, 8);
> +	if (len < 0) {
> +		RTE_LOG(ERR, EAL, "failed to read message: %s\n",
> +			strerror(errno));
> +		return -1;
> +	}

Why don't check if len is equal to 0?

> +
> +	hdr = (struct msg_hdr *) buf;
> +
> +	entry = find_action_entry_by_name(hdr->action_name);
> +	if (entry == NULL) {
> +		RTE_LOG(ERR, EAL, "cannot find action by: %s\n",
> +			hdr->action_name);
> +		return -1;
> +	}
> +
> +	params_len = len - sizeof(struct msg_hdr);
> +	return entry->action(hdr->params, params_len, fds, hdr->fds_num);
> +}
> +
> +static void *
> +thread_primary(__attribute__((unused)) void *arg)
> +{
> +	int fd;
> +	int i, n;
> +	struct epoll_event event;
> +	struct epoll_event *events;
> +
> +	event.events = EPOLLIN | EPOLLRDHUP;
> +	event.data.fd = fd_listen;
> +	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_listen, &event) < 0) {
> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n",
> +			strerror(errno));
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	events = calloc(20, sizeof event);

A simple question: Why the max events number is 20?

> +
> +	while (1) {
> +		n = epoll_wait(efd_pri_sec, events, 20, -1);
> +		for (i = 0; i < n; i++) {
> +			if (events[i].data.fd == fd_listen) {
> +				if (events[i].events != EPOLLIN) {
> +					RTE_LOG(ERR, EAL, "what happens?\n");
> +					exit(EXIT_FAILURE);
> +				}
> +
> +				fd = accept(fd_listen, NULL, NULL);
> +				if (fd < 0) {
> +					RTE_LOG(ERR, EAL, "primary failed to accept: %s\n",

This line is beyond 80 characters.

> +						strerror(errno));
> +					continue;
> +				}
> +
> +				event.data.fd = fd;
> +				if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd, &event) < 0) {
> +					RTE_LOG(ERR, EAL, "failed to add secondary: %s\n",

These two lines are beyond 80 characters.

> +						strerror(errno));
> +					continue;
> +				}
> +				if (add_sec_proc(fd) < 0)
> +					RTE_LOG(ERR, EAL, "too many secondary processes\n");

This line is beyond 80 characters.

> +
> +				continue;
> +			}
> +
> +			fd = events[i].data.fd;
> +
> +			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
> +				RTE_LOG(ERR, EAL,
> +					"secondary process exit: %d\n", fd);
> +				epoll_ctl(efd_pri_sec, EPOLL_CTL_DEL, fd, NULL);
> +				del_sec_proc(fd);

Need close(fd) here?

> +				continue;
> +			}
> +
> +			if ((events[i].events & EPOLLIN)) {
> +				RTE_LOG(INFO, EAL,
> +					"recv msg from secondary process\n");
> +
> +				process_msg(fd);
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +static void *
> +thread_secondary(__attribute__((unused)) void *arg)
> +{
> +	int fd;
> +	int i, n;
> +	struct epoll_event event;
> +	struct epoll_event *events;
> +
> +	event.events = EPOLLIN | EPOLLRDHUP;
> +	event.data.fd = fd_to_pri;
> +	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_to_pri, &event) < 0) {
> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n", strerror(errno));
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	events = calloc(20, sizeof event);
> +
> +	while (1) {
> +		n = epoll_wait(efd_pri_sec, events, 20, -1);
> +		for (i = 0; i < n; i++) {
> +
> +			fd = events[i].data.fd;
> +
> +			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
> +				RTE_LOG(ERR, EAL, "primary exits, so do I\n");
> +				/* Do we need exit secondary when primary exits? */

Need close(fd) here?

> +				exit(EXIT_FAILURE);
> +			}
> +
> +			if ((events[i].events & EPOLLIN)) {
> +				RTE_LOG(INFO, EAL,
> +					"recv msg from primary process\n");
> +				process_msg(fd);
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +int
> +rte_eal_primary_secondary_channel_init(void)
> +{
> +	int i, fd, ret;
> +	const char *path;
> +	struct sockaddr_un un;
> +	pthread_t tid;
> +	void*(*fn)(void *);
> +	char thread_name[RTE_MAX_THREAD_NAME_LEN];
> +
> +	efd_pri_sec = epoll_create1(0);
> +	if (efd_pri_sec < 0) {
> +		RTE_LOG(ERR, EAL, "epoll_create1 failed\n");
> +		return -1;
> +	}
> +
> +	fd = socket(AF_UNIX, SOCK_STREAM, 0);
> +	if (fd < 0) {
> +		RTE_LOG(ERR, EAL, "Failed to create unix socket");
> +		return -1;
> +	}
> +
> +	memset(&un, 0, sizeof(un));
> +	un.sun_family = AF_UNIX;
> +	path = eal_primary_secondary_unix_path();
> +	strncpy(un.sun_path, path, sizeof(un.sun_path));
> +	un.sun_path[sizeof(un.sun_path) - 1] = '\0';
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +
> +		for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +			fds_to_sec[i] = -1;
> +
> +		if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
> +			RTE_LOG(ERR, EAL, "cannot set nonblocking mode\n");
> +			close(fd);
> +			return -1;
> +		}
> +
> +		/* The file still exists since last run */
> +		unlink(path);
> +
> +		ret = bind(fd, (struct sockaddr *)&un, sizeof(un));
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to bind to %s: %s\n",
> +				path, strerror(errno));
> +			close(fd);
> +			return -1;
> +		}
> +		RTE_LOG(INFO, EAL, "primary bind to %s\n", path);
> +
> +		ret = listen(fd, 1024);
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to listen: %s", strerror(errno));
> +			close(fd);
> +			return -1;
> +		}
> +
> +		fn = thread_primary;
> +		fd_listen = fd;
> +	} else {
> +		ret = connect(fd, (struct sockaddr *)&un, sizeof(un));
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to connect primary\n");
> +			return -1;
> +		}
> +		fn = thread_secondary;
> +		fd_to_pri = fd;
> +	}
> +
> +	ret = pthread_create(&tid, NULL, fn, NULL);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, EAL, "failed to create thead: %s\n",
> +			strerror(errno));
> +		close(fd);
> +		close(efd_pri_sec);
> +		return -1;
> +	}
> +
> +	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
> +		 "ps_channel");
> +	ret = rte_thread_setname(tid, thread_name);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, EAL, "failed to set thead name\n");
> +		close(fd);
> +		close(efd_pri_sec);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +send_msg(int fd, struct msghdr *p_msgh)
> +{
> +	int ret;
> +
> +	do {
> +		ret = sendmsg(fd, p_msgh, 0);
> +	} while (ret < 0 && errno == EINTR);
> +
> +	return ret;
> +}
> +
> +int
> +rte_eal_primary_secondary_sendmsg(const char *action_name,
> +				  const void *params,
> +				  int len_params,
> +				  int fds[],
> +				  int fds_num)
> +{
> +	int i;
> +	int ret = 0;
> +	struct msghdr msgh;
> +	struct iovec iov;
> +	size_t fd_size = fds_num * sizeof(int);
> +	char control[CMSG_SPACE(fd_size)];
> +	struct cmsghdr *cmsg;
> +	struct msg_hdr *msg;
> +	int len_msg;
> +
> +	len_msg = sizeof(struct msg_hdr) + len_params;
> +	msg = malloc(len_msg);
> +	if (!msg) {
> +		RTE_LOG(ERR, EAL, "Cannot alloc memory for msg");
> +		return -ENOMEM;
> +	}
> +	memset(msg, 0, len_msg);
> +	strcpy(msg->action_name, action_name);
> +	msg->fds_num = fds_num;
> +	memcpy(msg->params, params, len_params);
> +
> +	memset(&msgh, 0, sizeof(msgh));
> +	memset(control, 0, sizeof(control));
> +
> +	iov.iov_base = (uint8_t *)msg;
> +	iov.iov_len = len_msg;
> +
> +	msgh.msg_iov = &iov;
> +	msgh.msg_iovlen = 1;
> +	msgh.msg_control = control;
> +	msgh.msg_controllen = sizeof(control);
> +
> +	cmsg = CMSG_FIRSTHDR(&msgh);
> +	cmsg->cmsg_len = CMSG_LEN(fd_size);
> +	cmsg->cmsg_level = SOL_SOCKET;
> +	cmsg->cmsg_type = SCM_RIGHTS;
> +	memcpy(CMSG_DATA(cmsg), fds, fd_size);
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
> +			if (fds_to_sec[i] == -1)
> +				continue;
> +
> +			ret = send_msg(fds_to_sec[i], &msgh);
> +			if (ret < 0)
> +				break;
> +		}
> +	} else {
> +		ret = send_msg(fd_to_pri, &msgh);
> +	}
> +
> +	free(msg);
> +
> +	return ret;
> +}
> diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
> index 8acbd99..78bb4fb 100644
> --- a/lib/librte_eal/common/eal_filesystem.h
> +++ b/lib/librte_eal/common/eal_filesystem.h
> @@ -67,6 +67,24 @@ eal_runtime_config_path(void)
>  	return buffer;
>  }
>  
> +/** Path of primary/secondary communication unix socket file. */
> +#define PRIMARY_SECONDARY_UNIX_PATH_FMT "%s/.%s_unix"
> +static inline const char *
> +eal_primary_secondary_unix_path(void)
> +{
> +	static char buffer[PATH_MAX]; /* static so auto-zeroed */
> +	const char *directory = default_config_dir;
> +	const char *home_dir = getenv("HOME");
> +
> +	if (getuid() != 0 && home_dir != NULL)
> +		directory = home_dir;
> +	snprintf(buffer, sizeof(buffer) - 1, PRIMARY_SECONDARY_UNIX_PATH_FMT,
> +		 directory, internal_config.hugefile_prefix);
> +
> +	return buffer;
> +
> +}
> +
>  /** Path of hugepage info file. */
>  #define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
>  
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 597d82e..719b160 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -355,4 +355,14 @@ bool rte_eal_using_phys_addrs(void);
>   */
>  struct rte_bus *rte_bus_find_by_device_name(const char *str);
>  
> +/**
> + * Create the unix channel for primary/secondary communication.
> + *
> + * @return
> + *   0 on success;
> + *   (<0) on failure.
> + */
> +
> +int rte_eal_primary_secondary_channel_init(void);
> +
>  #endif /* _EAL_PRIVATE_H_ */
> diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
> index 0e7363d..6cfc9d6 100644
> --- a/lib/librte_eal/common/include/rte_eal.h
> +++ b/lib/librte_eal/common/include/rte_eal.h
> @@ -210,6 +210,80 @@ int rte_eal_init(int argc, char **argv);
>  int rte_eal_primary_proc_alive(const char *config_file_path);
>  
>  /**
> + * Action function typedef used by other components.
> + *
> + * As we create unix socket channel for primary/secondary communication, use
> + * this function typedef to register action for coming messages.
> + */
> +typedef int (rte_eal_primary_secondary_t)(const char *params,
> +					  int len,
> +					  int fds[],
> +					  int fds_num);
> +/**
> + * Register an action function for primary/secondary communication.
> + *
> + * Call this function to register an action, if the calling component wants
> + * to response the messages from the corresponding component in its primary
> + * process or secondary processes.
> + *
> + * @param action_name
> + *   The action_name argument plays as the nonredundant key to find the action.
> + *
> + * @param action
> + *   The action argument is the function pointer to the action function.
> + *
> + * @return
> + *  - 0 on success.
> + *  - (<0) on failure.
> + */
> +int rte_eal_primary_secondary_add_action(const char *action_name,
> +					 rte_eal_primary_secondary_t action);
> +/**
> + * Unregister an action function for primary/secondary communication.
> + *
> + * Call this function to unregister an action  if the calling component does
> + * not want to response the messages from the corresponding component in its
> + * primary process or secondary processes.
> + *
> + * @param action_name
> + *   The action_name argument plays as the nonredundant key to find the action.
> + *
> + */
> +void rte_eal_primary_secondary_del_action(const char *name);
> +
> +/**
> + * Send a message to the primary process or the secondary processes.
> + *
> + * This function will send a message which will be responsed by the action
> + * identified by action_name of the process on the other side.
> + *
> + * @param action_name
> + *   The action_name argument is used to identify which action will be used.
> + *
> + * @param params
> + *   The params argument contains the customized message.
> + *
> + * @param len_params
> + *   The len_params argument is the length of the customized message.
> + *
> + * @param fds
> + *   The fds argument is an array of fds sent with sendmsg.
> + *
> + * @param fds_num
> + *   The fds_num argument is number of fds to be sent with sendmsg.
> + *
> + * @return
> + *  - (>=0) on success.
> + *  - (<0) on failure.
> + */
> +int
> +rte_eal_primary_secondary_sendmsg(const char *action_name,
> +				  const void *params,
> +				  int len_params,
> +				  int fds[],
> +				  int fds_num);
> +
> +/**
>   * Usage function typedef used by the application usage function.
>   *
>   * Use this function typedef to define and call rte_set_applcation_usage_hook()
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 48f12f4..237c0b1 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -873,6 +873,12 @@ rte_eal_init(int argc, char **argv)
>  
>  	eal_check_mem_on_local_socket();
>  
> +	if (rte_eal_primary_secondary_channel_init() < 0) {
> +		rte_eal_init_alert("Cannot create unix channel.");
> +		rte_errno = EFAULT;
> +		return -1;
> +	}
> +
>  	if (eal_plugins_init() < 0)
>  		rte_eal_init_alert("Cannot init plugins\n");
>  
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 3a8f154..c618aec 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -242,3 +242,11 @@ EXPERIMENTAL {
>  	rte_service_unregister;
>  
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_eal_primary_secondary_add_action;
> +	rte_eal_primary_secondary_del_action;
> +	rte_eal_primary_secondary_sendmsg;
> +} DPDK_17.11;
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-08-25  9:40 ` [PATCH 10/12] vhost: support to kick in secondary process Jianfeng Tan
@ 2017-09-21  3:33   ` Yuanhan Liu
  2017-09-21  7:04     ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-21  3:33 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit

Firstly, very sorry for so late review!

On Fri, Aug 25, 2017 at 09:40:50AM +0000, Jianfeng Tan wrote:
> To support kick in secondary process, we propose callfd_pri and
> kickfd_pri to store the value in primary process; and by a new
> API, rte_vhost_set_vring_effective_fd(), we can set effective
> callfd and kickfd which can be used by secondary process.
> 
> Note in this case, either primary process or the secondary process
> can kick the frontend; that is, they cannot kick a vring at the
> same time.

Since only one can work, why not just overwriting the fd? Say, you
could introudce some APIs like "rte_vhost_set_vring_callfd", then
you don't need to introduce few more fields like "callfd_pri".

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 11/12] net/vhost: support to run in the secondary process
  2017-08-25  9:40 ` [PATCH 11/12] net/vhost: support to run in the " Jianfeng Tan
@ 2017-09-21  4:29   ` Yuanhan Liu
  0 siblings, 0 replies; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-21  4:29 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, maxime.coquelin, mtetsuyah

On Fri, Aug 25, 2017 at 09:40:51AM +0000, Jianfeng Tan wrote:
>  static int
> +share_device(int vid)
> +{
> +	uint32_t i, vring_num;
> +	int len;
> +	int fds[8];
> +	struct rte_vhost_memory *mem;
> +	struct vhost_params *params;
> +	struct rte_vhost_vring vring;
> +
> +	/* share mem table */
> +	if (rte_vhost_get_mem_table(vid, &mem) < 0) {
> +		printf("Failed to get mem table\n");

No printf in DPDK lib and pmd, use RTE_LOG instead.

[...]
> +static int
> +eth_dev_vhost_attach(struct rte_vdev_device *dev)
> +{
> +	struct rte_eth_dev *eth_dev = NULL;
> +	struct rte_eth_dev_data *data = NULL;
> +
> +	RTE_LOG(INFO, PMD, "Attach vhost user port\n");
> +
> +	/* reserve an ethdev entry */
> +	eth_dev = rte_eth_vdev_allocate(dev, sizeof(struct pmd_internal));
> +	if (eth_dev == NULL)
> +		goto error;

I'd suggest to "return -1" directly here, without introducing goto.

> +
> +	eth_dev->dev_ops = &ops;
> +
> +	/* finally assign rx and tx ops */
> +	eth_dev->rx_pkt_burst = eth_vhost_rx;
> +	eth_dev->tx_pkt_burst = eth_vhost_tx;
> +
> +	data = eth_dev->data;
> +
> +	return data->port_id;
> +
> +error:
> +	return -1;
> +}
> +
>  static inline int
>  open_iface(const char *key __rte_unused, const char *value, void *extra_args)
>  {
> @@ -1154,6 +1244,39 @@ open_int(const char *key __rte_unused, const char *value, void *extra_args)
>  }
>  
>  static int
> +vhost_pmd_action(const char *params, int len __rte_unused,
> +		 int fds[], int fds_num)
> +{
> +	int i;
> +	void *base_addr;
> +	const struct vhost_params *p = (const struct vhost_params *)params;

The cast could be avoided if you define the action prototype with
"const void *params".

> +	const struct rte_vhost_mem_region *regions;
> +
> +	switch (p->type) {
> +	case VHOST_MSG_TYPE_REGIONS:
> +		regions = (const void *)p->regions;

Unnecessary cast.

> +		for (i = 0; i < fds_num; ++i) {
> +			base_addr = mmap(regions[i].mmap_addr,
> +					 regions[i].mmap_size,
> +					 PROT_READ | PROT_WRITE,
> +					 MAP_FIXED | MAP_SHARED, fds[i], 0);
> +			if (base_addr != regions[i].mmap_addr) {
> +				RTE_LOG(INFO, PMD, "mmap error");

The log level should be error, nothing will work if it happens. Also, the
log message should be more informative.

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-09-18 13:49   ` Jiayu Hu
@ 2017-09-21  6:11     ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-21  6:11 UTC (permalink / raw)
  To: Jiayu Hu
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

Hi Jiayu,


On 9/18/2017 9:49 PM, Jiayu Hu wrote:
> Hi Jianfeng,
>
>
> On Fri, Aug 25, 2017 at 09:40:46AM +0000, Jianfeng Tan wrote:
>> Previouly, there is only one way for primary/secondary to exchange
>> messages, that is, primary process writes info into some predefind
>> file, and secondary process reads info out. That cannot address
>> the requirements:
>>    a. Secondary wants to send info to primary.
>>    b. Sending info at any time, instead of just initialization time.
>>    c. Share FD with the other side.
> If you can explain more about why the above three characters are required
> for enabling vdev in the secondary process here, that would be better. For
> example, vdev may hot plugin or remove, so the primary and the secondary
> process need to exchange data bidirectionally and dynamically.

OK, I'll exemplify each item with a case.

>
>> This patch proposes to create a communication channel (as an unix
>> socket connection) for above requirements.
> Can you give more explainations about how the channel works? Like both
> the primary and the secondary register actions for specific messages, and
> another thread is created to listen and react incoming messages.

I suppose for users/developers who want to use it, below description 
about how to use related APIs is enough. As for how the channel is 
created, i'll try to describe more here.

>
>> Three new APIs are added:
>>
>>    1. rte_eal_primary_secondary_add_action is used to register an action,
>> if the calling component wants to response the messages from the
>> corresponding component in its primary process or secondary processes.
>>    2. rte_eal_primary_secondary_del_action is used to unregister the
>> action if the calling component does not want to response the messages.
>>    3. rte_eal_primary_secondary_sendmsg is used to send a message.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
>>   lib/librte_eal/common/eal_common_proc.c         | 454 ++++++++++++++++++++++++
>>   lib/librte_eal/common/eal_filesystem.h          |  18 +
>>   lib/librte_eal/common/eal_private.h             |  10 +
>>   lib/librte_eal/common/include/rte_eal.h         |  74 ++++
>>   lib/librte_eal/linuxapp/eal/eal.c               |   6 +
>>   lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
>>   7 files changed, 578 insertions(+)
...
>> +
>> +int
>> +rte_eal_primary_secondary_add_action(const char *action_name,
>> +				     rte_eal_primary_secondary_t action)
>> +{
>> +	struct action_entry *entry = malloc(sizeof(struct action_entry));
>> +
>> +	if (entry == NULL)
>> +		return -ENOMEM;
>> +
>> +	strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
>> +	entry->action = action;
> In struct action_entry, the type of action is 'rte_eal_primary_secondary_t *',
> but you assign an object to action here.

Nice catch!

>
>> +	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
> What would happen if register two actions for a same message name?

Hmm, yes, let's return error if there's an existing one for that name.

>
>> +	return 0;
>> +}
>> +
>> +void
>> +rte_eal_primary_secondary_del_action(const char *name)
>> +{
>> +	struct action_entry *entry = find_action_entry_by_name(name);
>> +
>> +	TAILQ_REMOVE(&action_entry_list, entry, next);
>> +	free(entry);
>> +}
>> +
>> +#define MAX_SECONDARY_PROCS	8
> A simple question: why the max number is 8?

Just a hard-coded value.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-09-20  3:00   ` Jiayu Hu
@ 2017-09-21  6:53     ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-21  6:53 UTC (permalink / raw)
  To: Jiayu Hu
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit

Hi Jiayu,


On 9/20/2017 11:00 AM, Jiayu Hu wrote:
> Hi Jianfeng,
>
> Few questions are inline.
>
> Thanks,
> Jiayu
>
> On Fri, Aug 25, 2017 at 09:40:46AM +0000, Jianfeng Tan wrote:
>> Previouly, there is only one way for primary/secondary to exchange
>> messages, that is, primary process writes info into some predefind
>> file, and secondary process reads info out. That cannot address
>> the requirements:
>>    a. Secondary wants to send info to primary.
>>    b. Sending info at any time, instead of just initialization time.
>>    c. Share FD with the other side.
>>
>> This patch proposes to create a communication channel (as an unix
>> socket connection) for above requirements.
>>
>> Three new APIs are added:
>>
>>    1. rte_eal_primary_secondary_add_action is used to register an action,
>> if the calling component wants to response the messages from the
>> corresponding component in its primary process or secondary processes.
>>    2. rte_eal_primary_secondary_del_action is used to unregister the
>> action if the calling component does not want to response the messages.
>>    3. rte_eal_primary_secondary_sendmsg is used to send a message.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
>>   lib/librte_eal/common/eal_common_proc.c         | 454 ++++++++++++++++++++++++
>>   lib/librte_eal/common/eal_filesystem.h          |  18 +
>>   lib/librte_eal/common/eal_private.h             |  10 +
>>   lib/librte_eal/common/include/rte_eal.h         |  74 ++++
>>   lib/librte_eal/linuxapp/eal/eal.c               |   6 +
>>   lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
>>   7 files changed, 578 insertions(+)
>>
>> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> index aac6fd7..f4ff29f 100644
>> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> @@ -237,3 +237,11 @@ EXPERIMENTAL {
>>   	rte_service_unregister;
>>   
>>   } DPDK_17.08;
>> +
>> +EXPERIMENTAL {
>> +	global:
>> +
>> +	rte_eal_primary_secondary_add_action;
>> +	rte_eal_primary_secondary_del_action;
>> +	rte_eal_primary_secondary_sendmsg;
>> +} DPDK_17.11;
>> diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
>> index 60526ca..fa316bf 100644
>> --- a/lib/librte_eal/common/eal_common_proc.c
>> +++ b/lib/librte_eal/common/eal_common_proc.c
>> @@ -33,8 +33,20 @@
>>   #include <stdio.h>
>>   #include <fcntl.h>
>>   #include <stdlib.h>
>> +#include <sys/types.h>
>> +#include <sys/socket.h>
>> +#include <sys/epoll.h>
>> +#include <limits.h>
>> +#include <unistd.h>
>> +#include <sys/un.h>
>> +#include <errno.h>
>> +#include <pthread.h>
>> +
>> +#include <rte_log.h>
>>   #include <rte_eal.h>
>> +#include <rte_lcore.h>
>>   
>> +#include "eal_private.h"
>>   #include "eal_filesystem.h"
>>   #include "eal_internal_cfg.h"
>>   
>> @@ -59,3 +71,445 @@ rte_eal_primary_proc_alive(const char *config_file_path)
>>   
>>   	return !!ret;
>>   }
>> +
>> +struct action_entry {
>> +	TAILQ_ENTRY(action_entry) next;      /**< Next attached action entry*/
>> +
>> +#define MAX_ACTION_NAME_LEN	64
>> +	char action_name[MAX_ACTION_NAME_LEN];
>> +	rte_eal_primary_secondary_t *action;
>> +};
>> +
>> +/** Double linked list of actions. */
>> +TAILQ_HEAD(action_entry_list, action_entry);
>> +
>> +static struct action_entry_list action_entry_list =
>> +	TAILQ_HEAD_INITIALIZER(action_entry_list);
>> +
>> +static struct action_entry *
>> +find_action_entry_by_name(const char *name)
>> +{
>> +	int len = strlen(name);
>> +	struct action_entry *entry;
>> +
>> +	TAILQ_FOREACH(entry, &action_entry_list, next) {
>> +		if (strncmp(entry->action_name, name, len) == 0)
>> +				break;
>> +	}
>> +
>> +	return entry;
>> +}
>> +
>> +int
>> +rte_eal_primary_secondary_add_action(const char *action_name,
>> +				     rte_eal_primary_secondary_t action)
>> +{
>> +	struct action_entry *entry = malloc(sizeof(struct action_entry));
>> +
>> +	if (entry == NULL)
>> +		return -ENOMEM;
>> +
>> +	strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
>> +	entry->action = action;
>> +	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
>> +	return 0;
>> +}
>> +
>> +void
>> +rte_eal_primary_secondary_del_action(const char *name)
>> +{
>> +	struct action_entry *entry = find_action_entry_by_name(name);
>> +
>> +	TAILQ_REMOVE(&action_entry_list, entry, next);
>> +	free(entry);
>> +}
>> +
>> +#define MAX_SECONDARY_PROCS	8
>> +
>> +static int efd_pri_sec; /* epoll fd for primary/secondary channel thread */
>> +static int fd_listen;   /* unix listen socket by primary */
>> +static int fd_to_pri;   /* only used by secondary process */
>> +static int fds_to_sec[MAX_SECONDARY_PROCS];
>> +
>> +struct msg_hdr {
>> +	char action_name[MAX_ACTION_NAME_LEN];
>> +	int fds_num;
>> +	char params[0];
>> +} __rte_packed;
>> +
>> +static int
>> +add_sec_proc(int fd)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
>> +		if (fds_to_sec[i] == -1)
>> +			break;
>> +
>> +	if (i >= MAX_SECONDARY_PROCS)
>> +		return -1;
>> +
>> +	fds_to_sec[i] = fd;
>> +
>> +	return i;
>> +}
>> +
>> +static void
>> +del_sec_proc(int fd)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
>> +		if (fds_to_sec[i] == fd) {
>> +			fds_to_sec[i] = -1;
>> +			break;
>> +		}
>> +	}
>> +}
>> +
>> +static int
>> +read_msg(int sockfd, char *buf, int buflen, int *fds, int fds_num)
>> +{
>> +	struct iovec iov;
>> +	struct msghdr msgh;
>> +	size_t fdsize = fds_num * sizeof(int);
>> +	char control[CMSG_SPACE(fdsize)];
>> +	struct cmsghdr *cmsg;
>> +	int ret;
>> +
>> +	memset(&msgh, 0, sizeof(msgh));
>> +	iov.iov_base = buf;
>> +	iov.iov_len  = buflen;
>> +
>> +	msgh.msg_iov = &iov;
>> +	msgh.msg_iovlen = 1;
>> +	msgh.msg_control = control;
>> +	msgh.msg_controllen = sizeof(control);
>> +
>> +	ret = recvmsg(sockfd, &msgh, 0);
>> +	if (ret <= 0) {
>> +		RTE_LOG(ERR, EAL, "recvmsg failed\n");
>> +		return ret;
>> +	}
>> +
>> +	if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
>> +		RTE_LOG(ERR, EAL, "truncted msg\n");
>> +		return -1;
>> +	}
>> +
>> +	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
>> +		cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
>> +		if ((cmsg->cmsg_level == SOL_SOCKET) &&
>> +			(cmsg->cmsg_type == SCM_RIGHTS)) {
>> +			memcpy(fds, CMSG_DATA(cmsg), fdsize);
>> +			break;
>> +		}
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int
>> +process_msg(int fd)
>> +{
>> +	int len;
>> +	int params_len;
>> +	char buf[1024];
> The max length of message to receive is 1024 here, but the
> senders don't know the limit. It's better to define a macro
> for the max message length?

OK, let's make it a macro, and check the length when sending messages.

>
>> +	int fds[8]; /* accept at most 8 FDs per message */
>> +	struct msg_hdr *hdr;
>> +	struct action_entry *entry;
>> +
>> +	len = read_msg(fd, buf, 1024, fds, 8);
>> +	if (len < 0) {
>> +		RTE_LOG(ERR, EAL, "failed to read message: %s\n",
>> +			strerror(errno));
>> +		return -1;
>> +	}
> Why don't check if len is equal to 0?

Nice catch!

>
>> +
>> +	hdr = (struct msg_hdr *) buf;
>> +
>> +	entry = find_action_entry_by_name(hdr->action_name);
>> +	if (entry == NULL) {
>> +		RTE_LOG(ERR, EAL, "cannot find action by: %s\n",
>> +			hdr->action_name);
>> +		return -1;
>> +	}
>> +
>> +	params_len = len - sizeof(struct msg_hdr);
>> +	return entry->action(hdr->params, params_len, fds, hdr->fds_num);
>> +}
>> +
>> +static void *
>> +thread_primary(__attribute__((unused)) void *arg)
>> +{
>> +	int fd;
>> +	int i, n;
>> +	struct epoll_event event;
>> +	struct epoll_event *events;
>> +
>> +	event.events = EPOLLIN | EPOLLRDHUP;
>> +	event.data.fd = fd_listen;
>> +	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_listen, &event) < 0) {
>> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n",
>> +			strerror(errno));
>> +		exit(EXIT_FAILURE);
>> +	}
>> +
>> +	events = calloc(20, sizeof event);
> A simple question: Why the max events number is 20?

Another hard-coded value, this value only decides how many events can be 
process for each iteration, other events will be kept in kernel for 
another iteration.

>
>> +
>> +	while (1) {
>> +		n = epoll_wait(efd_pri_sec, events, 20, -1);
>> +		for (i = 0; i < n; i++) {
>> +			if (events[i].data.fd == fd_listen) {
>> +				if (events[i].events != EPOLLIN) {
>> +					RTE_LOG(ERR, EAL, "what happens?\n");
>> +					exit(EXIT_FAILURE);
>> +				}
>> +
>> +				fd = accept(fd_listen, NULL, NULL);
>> +				if (fd < 0) {
>> +					RTE_LOG(ERR, EAL, "primary failed to accept: %s\n",
> This line is beyond 80 characters.

Will fix it.
[...]
>> +
>> +				continue;
>> +			}
>> +
>> +			fd = events[i].data.fd;
>> +
>> +			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
>> +				RTE_LOG(ERR, EAL,
>> +					"secondary process exit: %d\n", fd);
>> +				epoll_ctl(efd_pri_sec, EPOLL_CTL_DEL, fd, NULL);
>> +				del_sec_proc(fd);
> Need close(fd) here?

Nice catch.

>
>> +				continue;
>> +			}
>> +
>> +			if ((events[i].events & EPOLLIN)) {
>> +				RTE_LOG(INFO, EAL,
>> +					"recv msg from secondary process\n");
>> +
>> +				process_msg(fd);
>> +			}
>> +		}
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +static void *
>> +thread_secondary(__attribute__((unused)) void *arg)
>> +{
>> +	int fd;
>> +	int i, n;
>> +	struct epoll_event event;
>> +	struct epoll_event *events;
>> +
>> +	event.events = EPOLLIN | EPOLLRDHUP;
>> +	event.data.fd = fd_to_pri;
>> +	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_to_pri, &event) < 0) {
>> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n", strerror(errno));
>> +		exit(EXIT_FAILURE);
>> +	}
>> +
>> +	events = calloc(20, sizeof event);
>> +
>> +	while (1) {
>> +		n = epoll_wait(efd_pri_sec, events, 20, -1);
>> +		for (i = 0; i < n; i++) {
>> +
>> +			fd = events[i].data.fd;
>> +
>> +			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
>> +				RTE_LOG(ERR, EAL, "primary exits, so do I\n");
>> +				/* Do we need exit secondary when primary exits? */
> Need close(fd) here?

We will exit here, no need to close().

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-09-21  3:33   ` Yuanhan Liu
@ 2017-09-21  7:04     ` Tan, Jianfeng
  2017-09-21  9:17       ` Yuanhan Liu
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-21  7:04 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit



On 9/21/2017 11:33 AM, Yuanhan Liu wrote:
> Firstly, very sorry for so late review!

That is understood.

>
> On Fri, Aug 25, 2017 at 09:40:50AM +0000, Jianfeng Tan wrote:
>> To support kick in secondary process, we propose callfd_pri and
>> kickfd_pri to store the value in primary process; and by a new
>> API, rte_vhost_set_vring_effective_fd(), we can set effective
>> callfd and kickfd which can be used by secondary process.
>>
>> Note in this case, either primary process or the secondary process
>> can kick the frontend; that is, they cannot kick a vring at the
>> same time.
> Since only one can work, why not just overwriting the fd? Say, you
> could introudce some APIs like "rte_vhost_set_vring_callfd", then
> you don't need to introduce few more fields like "callfd_pri".

That cannot address the below case:
1. Primary starts;
2. Secondary one starts; (if we overwrite it without storing it in some 
other fields)
3. Secondary one exits;
4. Secondary two starts. (primary cannot share the fd with this 
secondary process now, as this fd does not mean anything to the primary 
process)

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-09-21  7:04     ` Tan, Jianfeng
@ 2017-09-21  9:17       ` Yuanhan Liu
  2017-09-22  2:30         ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-21  9:17 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev, maxime.coquelin, mtetsuyah

On Thu, Sep 21, 2017 at 03:04:39PM +0800, Tan, Jianfeng wrote:
> >On Fri, Aug 25, 2017 at 09:40:50AM +0000, Jianfeng Tan wrote:
> >>To support kick in secondary process, we propose callfd_pri and
> >>kickfd_pri to store the value in primary process; and by a new
> >>API, rte_vhost_set_vring_effective_fd(), we can set effective
> >>callfd and kickfd which can be used by secondary process.
> >>
> >>Note in this case, either primary process or the secondary process
> >>can kick the frontend; that is, they cannot kick a vring at the
> >>same time.
> >Since only one can work, why not just overwriting the fd? Say, you
> >could introudce some APIs like "rte_vhost_set_vring_callfd", then
> >you don't need to introduce few more fields like "callfd_pri".
> 
> That cannot address the below case:
> 1. Primary starts;
> 2. Secondary one starts; (if we overwrite it without storing it in some
> other fields)
> 3. Secondary one exits;
> 4. Secondary two starts. (primary cannot share the fd with this secondary
> process now, as this fd does not mean anything to the primary process)

I was thinking that those fds will be retrieved by the primary process
once? So thsoe it got at beginning are still valid?

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-09-21  9:17       ` Yuanhan Liu
@ 2017-09-22  2:30         ` Tan, Jianfeng
  2017-09-27  9:36           ` Yuanhan Liu
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-22  2:30 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, maxime.coquelin, mtetsuyah



> -----Original Message-----
> From: Yuanhan Liu [mailto:yliu@fridaylinux.org]
> Sent: Thursday, September 21, 2017 5:18 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com
> Subject: Re: [PATCH 10/12] vhost: support to kick in secondary process
> 
> On Thu, Sep 21, 2017 at 03:04:39PM +0800, Tan, Jianfeng wrote:
> > >On Fri, Aug 25, 2017 at 09:40:50AM +0000, Jianfeng Tan wrote:
> > >>To support kick in secondary process, we propose callfd_pri and
> > >>kickfd_pri to store the value in primary process; and by a new
> > >>API, rte_vhost_set_vring_effective_fd(), we can set effective
> > >>callfd and kickfd which can be used by secondary process.
> > >>
> > >>Note in this case, either primary process or the secondary process
> > >>can kick the frontend; that is, they cannot kick a vring at the
> > >>same time.
> > >Since only one can work, why not just overwriting the fd? Say, you
> > >could introudce some APIs like "rte_vhost_set_vring_callfd", then
> > >you don't need to introduce few more fields like "callfd_pri".
> >
> > That cannot address the below case:
> > 1. Primary starts;
> > 2. Secondary one starts; (if we overwrite it without storing it in some
> > other fields)
> > 3. Secondary one exits;
> > 4. Secondary two starts. (primary cannot share the fd with this secondary
> > process now, as this fd does not mean anything to the primary process)
> 
> I was thinking that those fds will be retrieved by the primary process
> once? So thsoe it got at beginning are still valid?

Yes, the FDs are valid to primary process at step 1. But After overwriting in step 2, those FDs are not valid to primary.

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-09-22  2:30         ` Tan, Jianfeng
@ 2017-09-27  9:36           ` Yuanhan Liu
  2017-09-28  5:10             ` Tan, Jianfeng
  2017-09-28  8:09             ` Tan, Jianfeng
  0 siblings, 2 replies; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-27  9:36 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev, maxime.coquelin, mtetsuyah

On Fri, Sep 22, 2017 at 02:30:21AM +0000, Tan, Jianfeng wrote:
> 
> 
> > -----Original Message-----
> > From: Yuanhan Liu [mailto:yliu@fridaylinux.org]
> > Sent: Thursday, September 21, 2017 5:18 PM
> > To: Tan, Jianfeng
> > Cc: dev@dpdk.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com
> > Subject: Re: [PATCH 10/12] vhost: support to kick in secondary process
> > 
> > On Thu, Sep 21, 2017 at 03:04:39PM +0800, Tan, Jianfeng wrote:
> > > >On Fri, Aug 25, 2017 at 09:40:50AM +0000, Jianfeng Tan wrote:
> > > >>To support kick in secondary process, we propose callfd_pri and
> > > >>kickfd_pri to store the value in primary process; and by a new
> > > >>API, rte_vhost_set_vring_effective_fd(), we can set effective
> > > >>callfd and kickfd which can be used by secondary process.
> > > >>
> > > >>Note in this case, either primary process or the secondary process
> > > >>can kick the frontend; that is, they cannot kick a vring at the
> > > >>same time.
> > > >Since only one can work, why not just overwriting the fd? Say, you
> > > >could introudce some APIs like "rte_vhost_set_vring_callfd", then
> > > >you don't need to introduce few more fields like "callfd_pri".
> > >
> > > That cannot address the below case:
> > > 1. Primary starts;
> > > 2. Secondary one starts; (if we overwrite it without storing it in some
> > > other fields)
> > > 3. Secondary one exits;
> > > 4. Secondary two starts. (primary cannot share the fd with this secondary
> > > process now, as this fd does not mean anything to the primary process)
> > 
> > I was thinking that those fds will be retrieved by the primary process
> > once? So thsoe it got at beginning are still valid?
> 
> Yes, the FDs are valid to primary process at step 1. But After overwriting in step 2, those FDs are not valid to primary.

Yes, but the primary process has already got its correct fds saved, right?
With the saved fds, it then could share it with another secondary process.

Actually, the key (and typical) issue of multi-process here is the fds are
process specific, while they are stored in the shared memory. That means
only one will take effect eventually. Worse, the old ones are lost.

So, I think to make it right in this case, you should move the fds from
the shared memory and store them in the memory of the corresponding process.
If that's done, all processes could have its own valid fds, then every
process could do the kick (if that's really necessary).

You could check following commit for more info.
553f45932fb7 ("net/virtio: store PCI operators pointer locally")

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-08-25  9:40 ` [PATCH 06/12] eal: add channel for primary/secondary communication Jianfeng Tan
  2017-09-18 13:49   ` Jiayu Hu
  2017-09-20  3:00   ` Jiayu Hu
@ 2017-09-27 12:19   ` Yuanhan Liu
  2017-09-28 13:50     ` Tan, Jianfeng
  2 siblings, 1 reply; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-27 12:19 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit

On Fri, Aug 25, 2017 at 09:40:46AM +0000, Jianfeng Tan wrote:
> Previouly, there is only one way for primary/secondary to exchange
> messages, that is, primary process writes info into some predefind
> file, and secondary process reads info out. That cannot address
> the requirements:
>   a. Secondary wants to send info to primary.
>   b. Sending info at any time, instead of just initialization time.
>   c. Share FD with the other side.
> 
> This patch proposes to create a communication channel (as an unix
> socket connection) for above requirements.

Firstly, I think it's a good idea to have such generic interfaces for
multiple process.

> Three new APIs are added:
> 
>   1. rte_eal_primary_secondary_add_action is used to register an action,

As you have said, it's for registration, why use "add" verb here?
Normally, "register" implies one time action, while "add" means
it could be a repeat action.

Also, the function name is a bit long. Maybe something like
"rte_eal_mp_xxx" is shorter and better.

[...]
> +static struct action_entry *
> +find_action_entry_by_name(const char *name)
> +{
> +	int len = strlen(name);
> +	struct action_entry *entry;
> +
> +	TAILQ_FOREACH(entry, &action_entry_list, next) {
> +		if (strncmp(entry->action_name, name, len) == 0)
> +				break;

Broken indentation here.

> +	}
> +
> +	return entry;
> +}
> +
> +int
> +rte_eal_primary_secondary_add_action(const char *action_name,
> +				     rte_eal_primary_secondary_t action)
> +{
> +	struct action_entry *entry = malloc(sizeof(struct action_entry));
> +
> +	if (entry == NULL)
> +		return -ENOMEM;
> +
> +	strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
> +	entry->action = action;
> +	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);

Since you intended to support "one primary process and multiple secondary
process", here we need a lock to protect the list.

Another wonder is do we really need that, I mean 1:N model?

> +	return 0;
> +}
> +
> +void
> +rte_eal_primary_secondary_del_action(const char *name)
> +{
> +	struct action_entry *entry = find_action_entry_by_name(name);
> +
> +	TAILQ_REMOVE(&action_entry_list, entry, next);
> +	free(entry);
> +}
> +
> +#define MAX_SECONDARY_PROCS	8
> +
> +static int efd_pri_sec; /* epoll fd for primary/secondary channel thread */

I think it's not a good idea to use "pri". For me, "private" comes to
my mind firstly but not "primary".

> +static int fd_listen;   /* unix listen socket by primary */
> +static int fd_to_pri;   /* only used by secondary process */
> +static int fds_to_sec[MAX_SECONDARY_PROCS];

Too many vars. I'd suggest to use a struct here, which could also make
the naming a bit simpler. For instance,

struct mp_fds {
        int efd;

        union {
                /* fds for primary process */
                struct {
                        int listen;
			/* fds used to send msg to secondary process */
                        int secondaries[...];
                };

                /* fds for secondary process */
                struct {
			/* fds used to send msg to the primary process */
                        int primary;
                };
        };
};

It also separates the scope well. Note that above field naming does
not like perfect though. Feel free to come up with some better names.

[...]
> +static int
> +process_msg(int fd)
> +{
> +	int len;
> +	int params_len;
> +	char buf[1024];
> +	int fds[8]; /* accept at most 8 FDs per message */

Why it's 8? I think you are adding a vhost-user specific limitation to a
generic interface, which isn't quite right.

> +	struct msg_hdr *hdr;
> +	struct action_entry *entry;
> +
> +	len = read_msg(fd, buf, 1024, fds, 8);
> +	if (len < 0) {
> +		RTE_LOG(ERR, EAL, "failed to read message: %s\n",
> +			strerror(errno));
> +		return -1;
> +	}
> +
> +	hdr = (struct msg_hdr *) buf;
                                ^
An extra whitespace.

> +
> +	entry = find_action_entry_by_name(hdr->action_name);
> +	if (entry == NULL) {
> +		RTE_LOG(ERR, EAL, "cannot find action by: %s\n",
> +			hdr->action_name);
> +		return -1;
> +	}
> +
> +	params_len = len - sizeof(struct msg_hdr);
> +	return entry->action(hdr->params, params_len, fds, hdr->fds_num);
> +}
> +
> +static void *
> +thread_primary(__attribute__((unused)) void *arg)

Use __rte_unused instead, and put it after the var name.

> +{
> +	int fd;
> +	int i, n;
> +	struct epoll_event event;
> +	struct epoll_event *events;
> +
> +	event.events = EPOLLIN | EPOLLRDHUP;
> +	event.data.fd = fd_listen;
> +	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_listen, &event) < 0) {
> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n",
> +			strerror(errno));
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	events = calloc(20, sizeof event);
> +
> +	while (1) {
> +		n = epoll_wait(efd_pri_sec, events, 20, -1);
> +		for (i = 0; i < n; i++) {
> +			if (events[i].data.fd == fd_listen) {
> +				if (events[i].events != EPOLLIN) {
> +					RTE_LOG(ERR, EAL, "what happens?\n");
> +					exit(EXIT_FAILURE);
> +				}
> +
> +				fd = accept(fd_listen, NULL, NULL);
> +				if (fd < 0) {
> +					RTE_LOG(ERR, EAL, "primary failed to accept: %s\n",
> +						strerror(errno));
> +					continue;
> +				}
> +
> +				event.data.fd = fd;
> +				if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd, &event) < 0) {
> +					RTE_LOG(ERR, EAL, "failed to add secondary: %s\n",
> +						strerror(errno));
> +					continue;
> +				}
> +				if (add_sec_proc(fd) < 0)
> +					RTE_LOG(ERR, EAL, "too many secondary processes\n");
> +
> +				continue;
> +			}
> +
> +			fd = events[i].data.fd;
> +
> +			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
> +				RTE_LOG(ERR, EAL,
> +					"secondary process exit: %d\n", fd);
> +				epoll_ctl(efd_pri_sec, EPOLL_CTL_DEL, fd, NULL);
> +				del_sec_proc(fd);
> +				continue;
> +			}
> +
> +			if ((events[i].events & EPOLLIN)) {
> +				RTE_LOG(INFO, EAL,
> +					"recv msg from secondary process\n");
> +
> +				process_msg(fd);
> +			}
> +		}
> +	}

Too much redundant code. You are doing check twice and it could be
simplified.

> +
> +	return NULL;
> +}
> +
> +static void *
> +thread_secondary(__attribute__((unused)) void *arg)

I'm also wondering this one can be removed. I think we just need one
thread handling.

> +{
> +	int fd;
> +	int i, n;
> +	struct epoll_event event;
> +	struct epoll_event *events;
> +
> +	event.events = EPOLLIN | EPOLLRDHUP;
> +	event.data.fd = fd_to_pri;
> +	if (epoll_ctl(efd_pri_sec, EPOLL_CTL_ADD, fd_to_pri, &event) < 0) {
> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n", strerror(errno));
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	events = calloc(20, sizeof event);
> +
> +	while (1) {
> +		n = epoll_wait(efd_pri_sec, events, 20, -1);
> +		for (i = 0; i < n; i++) {
> +
> +			fd = events[i].data.fd;
> +
> +			if ((events[i].events & (EPOLLERR | EPOLLHUP))) {
> +				RTE_LOG(ERR, EAL, "primary exits, so do I\n");
> +				/* Do we need exit secondary when primary exits? */
> +				exit(EXIT_FAILURE);
> +			}
> +
> +			if ((events[i].events & EPOLLIN)) {
> +				RTE_LOG(INFO, EAL,
> +					"recv msg from primary process\n");
> +				process_msg(fd);
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +int
> +rte_eal_primary_secondary_channel_init(void)
> +{
> +	int i, fd, ret;
> +	const char *path;
> +	struct sockaddr_un un;
> +	pthread_t tid;
> +	void*(*fn)(void *);
> +	char thread_name[RTE_MAX_THREAD_NAME_LEN];
> +
> +	efd_pri_sec = epoll_create1(0);
> +	if (efd_pri_sec < 0) {
> +		RTE_LOG(ERR, EAL, "epoll_create1 failed\n");
> +		return -1;
> +	}
> +
> +	fd = socket(AF_UNIX, SOCK_STREAM, 0);
> +	if (fd < 0) {
> +		RTE_LOG(ERR, EAL, "Failed to create unix socket");
> +		return -1;
> +	}
> +
> +	memset(&un, 0, sizeof(un));
> +	un.sun_family = AF_UNIX;
> +	path = eal_primary_secondary_unix_path();
> +	strncpy(un.sun_path, path, sizeof(un.sun_path));
> +	un.sun_path[sizeof(un.sun_path) - 1] = '\0';
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +

Do not leave an extra whitespace line here.
> +		for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +			fds_to_sec[i] = -1;
> +
> +		if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
> +			RTE_LOG(ERR, EAL, "cannot set nonblocking mode\n");
> +			close(fd);
> +			return -1;
> +		}
> +
> +		/* The file still exists since last run */
> +		unlink(path);
> +
> +		ret = bind(fd, (struct sockaddr *)&un, sizeof(un));
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to bind to %s: %s\n",
> +				path, strerror(errno));
> +			close(fd);
> +			return -1;
> +		}
> +		RTE_LOG(INFO, EAL, "primary bind to %s\n", path);
> +
> +		ret = listen(fd, 1024);
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to listen: %s", strerror(errno));
> +			close(fd);
> +			return -1;
> +		}
> +
> +		fn = thread_primary;
> +		fd_listen = fd;
> +	} else {
> +		ret = connect(fd, (struct sockaddr *)&un, sizeof(un));
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to connect primary\n");
> +			return -1;
> +		}
> +		fn = thread_secondary;
> +		fd_to_pri = fd;
> +	}
> +
> +	ret = pthread_create(&tid, NULL, fn, NULL);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, EAL, "failed to create thead: %s\n",
> +			strerror(errno));
> +		close(fd);
> +		close(efd_pri_sec);
> +		return -1;
> +	}
> +
> +	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
> +		 "ps_channel");

It may be not that easy to know what "ps" stands for. Maybe "rte_mp_xx"
is better. Naming it start with "rte_" reminds people easily that it's
a thread from DPDK.

[...]
> diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
> index 8acbd99..78bb4fb 100644
> --- a/lib/librte_eal/common/eal_filesystem.h
> +++ b/lib/librte_eal/common/eal_filesystem.h
> @@ -67,6 +67,24 @@ eal_runtime_config_path(void)
>  	return buffer;
>  }
>  
> +/** Path of primary/secondary communication unix socket file. */
> +#define PRIMARY_SECONDARY_UNIX_PATH_FMT "%s/.%s_unix"
> +static inline const char *
> +eal_primary_secondary_unix_path(void)
> +{
> +	static char buffer[PATH_MAX]; /* static so auto-zeroed */
> +	const char *directory = default_config_dir;
> +	const char *home_dir = getenv("HOME");

It's not a good practice to generate such file at HOME dir. User would
be surprised to find it at HOME dir. In the worst case, user might delete
it.

The more common way is to put it to tmp dir, like "/tmp".

> +
> +	if (getuid() != 0 && home_dir != NULL)
> +		directory = home_dir;
> +	snprintf(buffer, sizeof(buffer) - 1, PRIMARY_SECONDARY_UNIX_PATH_FMT,
> +		 directory, internal_config.hugefile_prefix);
> +
> +	return buffer;
> +
> +}
> +
[...]
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 48f12f4..237c0b1 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -873,6 +873,12 @@ rte_eal_init(int argc, char **argv)
>  
>  	eal_check_mem_on_local_socket();
>  
> +	if (rte_eal_primary_secondary_channel_init() < 0) {
> +		rte_eal_init_alert("Cannot create unix channel.");

The alert message doesn't quite match the function name. Actually, you
have already print the specific error inside that init function when it
fails. Thus, you could just say "failed to init mp channel" or something
like this.

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-09-27  9:36           ` Yuanhan Liu
@ 2017-09-28  5:10             ` Tan, Jianfeng
  2017-09-28  8:09             ` Tan, Jianfeng
  1 sibling, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-28  5:10 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, maxime.coquelin, mtetsuyah



> -----Original Message-----
> From: Yuanhan Liu [mailto:yliu@fridaylinux.org]
> Sent: Wednesday, September 27, 2017 5:36 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com
> Subject: Re: [PATCH 10/12] vhost: support to kick in secondary process
> 
> On Fri, Sep 22, 2017 at 02:30:21AM +0000, Tan, Jianfeng wrote:
> >
> >
> > > -----Original Message-----
> > > From: Yuanhan Liu [mailto:yliu@fridaylinux.org]
> > > Sent: Thursday, September 21, 2017 5:18 PM
> > > To: Tan, Jianfeng
> > > Cc: dev@dpdk.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com
> > > Subject: Re: [PATCH 10/12] vhost: support to kick in secondary process
> > >
> > > On Thu, Sep 21, 2017 at 03:04:39PM +0800, Tan, Jianfeng wrote:
> > > > >On Fri, Aug 25, 2017 at 09:40:50AM +0000, Jianfeng Tan wrote:
> > > > >>To support kick in secondary process, we propose callfd_pri and
> > > > >>kickfd_pri to store the value in primary process; and by a new
> > > > >>API, rte_vhost_set_vring_effective_fd(), we can set effective
> > > > >>callfd and kickfd which can be used by secondary process.
> > > > >>
> > > > >>Note in this case, either primary process or the secondary process
> > > > >>can kick the frontend; that is, they cannot kick a vring at the
> > > > >>same time.
> > > > >Since only one can work, why not just overwriting the fd? Say, you
> > > > >could introudce some APIs like "rte_vhost_set_vring_callfd", then
> > > > >you don't need to introduce few more fields like "callfd_pri".
> > > >
> > > > That cannot address the below case:
> > > > 1. Primary starts;
> > > > 2. Secondary one starts; (if we overwrite it without storing it in some
> > > > other fields)
> > > > 3. Secondary one exits;
> > > > 4. Secondary two starts. (primary cannot share the fd with this
> secondary
> > > > process now, as this fd does not mean anything to the primary process)
> > >
> > > I was thinking that those fds will be retrieved by the primary process
> > > once? So thsoe it got at beginning are still valid?
> >
> > Yes, the FDs are valid to primary process at step 1. But After overwriting in
> step 2, those FDs are not valid to primary.
> 
> Yes, but the primary process has already got its correct fds saved, right?
> With the saved fds, it then could share it with another secondary process.
> 
> Actually, the key (and typical) issue of multi-process here is the fds are
> process specific, while they are stored in the shared memory. That means
> only one will take effect eventually. Worse, the old ones are lost.
> 
> So, I think to make it right in this case, you should move the fds from
> the shared memory and store them in the memory of the corresponding
> process.
> If that's done, all processes could have its own valid fds, then every
> process could do the kick (if that's really necessary).

Agreed, that can reduce the application's effort to decide which process should set the FDs. Will try to fix that in the coming version.

Thanks,
Jianfeng

> 
> You could check following commit for more info.
> 553f45932fb7 ("net/virtio: store PCI operators pointer locally")
> 
> 	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-09-27  9:36           ` Yuanhan Liu
  2017-09-28  5:10             ` Tan, Jianfeng
@ 2017-09-28  8:09             ` Tan, Jianfeng
  2017-09-30  8:18               ` Yuanhan Liu
  1 sibling, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-28  8:09 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, maxime.coquelin, mtetsuyah



> -----Original Message-----
> From: Yuanhan Liu [mailto:yliu@fridaylinux.org]
> Sent: Wednesday, September 27, 2017 5:36 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com
> Subject: Re: [PATCH 10/12] vhost: support to kick in secondary process
> 
> On Fri, Sep 22, 2017 at 02:30:21AM +0000, Tan, Jianfeng wrote:
> >
> >
> > > -----Original Message-----
> > > From: Yuanhan Liu [mailto:yliu@fridaylinux.org]
> > > Sent: Thursday, September 21, 2017 5:18 PM
> > > To: Tan, Jianfeng
> > > Cc: dev@dpdk.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com
> > > Subject: Re: [PATCH 10/12] vhost: support to kick in secondary process
> > >
> > > On Thu, Sep 21, 2017 at 03:04:39PM +0800, Tan, Jianfeng wrote:
> > > > >On Fri, Aug 25, 2017 at 09:40:50AM +0000, Jianfeng Tan wrote:
> > > > >>To support kick in secondary process, we propose callfd_pri and
> > > > >>kickfd_pri to store the value in primary process; and by a new
> > > > >>API, rte_vhost_set_vring_effective_fd(), we can set effective
> > > > >>callfd and kickfd which can be used by secondary process.
> > > > >>
> > > > >>Note in this case, either primary process or the secondary process
> > > > >>can kick the frontend; that is, they cannot kick a vring at the
> > > > >>same time.
> > > > >Since only one can work, why not just overwriting the fd? Say, you
> > > > >could introudce some APIs like "rte_vhost_set_vring_callfd", then
> > > > >you don't need to introduce few more fields like "callfd_pri".
> > > >
> > > > That cannot address the below case:
> > > > 1. Primary starts;
> > > > 2. Secondary one starts; (if we overwrite it without storing it in some
> > > > other fields)
> > > > 3. Secondary one exits;
> > > > 4. Secondary two starts. (primary cannot share the fd with this
> secondary
> > > > process now, as this fd does not mean anything to the primary process)
> > >
> > > I was thinking that those fds will be retrieved by the primary process
> > > once? So thsoe it got at beginning are still valid?
> >
> > Yes, the FDs are valid to primary process at step 1. But After overwriting in
> step 2, those FDs are not valid to primary.
> 
> Yes, but the primary process has already got its correct fds saved, right?
> With the saved fds, it then could share it with another secondary process.
> 
> Actually, the key (and typical) issue of multi-process here is the fds are
> process specific, while they are stored in the shared memory. That means
> only one will take effect eventually. Worse, the old ones are lost.
> 
> So, I think to make it right in this case, you should move the fds from
> the shared memory and store them in the memory of the corresponding
> process.
> If that's done, all processes could have its own valid fds, then every
> process could do the kick (if that's really necessary).
> 
> You could check following commit for more info.
> 553f45932fb7 ("net/virtio: store PCI operators pointer locally")

Have referred to the above solution, but seems not feasible for this case since there are too many queues. For example, if we define an array like this:
  int vhost_callfds[index_by_vid][index_by_queue_id];
The size would be MAX_VHOST_DEVICE * VHOST_MAX_VRING * 8Byte = 2Mbyte.

Instead, can we propose something like process_id to index array located at shared memory?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-09-27 12:19   ` Yuanhan Liu
@ 2017-09-28 13:50     ` Tan, Jianfeng
  2017-09-29  1:24       ` Yuanhan Liu
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-28 13:50 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, Richardson, Bruce, Ananyev, Konstantin, De Lara Guarch,
	Pablo, thomas, maxime.coquelin, mtetsuyah, Yigit, Ferruh

Yuanhan,

Thank you for the detailed review! Most of your suggestions are very good and I'll fix them in next version.

> -----Original Message-----
> From: Yuanhan Liu [mailto:yliu@fridaylinux.org]
> Sent: Wednesday, September 27, 2017 8:20 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; Richardson, Bruce; Ananyev, Konstantin; De Lara Guarch,
> Pablo; thomas@monjalon.net; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh
> Subject: Re: [PATCH 06/12] eal: add channel for primary/secondary
> communication
> 
[...]
> > +int
> > +rte_eal_primary_secondary_add_action(const char *action_name,
> > +				     rte_eal_primary_secondary_t action)
> > +{
> > +	struct action_entry *entry = malloc(sizeof(struct action_entry));
> > +
> > +	if (entry == NULL)
> > +		return -ENOMEM;
> > +
> > +	strncpy(entry->action_name, action_name,
> MAX_ACTION_NAME_LEN);
> > +	entry->action = action;
> > +	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
> 
> Since you intended to support "one primary process and multiple secondary
> process", here we need a lock to protect the list.

Only one thread of each process (either primary or secondary) does the register. So I wonder we don't have to add lock? Of course, no harm to add a lock.

> 
> Another wonder is do we really need that, I mean 1:N model?

I'm open to suggestions. IMO, not much extra code for 1:N model than 1:1 model. So not necessary to restrict that.

> 
> > +	return 0;
> > +}
> > +
> > +void
> > +rte_eal_primary_secondary_del_action(const char *name)
> > +{
> > +	struct action_entry *entry = find_action_entry_by_name(name);
> > +
> > +	TAILQ_REMOVE(&action_entry_list, entry, next);
> > +	free(entry);
> > +}
> > +
> > +#define MAX_SECONDARY_PROCS	8
> > +
> > +static int efd_pri_sec; /* epoll fd for primary/secondary channel thread */
> 
> I think it's not a good idea to use "pri". For me, "private" comes to
> my mind firstly but not "primary".
> 
> > +static int fd_listen;   /* unix listen socket by primary */
> > +static int fd_to_pri;   /* only used by secondary process */
> > +static int fds_to_sec[MAX_SECONDARY_PROCS];
> 
> Too many vars. I'd suggest to use a struct here, which could also make
> the naming a bit simpler. For instance,
> 
> struct mp_fds {
>         int efd;
> 
>         union {
>                 /* fds for primary process */
>                 struct {
>                         int listen;
> 			/* fds used to send msg to secondary process */
>                         int secondaries[...];
>                 };
> 
>                 /* fds for secondary process */
>                 struct {
> 			/* fds used to send msg to the primary process */
>                         int primary;
>                 };
>         };
> };
> 
> It also separates the scope well. Note that above field naming does
> not like perfect though. Feel free to come up with some better names.

You can always make the code look so clean, thank you!

[...]

> > +/** Path of primary/secondary communication unix socket file. */
> > +#define PRIMARY_SECONDARY_UNIX_PATH_FMT "%s/.%s_unix"
> > +static inline const char *
> > +eal_primary_secondary_unix_path(void)
> > +{
> > +	static char buffer[PATH_MAX]; /* static so auto-zeroed */
> > +	const char *directory = default_config_dir;
> > +	const char *home_dir = getenv("HOME");
> 
> It's not a good practice to generate such file at HOME dir. User would
> be surprised to find it at HOME dir. In the worst case, user might delete
> it.

This way is the legacy way in DPDK, for example the config path. So I think we should fix that in another patch.

> 
> The more common way is to put it to tmp dir, like "/tmp".

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v2 00/12] support to run vdev in the secondary process
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (11 preceding siblings ...)
  2017-08-25  9:40 ` [PATCH 12/12] examples/helloworld: do not exit automatically Jianfeng Tan
@ 2017-09-28 13:55 ` Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 01/12] cryptodev: remove crypto vdev init API Jianfeng Tan
                     ` (11 more replies)
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
  13 siblings, 12 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

v2:
  - Address Gaetan's comment in patch 2.
  - Add RTE_LOGTYPE_BUS suggested by Gaetan.
  - Don't moving crypto vdev into drivers/bus/vdev, instead we use a
    new way (details in patch 3) which may break the ABI (the
    validate_abi.sh report a low warning of "Problems with Symbols").
  - Rename CONFIG_RTE_LIBRTE_VDEV to CONFIG_RTE_LIBRTE_VDEV_BUS.
  - Return error if there's an existing action for an action name.
  - Redefine rte_eal_primary_secondary_t as func pointer, and change
    the first parameter type to avoid explicit type casting.
  - Handle the case for vhost "primary - VM - secondary" sequence.
  - Fix a bug in recv multiple messages as one message.
  - Fix a bug of get vid of -1 in secondary process.
  - Remove the modification on helloworld example, instead we use
    symmetric_mp as the test case.
  - Address yuanhan's comment on code refactor on mp channel.

Patch 1~6: move vdev bus into drivers/bus.
Patch 7: add unix socket channel for primary/secondary communication.
Patch 8~9: make use of the channel to discover and probe virtual devices
         the primary process.
Patch 10~12: support to run vhost-pmd in the secondary process.

How to test:

Step 1: run symmetric_mp as the primary process.
  $ ./symmetric_mp -c 2 --proc-type=auto ... \
          --vdev 'net_vhost0,iface=/tmp/sock1,queues=2' \
	  --vdev 'net_vhost1,iface=/tmp/sock2,queues=2' \
	  -- -p 3 --num-procs=2 --proc-id=0

Step 2: run testpmd as the secondary process.
  $ ./symmetric_mp -c 4 --proc-type=auto -- -p 3 --num-procs=2 --proc-id=1

Step 3: start VM1.
  $ ./qemu-system-x86_64 ... -chardev socket,id=chr1,path=/tmp/sock1 \
          -netdev type=vhost-user,id=net1,chardev=chr1,vhostforce,queues=2 \
          -device virtio-net-pci,netdev=net1,mq=on,vectors=6 ...

Step 4: start VM2.
  $ ./qemu-system-x86_64 ... -chardev socket,id=chr1,path=/tmp/sock2 \
          -netdev type=vhost-user,id=net1,chardev=chr1,vhostforce,queues=2 \
          -device virtio-net-pci,netdev=net1,mq=on,vectors=6 ...

Step 5: enable multi queue in VM1 and VM2.
  $ ethtool -L ethX combined 2

Note in this test case, only queue 1, i.e., secondary process can process
packets. To use queue 1, basically, we can run command like:
  $ taskset -c 1 <commands>


Jianfeng Tan (12):
  cryptodev: remove crypto vdev init API
  eal: avoid calling rte_vdev_init()
  cryptodev: avoid dependency on rte_vdev.h
  bus/fslmc: introduce RTE_LOGTYPE_BUS for bus drivers
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: normalize log type
  eal: add channel for primary/secondary communication
  bus/vdev: scan and probe vdev in secondary processes
  ethdev: support attach vdev in secondary process
  vhost: allocate virtio_net in memzone
  vhost: support to kick in secondary process
  net/vhost: support to run in the secondary process

 config/common_base                              |   5 +
 doc/guides/rel_notes/deprecation.rst            |   5 -
 drivers/bus/Makefile                            |   2 +
 drivers/bus/fslmc/fslmc_bus.c                   |   5 +-
 drivers/bus/fslmc/fslmc_logs.h                  |  42 +-
 drivers/bus/fslmc/fslmc_vfio.c                  |   4 +-
 drivers/bus/vdev/Makefile                       |  55 +++
 drivers/bus/vdev/rte_bus_vdev_version.map       |  10 +
 drivers/bus/vdev/rte_vdev.h                     | 153 ++++++++
 drivers/bus/vdev/vdev.c                         | 440 +++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                    |  40 ++
 drivers/net/vhost/rte_eth_vhost.c               | 200 +++++++++-
 lib/librte_cryptodev/rte_cryptodev.c            |   6 -
 lib/librte_cryptodev/rte_cryptodev.h            |  18 -
 lib/librte_cryptodev/rte_cryptodev_pmd.c        |   9 +-
 lib/librte_cryptodev/rte_cryptodev_vdev.c       | 161 ++++++++
 lib/librte_cryptodev/rte_cryptodev_vdev.h       |   3 +-
 lib/librte_cryptodev/rte_cryptodev_version.map  |   1 -
 lib/librte_eal/bsdapp/eal/Makefile              |   1 -
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  21 +-
 lib/librte_eal/common/eal_common_log.c          |   1 +
 lib/librte_eal/common/eal_common_proc.c         | 498 ++++++++++++++++++++++++
 lib/librte_eal/common/eal_common_vdev.c         | 342 ----------------
 lib/librte_eal/common/eal_filesystem.h          |  18 +
 lib/librte_eal/common/eal_private.h             |  10 +
 lib/librte_eal/common/include/rte_dev.h         |  24 +-
 lib/librte_eal/common/include/rte_eal.h         |  68 ++++
 lib/librte_eal/common/include/rte_log.h         |   1 +
 lib/librte_eal/common/include/rte_vdev.h        | 131 -------
 lib/librte_eal/linuxapp/eal/Makefile            |   1 -
 lib/librte_eal/linuxapp/eal/eal.c               |   6 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
 lib/librte_ether/rte_ethdev_vdev.h              |  26 +-
 lib/librte_vhost/rte_vhost.h                    |   3 +
 lib/librte_vhost/rte_vhost_version.map          |   7 +
 lib/librte_vhost/socket.c                       |   2 +
 lib/librte_vhost/vhost.c                        |  71 +++-
 lib/librte_vhost/vhost.h                        |   7 +-
 lib/librte_vhost/vhost_user.c                   |  17 +-
 mk/rte.app.mk                                   |   1 +
 42 files changed, 1799 insertions(+), 634 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 create mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v2 01/12] cryptodev: remove crypto vdev init API
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 02/12] eal: avoid calling rte_vdev_init() Jianfeng Tan
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Remove rte_cryptodev_create_vdev().

CC: Pablo de Lara <pablo.de.lara.guarch@intel.com>

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 18 ------------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 4 files changed, 30 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3362f33..665e502 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -96,11 +96,6 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * cryptodev: the following function will be static in 17.11 and included
   by all crypto drivers, therefore, will not be public:
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 327d7e8..12c46a5 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 7ec9c4b..c5d6939 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -49,7 +49,6 @@ extern "C" {
 #include "rte_crypto.h"
 #include "rte_dev.h"
 #include <rte_common.h>
-#include <rte_vdev.h>
 
 extern const char **rte_cyptodev_names;
 
@@ -434,23 +433,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e9ba88a..3b05a4d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 02/12] eal: avoid calling rte_vdev_init()
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 01/12] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 03/12] cryptodev: avoid dependency on rte_vdev.h Jianfeng Tan
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..87e2bf8 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,12 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 03/12] cryptodev: avoid dependency on rte_vdev.h
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 01/12] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 02/12] eal: avoid calling rte_vdev_init() Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-10-05 13:13     ` Jan Blunck
  2017-09-28 13:55   ` [PATCH v2 04/12] bus/fslmc: introduce RTE_LOGTYPE_BUS for bus drivers Jianfeng Tan
                     ` (8 subsequent siblings)
  11 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

The helper API, rte_cryptodev_vdev_pmd_init(), has a parameter of
struct rte_vdev_device *, which needs to include rte_vdev.h.

We will move vdev into drivers/bus, so we need to avoid such
dependency. And also, we cannot break the ABI.

This patch changes that pointer to void *, and defines an internal
structure same with struct rte_vdev_device.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_cryptodev/rte_cryptodev_pmd.c  |   9 +-
 lib/librte_cryptodev/rte_cryptodev_vdev.c | 161 ++++++++++++++++++++++++++++++
 lib/librte_cryptodev/rte_cryptodev_vdev.h |   3 +-
 3 files changed, 169 insertions(+), 4 deletions(-)
 create mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.c

diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index a57faad..60b3980 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -75,9 +75,14 @@ rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
 	return 0;
 }
 
+struct vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;
+	struct rte_device device;
+};
+
 struct rte_cryptodev *
 rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
-		int socket_id, struct rte_vdev_device *vdev)
+		int socket_id, void *vdev)
 {
 	struct rte_cryptodev *cryptodev;
 
@@ -99,7 +104,7 @@ rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
 					" data");
 	}
 
-	cryptodev->device = &vdev->device;
+	cryptodev->device = &((struct vdev_device *)vdev)->device;
 
 	/* initialise user call-back tail queue */
 	TAILQ_INIT(&(cryptodev->link_intr_cbs));
diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.c b/lib/librte_cryptodev/rte_cryptodev_vdev.c
new file mode 100644
index 0000000..4af8d51
--- /dev/null
+++ b/lib/librte_cryptodev/rte_cryptodev_vdev.c
@@ -0,0 +1,161 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include "rte_cryptodev_vdev.h"
+#include "rte_cryptodev_pci.h"
+#include "rte_cryptodev_pmd.h"
+
+/**
+ * Parse name from argument
+ */
+static int
+rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	struct rte_crypto_vdev_init_params *params = extra_args;
+
+	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
+		CDEV_LOG_ERR("Invalid name %s, should be less than "
+				"%u bytes", value,
+				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
+		return -1;
+	}
+
+	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
+
+	return 0;
+}
+
+/**
+ * Parse integer from argument
+ */
+static int
+rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	int *i = extra_args;
+
+	*i = atoi(value);
+	if (*i < 0) {
+		CDEV_LOG_ERR("Argument has to be positive.");
+		return -1;
+	}
+
+	return 0;
+}
+
+struct vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;
+	struct rte_device device;
+};
+
+struct rte_cryptodev *
+rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
+		int socket_id, void *vdev)
+{
+	struct rte_cryptodev *cryptodev;
+
+	/* allocate device structure */
+	cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
+	if (cryptodev == NULL)
+		return NULL;
+
+	/* allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket("cryptodev device private",
+						dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						socket_id);
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private device"
+					" data");
+	}
+
+	cryptodev->device = &((struct vdev_device *)vdev)->device;
+
+	/* initialise user call-back tail queue */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	return cryptodev;
+}
+
+int
+rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
+		const char *input_args)
+{
+	struct rte_kvargs *kvlist = NULL;
+	int ret = 0;
+
+	if (params == NULL)
+		return -EINVAL;
+
+	if (input_args) {
+		kvlist = rte_kvargs_parse(input_args,
+				cryptodev_vdev_valid_params);
+		if (kvlist == NULL)
+			return -1;
+
+		ret = rte_kvargs_process(kvlist,
+					RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->max_nb_queue_pairs);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist,
+					RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->max_nb_sessions);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
+					&rte_cryptodev_vdev_parse_integer_arg,
+					&params->socket_id);
+		if (ret < 0)
+			goto free_kvlist;
+
+		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
+					&rte_cryptodev_vdev_parse_name_arg,
+					params);
+		if (ret < 0)
+			goto free_kvlist;
+	}
+
+free_kvlist:
+	rte_kvargs_free(kvlist);
+	return ret;
+}
diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.h b/lib/librte_cryptodev/rte_cryptodev_vdev.h
index 94ab9d3..1142d1d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_vdev.h
+++ b/lib/librte_cryptodev/rte_cryptodev_vdev.h
@@ -33,7 +33,6 @@
 #ifndef _RTE_CRYPTODEV_VDEV_H_
 #define _RTE_CRYPTODEV_VDEV_H_
 
-#include <rte_vdev.h>
 #include <inttypes.h>
 
 #include "rte_cryptodev.h"
@@ -80,7 +79,7 @@ struct rte_crypto_vdev_init_params {
  */
 struct rte_cryptodev *
 rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
-		int socket_id, struct rte_vdev_device *vdev);
+		int socket_id, void *vdev);
 
 /**
  * @internal
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 04/12] bus/fslmc: introduce RTE_LOGTYPE_BUS for bus drivers
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (2 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 03/12] cryptodev: avoid dependency on rte_vdev.h Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 05/12] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Introduce a new log type, RTE_LOGTYPE_BUS, for bus drivers. And
change fslmc to use this type for logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/fslmc/fslmc_bus.c           |  5 +---
 drivers/bus/fslmc/fslmc_logs.h          | 42 ++++-----------------------------
 drivers/bus/fslmc/fslmc_vfio.c          |  4 +---
 lib/librte_eal/common/eal_common_log.c  |  1 +
 lib/librte_eal/common/include/rte_log.h |  1 +
 5 files changed, 9 insertions(+), 44 deletions(-)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index f71598d..b5ff1ba 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -34,7 +34,6 @@
 #include <dirent.h>
 #include <stdbool.h>
 
-#include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
@@ -44,9 +43,7 @@
 
 #include "rte_fslmc.h"
 #include "fslmc_vfio.h"
-
-#define FSLMC_BUS_LOG(level, fmt, args...) \
-	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
+#include "fslmc_logs.h"
 
 struct rte_fslmc_bus rte_fslmc_bus;
 
diff --git a/drivers/bus/fslmc/fslmc_logs.h b/drivers/bus/fslmc/fslmc_logs.h
index 1f7c24b..dbf2281 100644
--- a/drivers/bus/fslmc/fslmc_logs.h
+++ b/drivers/bus/fslmc/fslmc_logs.h
@@ -33,44 +33,12 @@
 #ifndef _FSLMC_LOGS_H_
 #define _FSLMC_LOGS_H_
 
-#define PMD_INIT_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)
+#include <rte_log.h>
 
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_INIT
-#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
-#else
-#define PMD_INIT_FUNC_TRACE() do { } while (0)
-#endif
+#define FSLMC_BUS_LOG(level, fmt, args...) \
+	RTE_LOG(level, BUS, "%s(): " fmt "\n", __func__, ##args)
 
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_RX
-#define PMD_RX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_RX_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX
-#define PMD_TX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX_FREE
-#define PMD_TX_FREE_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_TX_FREE_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
-#define PMD_DRV_LOG_RAW(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt, __func__, ## args)
-#else
-#define PMD_DRV_LOG_RAW(level, fmt, args...) do { } while (0)
-#endif
-
-#define PMD_DRV_LOG(level, fmt, args...) \
-	PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
+#define FSLMC_VFIO_LOG(level, fmt, args...) \
+	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
 
 #endif /* _FSLMC_LOGS_H_ */
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 45e5927..f35a244 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -61,12 +61,10 @@
 
 #include "portal/dpaa2_hw_pvt.h"
 #include "portal/dpaa2_hw_dpio.h"
+#include "fslmc_logs.h"
 
 #define VFIO_MAX_CONTAINERS	1
 
-#define FSLMC_VFIO_LOG(level, fmt, args...) \
-	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
-
 /** Pathname of FSL-MC devices directory. */
 #define SYSFS_FSL_MC_DEVICES "/sys/bus/fsl-mc/devices"
 
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index 0e3b932..95371eb 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -279,6 +279,7 @@ static const struct logtype logtype_strings[] = {
 	{RTE_LOGTYPE_CRYPTODEV,  "cryptodev"},
 	{RTE_LOGTYPE_EFD,        "efd"},
 	{RTE_LOGTYPE_EVENTDEV,   "eventdev"},
+	{RTE_LOGTYPE_BUS,        "bus"},
 	{RTE_LOGTYPE_USER1,      "user1"},
 	{RTE_LOGTYPE_USER2,      "user2"},
 	{RTE_LOGTYPE_USER3,      "user3"},
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index ec8dba7..c1bb4c7 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -87,6 +87,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
+#define RTE_LOGTYPE_BUS       20 /**< Log related to bus. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 05/12] bus/vdev: move to vdev bus to drivers/bus
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (3 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 04/12] bus/fslmc: introduce RTE_LOGTYPE_BUS for bus drivers Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 06/12] bus/vdev: normalize log type Jianfeng Tan
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 drivers/bus/Makefile                      |   2 +
 drivers/bus/vdev/Makefile                 |  55 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |  10 +
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 343 ++++++++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/Makefile        |   1 -
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 -----------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   1 -
 mk/rte.app.mk                             |   1 +
 13 files changed, 571 insertions(+), 499 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 12f6be9..e240cad 100644
--- a/config/common_base
+++ b/config/common_base
@@ -751,3 +751,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 0224214..ac8c428 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -35,4 +35,6 @@ core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..6c48ba0
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,55 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..69740c3
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,10 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+	rte_cryptodev_vdev_pmd_init
+	rte_cryptodev_vdev_parse_init_params
+};
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..8a1b00a
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,343 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 005019e..6fee587 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..7eeb06a 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5386d3a..8bfc343 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -166,28 +166,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -312,4 +290,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 90bca4d..33faa18 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -80,7 +80,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..9b237c5 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -97,6 +97,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 06/12] bus/vdev: normalize log type
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (4 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 05/12] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 07/12] eal: add channel for primary/secondary communication Jianfeng Tan
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Use RTE_LOGTYPE_BUS for logging in vdev bus.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      |  9 +++++----
 drivers/bus/vdev/vdev_logs.h | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 8a1b00a..e0ba0da 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,7 @@
 #include <rte_errno.h>
 
 #include "rte_vdev.h"
+#include "vdev_logs.h"
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +104,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -189,7 +190,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -212,7 +213,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -293,7 +294,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..09ff973
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,40 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#define VDEV_LOG(level, fmt, args...) \
+	RTE_LOG(level, BUS, "%s(): " fmt "\n", __func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (5 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 06/12] bus/vdev: normalize log type Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-28 15:01     ` Ananyev, Konstantin
  2017-10-05 12:01     ` Jan Blunck
  2017-09-28 13:55   ` [PATCH v2 08/12] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
                     ` (4 subsequent siblings)
  11 siblings, 2 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Previouly, there is only one way for primary/secondary to exchange
messages, that is, primary process writes info into some predefind
file, and secondary process reads info out. That cannot address
the requirements:
  a. Secondary wants to send info to primary, for example, secondary
     would like to send request (about some specific vdev to primary).
  b. Sending info at any time, instead of just initialization time.
  c. Share FDs with the other side, for vdev like vhost, related FDs
     (memory region, kick) should be shared.

This patch proposes to create a communication channel, as an unix
socket connection, for above requirements. Primary will listen on
the unix socket; secondary will connect this socket to talk.

Three new APIs are added:

  1. rte_eal_mp_action_register is used to register an action,
     indexed by a string; if the calling component wants to
     response the messages from the corresponding component in
     its primary process or secondary processes.
  2. rte_eal_mp_action_unregister is used to unregister the action
     if the calling component does not want to response the messages.
  3. rte_eal_mp_sendmsg is used to send a message.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
 lib/librte_eal/common/eal_common_proc.c         | 498 ++++++++++++++++++++++++
 lib/librte_eal/common/eal_filesystem.h          |  18 +
 lib/librte_eal/common/eal_private.h             |  10 +
 lib/librte_eal/common/include/rte_eal.h         |  68 ++++
 lib/librte_eal/linuxapp/eal/eal.c               |   6 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
 7 files changed, 616 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 47a09ea..f895916 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -238,3 +238,11 @@ EXPERIMENTAL {
 	rte_service_start_with_defaults;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eal_primary_secondary_add_action;
+	rte_eal_primary_secondary_del_action;
+	rte_eal_primary_secondary_sendmsg;
+} DPDK_17.11;
diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
index 60526ca..eb5a502 100644
--- a/lib/librte_eal/common/eal_common_proc.c
+++ b/lib/librte_eal/common/eal_common_proc.c
@@ -33,8 +33,21 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rte_log.h>
 #include <rte_eal.h>
+#include <rte_lcore.h>
+#include <rte_common.h>
 
+#include "eal_private.h"
 #include "eal_filesystem.h"
 #include "eal_internal_cfg.h"
 
@@ -59,3 +72,488 @@ rte_eal_primary_proc_alive(const char *config_file_path)
 
 	return !!ret;
 }
+
+struct action_entry {
+	TAILQ_ENTRY(action_entry) next;      /**< Next attached action entry */
+
+#define MAX_ACTION_NAME_LEN	64
+	char action_name[MAX_ACTION_NAME_LEN];
+	rte_eal_mp_t action;
+};
+
+/** Double linked list of actions. */
+TAILQ_HEAD(action_entry_list, action_entry);
+
+static struct action_entry_list action_entry_list =
+	TAILQ_HEAD_INITIALIZER(action_entry_list);
+
+static struct action_entry *
+find_action_entry_by_name(const char *name)
+{
+	int len = strlen(name);
+	struct action_entry *entry;
+
+	TAILQ_FOREACH(entry, &action_entry_list, next) {
+		if (strncmp(entry->action_name, name, len) == 0)
+			break;
+	}
+
+	return entry;
+}
+
+int
+rte_eal_mp_action_register(const char *action_name, rte_eal_mp_t action)
+{
+	struct action_entry *entry = malloc(sizeof(struct action_entry));
+
+	if (entry == NULL)
+		return -ENOMEM;
+
+	if (find_action_entry_by_name(action_name) != NULL)
+		return -EEXIST;
+
+	strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
+	entry->action = action;
+	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
+	return 0;
+}
+
+void
+rte_eal_mp_action_unregister(const char *name)
+{
+	struct action_entry *entry = find_action_entry_by_name(name);
+
+	TAILQ_REMOVE(&action_entry_list, entry, next);
+	free(entry);
+}
+
+/* The maximum amount of fd for one recvmsg/sendmsg */
+#define SCM_MAX_FD		253
+#define MAX_SECONDARY_PROCS	8
+#define MAX_MESSAGE_LENGTH	1024
+
+struct mp_fds {
+	int efd;
+
+	union {
+		/* fds for primary process */
+		struct {
+			int listen;
+			/* fds used to send msg to secondary process(es) */
+			int secondaries[MAX_SECONDARY_PROCS];
+		};
+
+		/* fds for secondary process */
+		struct {
+			/* fds used to send msg to the primary process */
+			int primary;
+		};
+	};
+};
+
+static struct mp_fds mp_fds;
+
+struct msg_hdr {
+	char action_name[MAX_ACTION_NAME_LEN];
+	int fds_num;
+	int len_params;
+	char params[0];
+} __rte_packed;
+
+static int
+add_sec_proc(int fd)
+{
+	int i;
+
+	for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
+		if (mp_fds.secondaries[i] == -1)
+			break;
+
+	if (i >= MAX_SECONDARY_PROCS)
+		return -1;
+
+	mp_fds.secondaries[i] = fd;
+
+	return i;
+}
+
+static void
+del_sec_proc(int fd)
+{
+	int i;
+
+	for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
+		if (mp_fds.secondaries[i] == fd) {
+			mp_fds.secondaries[i] = -1;
+			break;
+		}
+	}
+}
+
+static int
+read_msg(int sockfd, char *buf, int buflen, int *fds, int fds_num)
+{
+	struct iovec iov;
+	struct msghdr msgh;
+	size_t fdsize = fds_num * sizeof(int);
+	char control[CMSG_SPACE(fdsize)];
+	struct cmsghdr *cmsg;
+	struct msg_hdr *hdr = (struct msg_hdr *)buf;
+	int ret, total;
+
+	/* read msg_hdr */
+	memset(&msgh, 0, sizeof(msgh));
+	iov.iov_base = hdr;
+	iov.iov_len  = sizeof(*hdr);
+
+	msgh.msg_iov = &iov;
+	msgh.msg_iovlen = 1;
+	msgh.msg_control = control;
+	msgh.msg_controllen = sizeof(control);
+
+	ret = recvmsg(sockfd, &msgh, 0);
+	if (ret != sizeof(struct msg_hdr)) {
+		RTE_LOG(ERR, EAL, "recvmsg failed\n");
+		return ret;
+	}
+
+	if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
+		RTE_LOG(ERR, EAL, "truncted msg\n");
+		return -1;
+	}
+	total = ret;
+
+	/* read auxiliary FDs if any */
+	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
+		cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
+		if ((cmsg->cmsg_level == SOL_SOCKET) &&
+			(cmsg->cmsg_type == SCM_RIGHTS)) {
+			memcpy(fds, CMSG_DATA(cmsg), fdsize);
+			break;
+		}
+	}
+
+	/* read params */
+	if (hdr->len_params) {
+		if (hdr->len_params > buflen - (int)sizeof(*hdr))
+			rte_exit(EXIT_FAILURE, "params too long\n");
+
+		ret = read(sockfd, &hdr->params, hdr->len_params);
+		if (ret != hdr->len_params)
+			rte_exit(EXIT_FAILURE, "failed to recv params\n");
+
+		total += ret;
+	}
+
+	RTE_LOG(INFO, EAL, "read msg: %s, %d\n", hdr->action_name,
+		(int)sizeof(*hdr) + hdr->len_params);
+	return total;
+}
+
+static int
+process_msg(int fd)
+{
+	int len;
+	int params_len;
+	char buf[MAX_MESSAGE_LENGTH];
+	int fds[SCM_MAX_FD];
+	struct msg_hdr *hdr;
+	struct action_entry *entry;
+
+	len = read_msg(fd, buf, MAX_MESSAGE_LENGTH, fds, SCM_MAX_FD);
+	if (len <= 0) {
+		RTE_LOG(ERR, EAL, "failed to read message: %s\n",
+			strerror(errno));
+		return -1;
+	}
+
+	hdr = (struct msg_hdr *) buf;
+
+	entry = find_action_entry_by_name(hdr->action_name);
+	if (entry == NULL) {
+		RTE_LOG(ERR, EAL, "cannot find action by: %s\n",
+			hdr->action_name);
+		return -1;
+	}
+
+	params_len = len - sizeof(struct msg_hdr);
+	entry->action(hdr->params, params_len, fds, hdr->fds_num);
+
+	return 0;
+}
+
+static int
+add_secondary(void)
+{
+	int fd;
+	struct epoll_event ev;
+
+	while (1) {
+		fd = accept(mp_fds.listen, NULL, NULL);
+		if (fd < 0 && errno == EAGAIN)
+			break;
+		else if (fd < 0) {
+			RTE_LOG(ERR, EAL, "primary failed to accept: %s\n",
+				strerror(errno));
+			return -1;
+		}
+
+		ev.events = EPOLLIN | EPOLLRDHUP;
+		ev.data.fd = fd;
+		if (epoll_ctl(mp_fds.efd, EPOLL_CTL_ADD, fd, &ev) < 0) {
+			RTE_LOG(ERR, EAL, "failed to add secondary: %s\n",
+				strerror(errno));
+			break;
+		}
+		if (add_sec_proc(fd) < 0) {
+			RTE_LOG(ERR, EAL, "too many secondary processes\n");
+			close(fd);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static void *
+mp_handler(void *arg __rte_unused)
+{
+	int fd;
+	int i, n;
+	struct epoll_event ev;
+	struct epoll_event *events;
+	int is_primary = rte_eal_process_type() == RTE_PROC_PRIMARY;
+
+	ev.events = EPOLLIN | EPOLLRDHUP;
+	ev.data.fd = (is_primary) ? mp_fds.listen : mp_fds.primary;
+	if (epoll_ctl(mp_fds.efd, EPOLL_CTL_ADD, ev.data.fd, &ev) < 0) {
+		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n",
+			strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	events = calloc(20, sizeof ev);
+
+	while (1) {
+		n = epoll_wait(mp_fds.efd, events, 20, -1);
+		for (i = 0; i < n; i++) {
+			if (is_primary && events[i].data.fd == mp_fds.listen) {
+				if (events[i].events != EPOLLIN) {
+					RTE_LOG(ERR, EAL, "what happens?\n");
+					exit(EXIT_FAILURE);
+				}
+
+				if (add_secondary() < 0)
+					break;
+
+				continue;
+			}
+
+			fd = events[i].data.fd;
+
+			if ((events[i].events & EPOLLIN)) {
+				if (process_msg(fd) < 0) {
+					RTE_LOG(ERR, EAL,
+						"failed to process msg\n");
+					if (!is_primary)
+						exit(EXIT_FAILURE);
+				}
+				continue;
+			}
+
+			/* EPOLLERR, EPOLLHUP, etc */
+			if (is_primary) {
+				RTE_LOG(ERR, EAL, "secondary exit: %d\n", fd);
+				epoll_ctl(mp_fds.efd, EPOLL_CTL_DEL, fd, NULL);
+				del_sec_proc(fd);
+				close(fd);
+			} else {
+				RTE_LOG(ERR, EAL, "primary exits, so do I\n");
+				/* Exit secondary when primary exits? */
+				exit(EXIT_FAILURE);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+int
+rte_eal_mp_channel_init(void)
+{
+	int i, fd, ret;
+	const char *path;
+	struct sockaddr_un un;
+	pthread_t tid;
+	char thread_name[RTE_MAX_THREAD_NAME_LEN];
+
+	mp_fds.efd = epoll_create1(0);
+	if (mp_fds.efd < 0) {
+		RTE_LOG(ERR, EAL, "epoll_create1 failed\n");
+		return -1;
+	}
+
+	fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create unix socket\n");
+		return -1;
+	}
+
+	memset(&un, 0, sizeof(un));
+	un.sun_family = AF_UNIX;
+	path = eal_mp_unix_path();
+	strncpy(un.sun_path, path, sizeof(un.sun_path));
+	un.sun_path[sizeof(un.sun_path) - 1] = '\0';
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
+			mp_fds.secondaries[i] = -1;
+
+		if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+			RTE_LOG(ERR, EAL, "cannot set nonblocking mode\n");
+			close(fd);
+			return -1;
+		}
+
+		/* The file still exists since last run */
+		unlink(path);
+
+		ret = bind(fd, (struct sockaddr *)&un, sizeof(un));
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "failed to bind to %s: %s\n",
+				path, strerror(errno));
+			close(fd);
+			return -1;
+		}
+		RTE_LOG(INFO, EAL, "primary bind to %s\n", path);
+
+		ret = listen(fd, 1024);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "failed to listen: %s\n",
+				strerror(errno));
+			close(fd);
+			return -1;
+		}
+		mp_fds.listen = fd;
+	} else {
+		ret = connect(fd, (struct sockaddr *)&un, sizeof(un));
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "failed to connect primary\n");
+			return -1;
+		}
+		mp_fds.primary = fd;
+	}
+
+	ret = pthread_create(&tid, NULL, mp_handler, NULL);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "failed to create thead: %s\n",
+			strerror(errno));
+		close(fd);
+		close(mp_fds.efd);
+		return -1;
+	}
+
+	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
+		 "rte_mp_handle");
+	ret = rte_thread_setname(tid, thread_name);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "failed to set thead name\n");
+		close(fd);
+		close(mp_fds.efd);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+send_msg(int fd, struct msghdr *p_msgh)
+{
+	int ret;
+
+	do {
+		ret = sendmsg(fd, p_msgh, 0);
+	} while (ret < 0 && errno == EINTR);
+
+	if (ret < 0)
+		RTE_LOG(ERR, EAL, "failed to send msg: %s\n", strerror(errno));
+
+	return ret;
+}
+
+int
+rte_eal_mp_sendmsg(const char *action_name,
+				  const void *params,
+				  int len_params,
+				  int fds[],
+				  int fds_num)
+{
+	int i;
+	int ret = 0;
+	struct msghdr msgh;
+	struct iovec iov;
+	size_t fd_size = fds_num * sizeof(int);
+	char control[CMSG_SPACE(fd_size)];
+	struct cmsghdr *cmsg;
+	struct msg_hdr *msg;
+	int len_msg;
+
+	if (fds_num > SCM_MAX_FD) {
+		RTE_LOG(ERR, EAL,
+			"Cannot send more than %d FDs\n", SCM_MAX_FD);
+		return -E2BIG;
+	}
+
+	len_msg = sizeof(struct msg_hdr) + len_params;
+	if (len_msg > MAX_MESSAGE_LENGTH) {
+		RTE_LOG(ERR, EAL, "Message is too long\n");
+		return -ENOMEM;
+	}
+
+	RTE_LOG(INFO, EAL, "send msg: %s, %d\n", action_name, len_msg);
+
+	msg = malloc(len_msg);
+	if (!msg) {
+		RTE_LOG(ERR, EAL, "Cannot alloc memory for msg\n");
+		return -ENOMEM;
+	}
+	memset(msg, 0, len_msg);
+	strcpy(msg->action_name, action_name);
+	msg->fds_num = fds_num;
+	msg->len_params = len_params;
+	memcpy(msg->params, params, len_params);
+
+	memset(&msgh, 0, sizeof(msgh));
+	memset(control, 0, sizeof(control));
+
+	iov.iov_base = (uint8_t *)msg;
+	iov.iov_len = len_msg;
+
+	msgh.msg_iov = &iov;
+	msgh.msg_iovlen = 1;
+	msgh.msg_control = control;
+	msgh.msg_controllen = sizeof(control);
+
+	cmsg = CMSG_FIRSTHDR(&msgh);
+	cmsg->cmsg_len = CMSG_LEN(fd_size);
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	memcpy(CMSG_DATA(cmsg), fds, fd_size);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
+			if (mp_fds.secondaries[i] == -1)
+				continue;
+
+			ret = send_msg(mp_fds.secondaries[i], &msgh);
+			if (ret < 0)
+				break;
+		}
+	} else {
+		ret = send_msg(mp_fds.primary, &msgh);
+	}
+
+	free(msg);
+
+	return ret;
+}
diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
index 8acbd99..3d9514f 100644
--- a/lib/librte_eal/common/eal_filesystem.h
+++ b/lib/librte_eal/common/eal_filesystem.h
@@ -67,6 +67,24 @@ eal_runtime_config_path(void)
 	return buffer;
 }
 
+/** Path of primary/secondary communication unix socket file. */
+#define MP_UNIX_PATH_FMT "%s/.%s_unix"
+static inline const char *
+eal_mp_unix_path(void)
+{
+	static char buffer[PATH_MAX]; /* static so auto-zeroed */
+	const char *directory = default_config_dir;
+	const char *home_dir = getenv("HOME");
+
+	if (getuid() != 0 && home_dir != NULL)
+		directory = home_dir;
+	snprintf(buffer, sizeof(buffer) - 1, MP_UNIX_PATH_FMT,
+		 directory, internal_config.hugefile_prefix);
+
+	return buffer;
+
+}
+
 /** Path of hugepage info file. */
 #define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
 
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 597d82e..7fbfbdf 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -355,4 +355,14 @@ bool rte_eal_using_phys_addrs(void);
  */
 struct rte_bus *rte_bus_find_by_device_name(const char *str);
 
+/**
+ * Create the unix channel for primary/secondary communication.
+ *
+ * @return
+ *   0 on success;
+ *   (<0) on failure.
+ */
+
+int rte_eal_mp_channel_init(void);
+
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
index 0e7363d..4e3d4d2 100644
--- a/lib/librte_eal/common/include/rte_eal.h
+++ b/lib/librte_eal/common/include/rte_eal.h
@@ -210,6 +210,74 @@ int rte_eal_init(int argc, char **argv);
 int rte_eal_primary_proc_alive(const char *config_file_path);
 
 /**
+ * Action function typedef used by other components.
+ *
+ * As we create unix socket channel for primary/secondary communication, use
+ * this function typedef to register action for coming messages.
+ */
+typedef int (*rte_eal_mp_t)(const void *params, int len,
+			    int fds[], int fds_num);
+/**
+ * Register an action function for primary/secondary communication.
+ *
+ * Call this function to register an action, if the calling component wants
+ * to response the messages from the corresponding component in its primary
+ * process or secondary processes.
+ *
+ * @param action_name
+ *   The action_name argument plays as the nonredundant key to find the action.
+ *
+ * @param action
+ *   The action argument is the function pointer to the action function.
+ *
+ * @return
+ *  - 0 on success.
+ *  - (<0) on failure.
+ */
+int rte_eal_mp_action_register(const char *action_name, rte_eal_mp_t action);
+/**
+ * Unregister an action function for primary/secondary communication.
+ *
+ * Call this function to unregister an action  if the calling component does
+ * not want to response the messages from the corresponding component in its
+ * primary process or secondary processes.
+ *
+ * @param action_name
+ *   The action_name argument plays as the nonredundant key to find the action.
+ *
+ */
+void rte_eal_mp_action_unregister(const char *name);
+
+/**
+ * Send a message to the primary process or the secondary processes.
+ *
+ * This function will send a message which will be responsed by the action
+ * identified by action_name of the process on the other side.
+ *
+ * @param action_name
+ *   The action_name argument is used to identify which action will be used.
+ *
+ * @param params
+ *   The params argument contains the customized message.
+ *
+ * @param len_params
+ *   The len_params argument is the length of the customized message.
+ *
+ * @param fds
+ *   The fds argument is an array of fds sent with sendmsg.
+ *
+ * @param fds_num
+ *   The fds_num argument is number of fds to be sent with sendmsg.
+ *
+ * @return
+ *  - (>=0) on success.
+ *  - (<0) on failure.
+ */
+int
+rte_eal_mp_sendmsg(const char *action_name, const void *params,
+		   int len_params, int fds[], int fds_num);
+
+/**
  * Usage function typedef used by the application usage function.
  *
  * Use this function typedef to define and call rte_set_applcation_usage_hook()
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 48f12f4..4b491b9 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -873,6 +873,12 @@ rte_eal_init(int argc, char **argv)
 
 	eal_check_mem_on_local_socket();
 
+	if (rte_eal_mp_channel_init() < 0) {
+		rte_eal_init_alert("failed to init mp channel\n");
+		rte_errno = EFAULT;
+		return -1;
+	}
+
 	if (eal_plugins_init() < 0)
 		rte_eal_init_alert("Cannot init plugins\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 8c08b8d..2e1d0e5 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -243,3 +243,11 @@ EXPERIMENTAL {
 	rte_service_start_with_defaults;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eal_primary_secondary_add_action;
+	rte_eal_primary_secondary_del_action;
+	rte_eal_primary_secondary_sendmsg;
+} DPDK_17.11;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 08/12] bus/vdev: scan and probe vdev in secondary processes
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (6 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 07/12] eal: add channel for primary/secondary communication Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-10-05 13:04     ` Jan Blunck
  2017-09-28 13:55   ` [PATCH v2 09/12] ethdev: support attach vdev in secondary process Jianfeng Tan
                     ` (3 subsequent siblings)
  11 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Base on primary/secondary communication channel, we add vdev action
to scan virtual devices in secondary processes.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 100 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index e0ba0da..1d1690f 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -104,7 +104,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +190,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			VDEV_LOG(ERR, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s", name);
 		goto fail;
 	}
 
@@ -213,7 +213,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s", name);
 		return 1;
 	}
 
@@ -252,12 +252,105 @@ rte_vdev_uninit(const char *name)
 	return 0;
 }
 
+struct vdev_action_params {
+#define VDEV_SCAN_REQUEST	1
+#define VDEV_SCAN_RESPONSE	2
+	int type;
+	char name[32];
+};
+
+static int vdev_plug(struct rte_device *dev);
+
+static int
+vdev_action(const void *params, int len,
+	    int fds[] __rte_unused,
+	    int fds_num __rte_unused)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	struct vdev_action_params ou_params;
+	const struct vdev_action_params *in_params = params;
+
+	switch (in_params->type) {
+	case VDEV_SCAN_REQUEST:
+		ou_params.type = VDEV_SCAN_RESPONSE;
+		TAILQ_FOREACH(dev, &vdev_device_list, next) {
+			VDEV_LOG(INFO, "push vdev, %s", dev->device.name);
+			strncpy(ou_params.name, dev->device.name, 32);
+			rte_eal_mp_sendmsg("vdev", &ou_params,
+							  len, NULL, 0);
+		}
+		break;
+	case VDEV_SCAN_RESPONSE:
+		VDEV_LOG(INFO, "get vdev, %s", in_params->name);
+
+		if (strlen(in_params->name) == 0) {
+			VDEV_LOG(ERR, "invalid name was passed");
+			break;
+		}
+
+		dev = find_vdev(in_params->name);
+		if (dev) {
+			VDEV_LOG(ERR, "vdev already exists: %s", in_params->name);
+			break;
+		}
+
+		devargs = alloc_devargs(in_params->name, NULL);
+		if (!devargs) {
+			VDEV_LOG(ERR, "failed to allocate memory");
+			break;
+		}
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev) {
+			VDEV_LOG(ERR, "failed to allocate memory");
+			free(devargs);
+			break;
+		}
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = 0; /* to be corrected in probe() */
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+
+		if (vdev_plug(&dev->device) < 0) {
+			VDEV_LOG(ERR, "failed to plug device %s", in_params->name);
+			free(devargs);
+			free(dev);
+		} else
+			VDEV_LOG(INFO, "plug in device: %s", in_params->name);
+
+		break;
+	default:
+		VDEV_LOG(ERR, "vdev cannot recognize this message");
+	}
+
+	return 0;
+}
+
 static int
 vdev_scan(void)
 {
 	struct rte_vdev_device *dev;
 	struct rte_devargs *devargs;
 
+	if (rte_eal_mp_action_register("vdev", vdev_action) < 0) {
+		VDEV_LOG(ERR, "vdev fails to add action");
+		return -1;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		struct vdev_action_params params;
+
+		params.type = VDEV_SCAN_REQUEST;
+		rte_eal_mp_sendmsg("vdev", &params,
+						  sizeof(params), NULL, 0);
+
+		return 0;
+	}
+
 	/* for virtual devices we scan the devargs_list populated via cmdline */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
 
@@ -287,6 +380,9 @@ vdev_probe(void)
 {
 	struct rte_vdev_device *dev;
 
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return 0;
+
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(dev, &vdev_device_list, next) {
 
@@ -294,7 +390,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			VDEV_LOG(ERR, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 09/12] ethdev: support attach vdev in secondary process
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (7 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 08/12] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-10-05 14:26     ` Jan Blunck
  2017-09-28 13:55   ` [PATCH v2 10/12] vhost: allocate virtio_net in memzone Jianfeng Tan
                     ` (2 subsequent siblings)
  11 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

When vdev driver requests an ethdev entry in secondary process,
we will identify the correct entry in rte_eth_dev_data array
and return the correct entry in the rte_eth_devices arrays.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev_vdev.h | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev_vdev.h b/lib/librte_ether/rte_ethdev_vdev.h
index 4d2c3e2..460749b 100644
--- a/lib/librte_ether/rte_ethdev_vdev.h
+++ b/lib/librte_ether/rte_ethdev_vdev.h
@@ -58,25 +58,29 @@ rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size)
 	struct rte_eth_dev *eth_dev;
 	const char *name = rte_vdev_device_name(dev);
 
-	eth_dev = rte_eth_dev_allocate(name);
-	if (!eth_dev)
-		return NULL;
-
-	if (private_data_size) {
-		eth_dev->data->dev_private = rte_zmalloc_socket(name,
-			private_data_size, RTE_CACHE_LINE_SIZE,
-			dev->device.numa_node);
-		if (!eth_dev->data->dev_private) {
-			rte_eth_dev_release_port(eth_dev);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev = rte_eth_dev_allocate(name);
+		if (!eth_dev)
 			return NULL;
+
+		if (private_data_size) {
+			eth_dev->data->dev_private = rte_zmalloc_socket(name,
+					private_data_size, RTE_CACHE_LINE_SIZE,
+					dev->device.numa_node);
+			if (!eth_dev->data->dev_private) {
+				rte_eth_dev_release_port(eth_dev);
+				return NULL;
+			}
 		}
+	} else {
+		eth_dev = rte_eth_dev_attach_secondary(name);
 	}
 
 	eth_dev->device = &dev->device;
 	eth_dev->intr_handle = NULL;
-
 	eth_dev->data->kdrv = RTE_KDRV_NONE;
 	eth_dev->data->numa_node = dev->device.numa_node;
+
 	return eth_dev;
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 10/12] vhost: allocate virtio_net in memzone
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (8 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 09/12] ethdev: support attach vdev in secondary process Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 11/12] vhost: support to kick in secondary process Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 12/12] net/vhost: support to run in the " Jianfeng Tan
  11 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Instead of allocate on the stack, change to allocate in memzone
so that we can retrieve them in secondary processes.

TODO: numa awareness.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_vhost/socket.c |  2 ++
 lib/librte_vhost/vhost.c  | 34 ++++++++++++++++++++++++++++++++--
 lib/librte_vhost/vhost.h  |  4 +++-
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 41aa3f9..35b9751 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -606,6 +606,8 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
 	int ret = -1;
 	struct vhost_user_socket *vsocket;
 
+	alloc_vhost_devices();
+
 	if (!path)
 		return -1;
 
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 0b6aa1c..2b687ea 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -47,15 +47,45 @@
 #include <rte_memory.h>
 #include <rte_malloc.h>
 #include <rte_vhost.h>
+#include <rte_memzone.h>
 
 #include "vhost.h"
 
-struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+#define MZ_VHOST_DEVICES "mz_vhost_devices"
+struct virtio_net **vhost_devices;
+
+void
+alloc_vhost_devices(void)
+{
+	const struct rte_memzone *mz;
+
+	if (vhost_devices != NULL)
+		return;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		mz = rte_memzone_reserve(MZ_VHOST_DEVICES,
+				MAX_VHOST_DEVICE * sizeof(*vhost_devices),
+				rte_socket_id(), 0);
+	} else
+		mz = rte_memzone_lookup(MZ_VHOST_DEVICES);
+
+	if (mz == NULL)
+		rte_panic("Cannot allocate memzone for vhost_devices\n");
+
+	vhost_devices = mz->addr;
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		memset(vhost_devices, 0,
+		       MAX_VHOST_DEVICE * sizeof(*vhost_devices));
+}
 
 struct virtio_net *
 get_device(int vid)
 {
-	struct virtio_net *dev = vhost_devices[vid];
+	struct virtio_net *dev;
+
+	alloc_vhost_devices();
+
+	dev = vhost_devices[vid];
 
 	if (unlikely(!dev)) {
 		RTE_LOG(ERR, VHOST_CONFIG,
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 6fe72ae..bc1f31e 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -278,7 +278,7 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
 
 extern uint64_t VHOST_FEATURES;
 #define MAX_VHOST_DEVICE	1024
-extern struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+extern struct virtio_net **vhost_devices;
 
 /* Convert guest physical address to host physical address */
 static __rte_always_inline phys_addr_t
@@ -300,6 +300,8 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size)
 	return 0;
 }
 
+
+void alloc_vhost_devices(void);
 struct virtio_net *get_device(int vid);
 
 int vhost_new_device(void);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 11/12] vhost: support to kick in secondary process
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (9 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 10/12] vhost: allocate virtio_net in memzone Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-28 13:55   ` [PATCH v2 12/12] net/vhost: support to run in the " Jianfeng Tan
  11 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

To support kick in secondary process, we propose callfd_pri and
kickfd_pri to store the value in primary process; and by a new
API, rte_vhost_set_vring_effective_fd(), we can set effective
callfd and kickfd which can be used by secondary process.

Note in this case, either primary process or the secondary process
can kick the frontend; that is, they cannot kick a vring at the
same time.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_vhost/rte_vhost.h           |  3 +++
 lib/librte_vhost/rte_vhost_version.map |  7 +++++++
 lib/librte_vhost/vhost.c               | 37 ++++++++++++++++++++++++++++------
 lib/librte_vhost/vhost.h               |  3 +++
 lib/librte_vhost/vhost_user.c          | 17 ++++++++--------
 5 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 8c974eb..c82f249 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -432,6 +432,9 @@ int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 			      struct rte_vhost_vring *vring);
 
+int rte_vhost_set_vring_effective_fd(int vid, uint16_t vring_idx,
+				     int callfd, int kickfd);
+
 /**
  * Get vhost RX queue avail count.
  *
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 1e70495..02142df 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -52,3 +52,10 @@ DPDK_17.08 {
 	rte_vhost_rx_queue_count;
 
 } DPDK_17.05;
+
+DPDK_17.11 {
+	global:
+
+	rte_vhost_set_vring_effective_fd;
+
+} DPDK_17.08;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 2b687ea..11a3db1 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -98,10 +98,10 @@ get_device(int vid)
 static void
 cleanup_vq(struct vhost_virtqueue *vq, int destroy)
 {
-	if ((vq->callfd >= 0) && (destroy != 0))
-		close(vq->callfd);
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
+	if ((vq->callfd_pri >= 0) && (destroy != 0))
+		close(vq->callfd_pri);
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
 }
 
 /*
@@ -146,6 +146,8 @@ init_vring_queue(struct vhost_virtqueue *vq)
 
 	vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
 	vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->kickfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->callfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
 
 	/* Backends are set to -1 indicating an inactive device. */
 	vq->backend = -1;
@@ -435,13 +437,36 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 	vring->used  = vq->used;
 	vring->log_guest_addr  = vq->log_guest_addr;
 
-	vring->callfd  = vq->callfd;
-	vring->kickfd  = vq->kickfd;
+	vring->callfd  = vq->callfd_pri;
+	vring->kickfd  = vq->kickfd_pri;
 	vring->size    = vq->size;
 
 	return 0;
 }
 
+int
+rte_vhost_set_vring_effective_fd(int vid, uint16_t vring_idx,
+				 int callfd, int kickfd)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (!dev)
+		return -1;
+
+	if (vring_idx >= VHOST_MAX_VRING)
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (!vq)
+		return -1;
+
+	vq->callfd = callfd;
+	vq->kickfd = kickfd;
+
+	return 0;
+}
 uint16_t
 rte_vhost_avail_entries(int vid, uint16_t queue_id)
 {
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index bc1f31e..be57c52 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -98,9 +98,12 @@ struct vhost_virtqueue {
 	/* Backend value to determine if device should started/stopped */
 	int			backend;
 	/* Used to notify the guest (trigger interrupt) */
+	int			callfd_pri;
 	int			callfd;
 	/* Currently unused as polling mode is enabled */
+	int			kickfd_pri;
 	int			kickfd;
+
 	int			enabled;
 
 	/* Physical address of used ring, for logging */
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index ad2e8d3..3d1eea4 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -661,10 +661,10 @@ vhost_user_set_vring_call(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 		"vring call idx:%d file:%d\n", file.index, file.fd);
 
 	vq = dev->virtqueue[file.index];
-	if (vq->callfd >= 0)
-		close(vq->callfd);
+	if (vq->callfd_pri >= 0)
+		close(vq->callfd_pri);
 
-	vq->callfd = file.fd;
+	vq->callfd_pri = vq->callfd = file.fd;
 }
 
 static void
@@ -682,9 +682,9 @@ vhost_user_set_vring_kick(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 		"vring kick idx:%d file:%d\n", file.index, file.fd);
 
 	vq = dev->virtqueue[file.index];
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
-	vq->kickfd = file.fd;
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
+	vq->kickfd_pri = vq->kickfd = file.fd;
 }
 
 static void
@@ -731,10 +731,11 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 	 * sent and only sent in vhost_vring_stop.
 	 * TODO: cleanup the vring, it isn't usable since here.
 	 */
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
 
 	vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->kickfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
 
 	if (dev->dequeue_zero_copy)
 		free_zmbufs(vq);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
                     ` (10 preceding siblings ...)
  2017-09-28 13:55   ` [PATCH v2 11/12] vhost: support to kick in secondary process Jianfeng Tan
@ 2017-09-28 13:55   ` Jianfeng Tan
  2017-09-29  8:28     ` Yuanhan Liu
  2017-09-30  8:23     ` Yuanhan Liu
  11 siblings, 2 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-09-28 13:55 UTC (permalink / raw)
  To: dev
  Cc: bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, yliu, maxime.coquelin, mtetsuyah, ferruh.yigit,
	Jianfeng Tan

Support to run vhost-pmd vdev in the secondary process. We obtain
information, like memory regions, kickfd, callfd, through
primary/secondary communication channel.

And by invoking rte_vhost_set_vring_effective_fd, we can set the
kickfd which can be recognized by the secondary process.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vhost/rte_eth_vhost.c | 200 +++++++++++++++++++++++++++++++++++---
 1 file changed, 187 insertions(+), 13 deletions(-)

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 0dac5e6..6a685a3 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -33,6 +33,7 @@
 #include <unistd.h>
 #include <pthread.h>
 #include <stdbool.h>
+#include <sys/mman.h>
 
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
@@ -46,6 +47,20 @@
 
 #include "rte_eth_vhost.h"
 
+#define VHOST_MSG_TYPE_REGIONS	1
+#define VHOST_MSG_TYPE_SET_FDS	2
+#define VHOST_MSG_TYPE_INIT	3
+
+struct vhost_params {
+	int type;
+	union {
+		int vid;
+		int portid;
+	};
+	int vring_idx;
+	struct rte_vhost_mem_region regions[0];
+};
+
 enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM};
 
 #define ETH_VHOST_IFACE_ARG		"iface"
@@ -550,6 +565,66 @@ update_queuing_status(struct rte_eth_dev *dev)
 }
 
 static int
+share_device(int vid)
+{
+	uint32_t i, vring_num;
+	int len;
+	int fds[8];
+	struct rte_vhost_memory *mem;
+	struct vhost_params *params;
+	struct rte_vhost_vring vring;
+
+	/* share mem table */
+	if (rte_vhost_get_mem_table(vid, &mem) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to get mem table\n");
+		return 0;
+	}
+	for (i = 0; i < mem->nregions; ++i)
+		fds[i] = mem->regions[i].fd;
+
+	len = sizeof(struct rte_vhost_mem_region) * mem->nregions;
+	params = malloc(sizeof(*params) + len);
+	if (params == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to allocate memory\n");
+		return -1;
+	}
+
+	params->type = VHOST_MSG_TYPE_REGIONS;
+	params->vid = vid;
+	memcpy(params->regions, mem->regions, len);
+
+	if (rte_eal_mp_sendmsg("vhost pmd", params, sizeof(*params) + len,
+			       fds, mem->nregions) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to share mem table\n");
+		free(params);
+		return -1;
+	}
+
+	/* share callfd and kickfd */
+	params->type = VHOST_MSG_TYPE_SET_FDS;
+	vring_num = rte_vhost_get_vring_num(vid);
+	for (i = 0; i < vring_num; i++) {
+		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
+			RTE_LOG(ERR, PMD, "Failed to get vring, idx = %d\n", i);
+			free(params);
+			return -1;
+		}
+
+		params->vring_idx = i;
+		fds[0] = vring.callfd;
+		fds[1] = vring.kickfd;
+		if (rte_eal_mp_sendmsg("vhost pmd", params,
+				       sizeof(*params), fds, 2) < 0) {
+			RTE_LOG(ERR, PMD, "Failed to set fds\n");
+			return -1;
+		}
+	}
+
+	free(params);
+	return 0;
+}
+
+static int
 new_device(int vid)
 {
 	struct rte_eth_dev *eth_dev;
@@ -610,6 +685,8 @@ new_device(int vid)
 	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
 				      NULL, NULL);
 
+	share_device(vid);
+
 	return 0;
 }
 
@@ -1025,13 +1102,6 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	RTE_LOG(INFO, PMD, "Creating VHOST-USER backend on numa socket %u\n",
 		numa_node);
 
-	/* now do all data allocation - for eth_dev structure and internal
-	 * (private) data
-	 */
-	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
-	if (data == NULL)
-		goto error;
-
 	list = rte_zmalloc_socket(name, sizeof(*list), 0, numa_node);
 	if (list == NULL)
 		goto error;
@@ -1073,11 +1143,7 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	rte_spinlock_init(&vring_state->lock);
 	vring_states[eth_dev->data->port_id] = vring_state;
 
-	/* We'll replace the 'data' originally allocated by eth_dev. So the
-	 * vhost PMD resources won't be shared between multi processes.
-	 */
-	rte_memcpy(data, eth_dev->data, sizeof(*data));
-	eth_dev->data = data;
+	data = eth_dev->data;
 
 	data->nb_rx_queues = queues;
 	data->nb_tx_queues = queues;
@@ -1125,6 +1191,30 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	return -1;
 }
 
+static int
+eth_dev_vhost_attach(struct rte_vdev_device *dev)
+{
+	struct rte_eth_dev *eth_dev = NULL;
+	struct rte_eth_dev_data *data = NULL;
+
+	RTE_LOG(INFO, PMD, "Attach vhost user port\n");
+
+	/* reserve an ethdev entry */
+	eth_dev = rte_eth_vdev_allocate(dev, sizeof(struct pmd_internal));
+	if (eth_dev == NULL)
+		return -1;
+
+	eth_dev->dev_ops = &ops;
+
+	/* finally assign rx and tx ops */
+	eth_dev->rx_pkt_burst = eth_vhost_rx;
+	eth_dev->tx_pkt_burst = eth_vhost_tx;
+
+	data = eth_dev->data;
+
+	return data->port_id;
+}
+
 static inline int
 open_iface(const char *key __rte_unused, const char *value, void *extra_args)
 {
@@ -1154,10 +1244,84 @@ open_int(const char *key __rte_unused, const char *value, void *extra_args)
 }
 
 static int
+vhost_pmd_action(const void *params, int len, int fds[], int fds_num)
+{
+	int i;
+	int vid;
+	void *base_addr;
+	const struct vhost_params *p = params;
+	const struct rte_vhost_mem_region *regions;
+
+	if (len < (int)sizeof(*p)) {
+		RTE_LOG(ERR, PMD, "message if too short\n");
+		return -1;
+	}
+
+	switch (p->type) {
+	case VHOST_MSG_TYPE_REGIONS:
+		regions = p->regions;
+		for (i = 0; i < fds_num; ++i) {
+			base_addr = mmap(regions[i].mmap_addr,
+					 regions[i].mmap_size,
+					 PROT_READ | PROT_WRITE,
+					 MAP_FIXED | MAP_SHARED, fds[i], 0);
+			if (base_addr != regions[i].mmap_addr) {
+				RTE_LOG(ERR, PMD,
+					"vhost in secondary mmap error: %s\n",
+					strerror(errno));
+				break;
+			}
+		}
+		break;
+	case VHOST_MSG_TYPE_SET_FDS:
+		rte_vhost_set_vring_effective_fd(p->vid,
+						 p->vring_idx,
+						 fds[0], fds[1]);
+		break;
+	case VHOST_MSG_TYPE_INIT:
+		vid = rte_eth_vhost_get_vid_from_port_id(p->portid);
+		share_device(vid);
+		break;
+	}
+
+	return 0;
+}
+
+static int
+probe_secondary(struct rte_vdev_device *dev)
+{
+	int portid = eth_dev_vhost_attach(dev);
+	struct rte_eth_dev *eth_dev;
+	struct pmd_internal *internal;
+	struct vhost_params p;
+
+	if (portid < 0)
+		return -1;
+
+	eth_dev = &rte_eth_devices[portid];
+	internal = eth_dev->data->dev_private;
+
+	if (!internal ||
+	    rte_atomic32_read(&internal->dev_attached) == 0) {
+		RTE_LOG(INFO, PMD, "%s is not ready\n", dev->device.name);
+		return 0;
+	}
+
+	p.type = VHOST_MSG_TYPE_INIT;
+	p.portid = portid;
+	if (rte_eal_mp_sendmsg("vhost pmd", &p, sizeof(p), NULL, 0) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to send request for init\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
 rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 {
 	struct rte_kvargs *kvlist = NULL;
-	int ret = 0;
+	int ret;
 	char *iface_name;
 	uint16_t queues;
 	uint64_t flags = 0;
@@ -1167,6 +1331,15 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 	RTE_LOG(INFO, PMD, "Initializing pmd_vhost for %s\n",
 		rte_vdev_device_name(dev));
 
+	ret = rte_eal_mp_action_register("vhost pmd", vhost_pmd_action);
+	if (ret < 0 && ret != -EEXIST) {
+		RTE_LOG(ERR, PMD, "vhost fails to add action\n");
+		return -1;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return probe_secondary(dev);
+
 	kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_arguments);
 	if (kvlist == NULL)
 		return -1;
@@ -1216,6 +1389,7 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 	eth_dev_vhost_create(dev, iface_name, queues, dev->device.numa_node,
 		flags);
 
+	ret = 0;
 out_free:
 	rte_kvargs_free(kvlist);
 	return ret;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-09-28 13:55   ` [PATCH v2 07/12] eal: add channel for primary/secondary communication Jianfeng Tan
@ 2017-09-28 15:01     ` Ananyev, Konstantin
  2017-09-28 15:29       ` Burakov, Anatoly
  2017-10-05 12:01     ` Jan Blunck
  1 sibling, 1 reply; 158+ messages in thread
From: Ananyev, Konstantin @ 2017-09-28 15:01 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: Richardson, Bruce, De Lara Guarch, Pablo, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh

Hi Jianfeng,


> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Thursday, September 28, 2017 2:56 PM
> To: dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net; yliu@fridaylinux.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com;
> Yigit, Ferruh <ferruh.yigit@intel.com>; Tan, Jianfeng <jianfeng.tan@intel.com>
> Subject: [PATCH v2 07/12] eal: add channel for primary/secondary communication
> 
> Previouly, there is only one way for primary/secondary to exchange
> messages, that is, primary process writes info into some predefind
> file, and secondary process reads info out. That cannot address
> the requirements:
>   a. Secondary wants to send info to primary, for example, secondary
>      would like to send request (about some specific vdev to primary).
>   b. Sending info at any time, instead of just initialization time.
>   c. Share FDs with the other side, for vdev like vhost, related FDs
>      (memory region, kick) should be shared.
> 
> This patch proposes to create a communication channel, as an unix
> socket connection, for above requirements. Primary will listen on
> the unix socket; secondary will connect this socket to talk.
> 
> Three new APIs are added:
> 
>   1. rte_eal_mp_action_register is used to register an action,
>      indexed by a string; if the calling component wants to
>      response the messages from the corresponding component in
>      its primary process or secondary processes.
>   2. rte_eal_mp_action_unregister is used to unregister the action
>      if the calling component does not want to response the messages.
>   3. rte_eal_mp_sendmsg is used to send a message.

I think we already have similar channel in librte_pdump().
Also it seems like eal_vfio also has it's own socket to communicate between mp/sp.
Could we probably make it generic - so same code (and socket) be used by all such  places.
Konstantin


> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
>  lib/librte_eal/common/eal_common_proc.c         | 498 ++++++++++++++++++++++++
>  lib/librte_eal/common/eal_filesystem.h          |  18 +
>  lib/librte_eal/common/eal_private.h             |  10 +
>  lib/librte_eal/common/include/rte_eal.h         |  68 ++++
>  lib/librte_eal/linuxapp/eal/eal.c               |   6 +
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
>  7 files changed, 616 insertions(+)
> 
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index 47a09ea..f895916 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -238,3 +238,11 @@ EXPERIMENTAL {
>  	rte_service_start_with_defaults;
> 
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_eal_primary_secondary_add_action;
> +	rte_eal_primary_secondary_del_action;
> +	rte_eal_primary_secondary_sendmsg;
> +} DPDK_17.11;
> diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
> index 60526ca..eb5a502 100644
> --- a/lib/librte_eal/common/eal_common_proc.c
> +++ b/lib/librte_eal/common/eal_common_proc.c
> @@ -33,8 +33,21 @@
>  #include <stdio.h>
>  #include <fcntl.h>
>  #include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <sys/epoll.h>
> +#include <limits.h>
> +#include <unistd.h>
> +#include <sys/un.h>
> +#include <errno.h>
> +#include <pthread.h>
> +
> +#include <rte_log.h>
>  #include <rte_eal.h>
> +#include <rte_lcore.h>
> +#include <rte_common.h>
> 
> +#include "eal_private.h"
>  #include "eal_filesystem.h"
>  #include "eal_internal_cfg.h"
> 
> @@ -59,3 +72,488 @@ rte_eal_primary_proc_alive(const char *config_file_path)
> 
>  	return !!ret;
>  }
> +
> +struct action_entry {
> +	TAILQ_ENTRY(action_entry) next;      /**< Next attached action entry */
> +
> +#define MAX_ACTION_NAME_LEN	64
> +	char action_name[MAX_ACTION_NAME_LEN];
> +	rte_eal_mp_t action;
> +};
> +
> +/** Double linked list of actions. */
> +TAILQ_HEAD(action_entry_list, action_entry);
> +
> +static struct action_entry_list action_entry_list =
> +	TAILQ_HEAD_INITIALIZER(action_entry_list);
> +
> +static struct action_entry *
> +find_action_entry_by_name(const char *name)
> +{
> +	int len = strlen(name);
> +	struct action_entry *entry;
> +
> +	TAILQ_FOREACH(entry, &action_entry_list, next) {
> +		if (strncmp(entry->action_name, name, len) == 0)
> +			break;
> +	}
> +
> +	return entry;
> +}
> +
> +int
> +rte_eal_mp_action_register(const char *action_name, rte_eal_mp_t action)
> +{
> +	struct action_entry *entry = malloc(sizeof(struct action_entry));
> +
> +	if (entry == NULL)
> +		return -ENOMEM;
> +
> +	if (find_action_entry_by_name(action_name) != NULL)
> +		return -EEXIST;
> +
> +	strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
> +	entry->action = action;
> +	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
> +	return 0;
> +}
> +
> +void
> +rte_eal_mp_action_unregister(const char *name)
> +{
> +	struct action_entry *entry = find_action_entry_by_name(name);
> +
> +	TAILQ_REMOVE(&action_entry_list, entry, next);
> +	free(entry);
> +}
> +
> +/* The maximum amount of fd for one recvmsg/sendmsg */
> +#define SCM_MAX_FD		253
> +#define MAX_SECONDARY_PROCS	8
> +#define MAX_MESSAGE_LENGTH	1024
> +
> +struct mp_fds {
> +	int efd;
> +
> +	union {
> +		/* fds for primary process */
> +		struct {
> +			int listen;
> +			/* fds used to send msg to secondary process(es) */
> +			int secondaries[MAX_SECONDARY_PROCS];
> +		};
> +
> +		/* fds for secondary process */
> +		struct {
> +			/* fds used to send msg to the primary process */
> +			int primary;
> +		};
> +	};
> +};
> +
> +static struct mp_fds mp_fds;
> +
> +struct msg_hdr {
> +	char action_name[MAX_ACTION_NAME_LEN];
> +	int fds_num;
> +	int len_params;
> +	char params[0];
> +} __rte_packed;
> +
> +static int
> +add_sec_proc(int fd)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +		if (mp_fds.secondaries[i] == -1)
> +			break;
> +
> +	if (i >= MAX_SECONDARY_PROCS)
> +		return -1;
> +
> +	mp_fds.secondaries[i] = fd;
> +
> +	return i;
> +}
> +
> +static void
> +del_sec_proc(int fd)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
> +		if (mp_fds.secondaries[i] == fd) {
> +			mp_fds.secondaries[i] = -1;
> +			break;
> +		}
> +	}
> +}
> +
> +static int
> +read_msg(int sockfd, char *buf, int buflen, int *fds, int fds_num)
> +{
> +	struct iovec iov;
> +	struct msghdr msgh;
> +	size_t fdsize = fds_num * sizeof(int);
> +	char control[CMSG_SPACE(fdsize)];
> +	struct cmsghdr *cmsg;
> +	struct msg_hdr *hdr = (struct msg_hdr *)buf;
> +	int ret, total;
> +
> +	/* read msg_hdr */
> +	memset(&msgh, 0, sizeof(msgh));
> +	iov.iov_base = hdr;
> +	iov.iov_len  = sizeof(*hdr);
> +
> +	msgh.msg_iov = &iov;
> +	msgh.msg_iovlen = 1;
> +	msgh.msg_control = control;
> +	msgh.msg_controllen = sizeof(control);
> +
> +	ret = recvmsg(sockfd, &msgh, 0);
> +	if (ret != sizeof(struct msg_hdr)) {
> +		RTE_LOG(ERR, EAL, "recvmsg failed\n");
> +		return ret;
> +	}
> +
> +	if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
> +		RTE_LOG(ERR, EAL, "truncted msg\n");
> +		return -1;
> +	}
> +	total = ret;
> +
> +	/* read auxiliary FDs if any */
> +	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
> +		cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
> +		if ((cmsg->cmsg_level == SOL_SOCKET) &&
> +			(cmsg->cmsg_type == SCM_RIGHTS)) {
> +			memcpy(fds, CMSG_DATA(cmsg), fdsize);
> +			break;
> +		}
> +	}
> +
> +	/* read params */
> +	if (hdr->len_params) {
> +		if (hdr->len_params > buflen - (int)sizeof(*hdr))
> +			rte_exit(EXIT_FAILURE, "params too long\n");
> +
> +		ret = read(sockfd, &hdr->params, hdr->len_params);
> +		if (ret != hdr->len_params)
> +			rte_exit(EXIT_FAILURE, "failed to recv params\n");
> +
> +		total += ret;
> +	}
> +
> +	RTE_LOG(INFO, EAL, "read msg: %s, %d\n", hdr->action_name,
> +		(int)sizeof(*hdr) + hdr->len_params);
> +	return total;
> +}
> +
> +static int
> +process_msg(int fd)
> +{
> +	int len;
> +	int params_len;
> +	char buf[MAX_MESSAGE_LENGTH];
> +	int fds[SCM_MAX_FD];
> +	struct msg_hdr *hdr;
> +	struct action_entry *entry;
> +
> +	len = read_msg(fd, buf, MAX_MESSAGE_LENGTH, fds, SCM_MAX_FD);
> +	if (len <= 0) {
> +		RTE_LOG(ERR, EAL, "failed to read message: %s\n",
> +			strerror(errno));
> +		return -1;
> +	}
> +
> +	hdr = (struct msg_hdr *) buf;
> +
> +	entry = find_action_entry_by_name(hdr->action_name);
> +	if (entry == NULL) {
> +		RTE_LOG(ERR, EAL, "cannot find action by: %s\n",
> +			hdr->action_name);
> +		return -1;
> +	}
> +
> +	params_len = len - sizeof(struct msg_hdr);
> +	entry->action(hdr->params, params_len, fds, hdr->fds_num);
> +
> +	return 0;
> +}
> +
> +static int
> +add_secondary(void)
> +{
> +	int fd;
> +	struct epoll_event ev;
> +
> +	while (1) {
> +		fd = accept(mp_fds.listen, NULL, NULL);
> +		if (fd < 0 && errno == EAGAIN)
> +			break;
> +		else if (fd < 0) {
> +			RTE_LOG(ERR, EAL, "primary failed to accept: %s\n",
> +				strerror(errno));
> +			return -1;
> +		}
> +
> +		ev.events = EPOLLIN | EPOLLRDHUP;
> +		ev.data.fd = fd;
> +		if (epoll_ctl(mp_fds.efd, EPOLL_CTL_ADD, fd, &ev) < 0) {
> +			RTE_LOG(ERR, EAL, "failed to add secondary: %s\n",
> +				strerror(errno));
> +			break;
> +		}
> +		if (add_sec_proc(fd) < 0) {
> +			RTE_LOG(ERR, EAL, "too many secondary processes\n");
> +			close(fd);
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static void *
> +mp_handler(void *arg __rte_unused)
> +{
> +	int fd;
> +	int i, n;
> +	struct epoll_event ev;
> +	struct epoll_event *events;
> +	int is_primary = rte_eal_process_type() == RTE_PROC_PRIMARY;
> +
> +	ev.events = EPOLLIN | EPOLLRDHUP;
> +	ev.data.fd = (is_primary) ? mp_fds.listen : mp_fds.primary;
> +	if (epoll_ctl(mp_fds.efd, EPOLL_CTL_ADD, ev.data.fd, &ev) < 0) {
> +		RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n",
> +			strerror(errno));
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	events = calloc(20, sizeof ev);
> +
> +	while (1) {
> +		n = epoll_wait(mp_fds.efd, events, 20, -1);
> +		for (i = 0; i < n; i++) {
> +			if (is_primary && events[i].data.fd == mp_fds.listen) {
> +				if (events[i].events != EPOLLIN) {
> +					RTE_LOG(ERR, EAL, "what happens?\n");
> +					exit(EXIT_FAILURE);
> +				}
> +
> +				if (add_secondary() < 0)
> +					break;
> +
> +				continue;
> +			}
> +
> +			fd = events[i].data.fd;
> +
> +			if ((events[i].events & EPOLLIN)) {
> +				if (process_msg(fd) < 0) {
> +					RTE_LOG(ERR, EAL,
> +						"failed to process msg\n");
> +					if (!is_primary)
> +						exit(EXIT_FAILURE);
> +				}
> +				continue;
> +			}
> +
> +			/* EPOLLERR, EPOLLHUP, etc */
> +			if (is_primary) {
> +				RTE_LOG(ERR, EAL, "secondary exit: %d\n", fd);
> +				epoll_ctl(mp_fds.efd, EPOLL_CTL_DEL, fd, NULL);
> +				del_sec_proc(fd);
> +				close(fd);
> +			} else {
> +				RTE_LOG(ERR, EAL, "primary exits, so do I\n");
> +				/* Exit secondary when primary exits? */
> +				exit(EXIT_FAILURE);
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +int
> +rte_eal_mp_channel_init(void)
> +{
> +	int i, fd, ret;
> +	const char *path;
> +	struct sockaddr_un un;
> +	pthread_t tid;
> +	char thread_name[RTE_MAX_THREAD_NAME_LEN];
> +
> +	mp_fds.efd = epoll_create1(0);
> +	if (mp_fds.efd < 0) {
> +		RTE_LOG(ERR, EAL, "epoll_create1 failed\n");
> +		return -1;
> +	}
> +
> +	fd = socket(AF_UNIX, SOCK_STREAM, 0);
> +	if (fd < 0) {
> +		RTE_LOG(ERR, EAL, "Failed to create unix socket\n");
> +		return -1;
> +	}
> +
> +	memset(&un, 0, sizeof(un));
> +	un.sun_family = AF_UNIX;
> +	path = eal_mp_unix_path();
> +	strncpy(un.sun_path, path, sizeof(un.sun_path));
> +	un.sun_path[sizeof(un.sun_path) - 1] = '\0';
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +			mp_fds.secondaries[i] = -1;
> +
> +		if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
> +			RTE_LOG(ERR, EAL, "cannot set nonblocking mode\n");
> +			close(fd);
> +			return -1;
> +		}
> +
> +		/* The file still exists since last run */
> +		unlink(path);
> +
> +		ret = bind(fd, (struct sockaddr *)&un, sizeof(un));
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to bind to %s: %s\n",
> +				path, strerror(errno));
> +			close(fd);
> +			return -1;
> +		}
> +		RTE_LOG(INFO, EAL, "primary bind to %s\n", path);
> +
> +		ret = listen(fd, 1024);
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to listen: %s\n",
> +				strerror(errno));
> +			close(fd);
> +			return -1;
> +		}
> +		mp_fds.listen = fd;
> +	} else {
> +		ret = connect(fd, (struct sockaddr *)&un, sizeof(un));
> +		if (ret < 0) {
> +			RTE_LOG(ERR, EAL, "failed to connect primary\n");
> +			return -1;
> +		}
> +		mp_fds.primary = fd;
> +	}
> +
> +	ret = pthread_create(&tid, NULL, mp_handler, NULL);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, EAL, "failed to create thead: %s\n",
> +			strerror(errno));
> +		close(fd);
> +		close(mp_fds.efd);
> +		return -1;
> +	}
> +
> +	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
> +		 "rte_mp_handle");
> +	ret = rte_thread_setname(tid, thread_name);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, EAL, "failed to set thead name\n");
> +		close(fd);
> +		close(mp_fds.efd);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +send_msg(int fd, struct msghdr *p_msgh)
> +{
> +	int ret;
> +
> +	do {
> +		ret = sendmsg(fd, p_msgh, 0);
> +	} while (ret < 0 && errno == EINTR);
> +
> +	if (ret < 0)
> +		RTE_LOG(ERR, EAL, "failed to send msg: %s\n", strerror(errno));
> +
> +	return ret;
> +}
> +
> +int
> +rte_eal_mp_sendmsg(const char *action_name,
> +				  const void *params,
> +				  int len_params,
> +				  int fds[],
> +				  int fds_num)
> +{
> +	int i;
> +	int ret = 0;
> +	struct msghdr msgh;
> +	struct iovec iov;
> +	size_t fd_size = fds_num * sizeof(int);
> +	char control[CMSG_SPACE(fd_size)];
> +	struct cmsghdr *cmsg;
> +	struct msg_hdr *msg;
> +	int len_msg;
> +
> +	if (fds_num > SCM_MAX_FD) {
> +		RTE_LOG(ERR, EAL,
> +			"Cannot send more than %d FDs\n", SCM_MAX_FD);
> +		return -E2BIG;
> +	}
> +
> +	len_msg = sizeof(struct msg_hdr) + len_params;
> +	if (len_msg > MAX_MESSAGE_LENGTH) {
> +		RTE_LOG(ERR, EAL, "Message is too long\n");
> +		return -ENOMEM;
> +	}
> +
> +	RTE_LOG(INFO, EAL, "send msg: %s, %d\n", action_name, len_msg);
> +
> +	msg = malloc(len_msg);
> +	if (!msg) {
> +		RTE_LOG(ERR, EAL, "Cannot alloc memory for msg\n");
> +		return -ENOMEM;
> +	}
> +	memset(msg, 0, len_msg);
> +	strcpy(msg->action_name, action_name);
> +	msg->fds_num = fds_num;
> +	msg->len_params = len_params;
> +	memcpy(msg->params, params, len_params);
> +
> +	memset(&msgh, 0, sizeof(msgh));
> +	memset(control, 0, sizeof(control));
> +
> +	iov.iov_base = (uint8_t *)msg;
> +	iov.iov_len = len_msg;
> +
> +	msgh.msg_iov = &iov;
> +	msgh.msg_iovlen = 1;
> +	msgh.msg_control = control;
> +	msgh.msg_controllen = sizeof(control);
> +
> +	cmsg = CMSG_FIRSTHDR(&msgh);
> +	cmsg->cmsg_len = CMSG_LEN(fd_size);
> +	cmsg->cmsg_level = SOL_SOCKET;
> +	cmsg->cmsg_type = SCM_RIGHTS;
> +	memcpy(CMSG_DATA(cmsg), fds, fd_size);
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
> +			if (mp_fds.secondaries[i] == -1)
> +				continue;
> +
> +			ret = send_msg(mp_fds.secondaries[i], &msgh);
> +			if (ret < 0)
> +				break;
> +		}
> +	} else {
> +		ret = send_msg(mp_fds.primary, &msgh);
> +	}
> +
> +	free(msg);
> +
> +	return ret;
> +}
> diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
> index 8acbd99..3d9514f 100644
> --- a/lib/librte_eal/common/eal_filesystem.h
> +++ b/lib/librte_eal/common/eal_filesystem.h
> @@ -67,6 +67,24 @@ eal_runtime_config_path(void)
>  	return buffer;
>  }
> 
> +/** Path of primary/secondary communication unix socket file. */
> +#define MP_UNIX_PATH_FMT "%s/.%s_unix"
> +static inline const char *
> +eal_mp_unix_path(void)
> +{
> +	static char buffer[PATH_MAX]; /* static so auto-zeroed */
> +	const char *directory = default_config_dir;
> +	const char *home_dir = getenv("HOME");
> +
> +	if (getuid() != 0 && home_dir != NULL)
> +		directory = home_dir;
> +	snprintf(buffer, sizeof(buffer) - 1, MP_UNIX_PATH_FMT,
> +		 directory, internal_config.hugefile_prefix);
> +
> +	return buffer;
> +
> +}
> +
>  /** Path of hugepage info file. */
>  #define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
> 
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 597d82e..7fbfbdf 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -355,4 +355,14 @@ bool rte_eal_using_phys_addrs(void);
>   */
>  struct rte_bus *rte_bus_find_by_device_name(const char *str);
> 
> +/**
> + * Create the unix channel for primary/secondary communication.
> + *
> + * @return
> + *   0 on success;
> + *   (<0) on failure.
> + */
> +
> +int rte_eal_mp_channel_init(void);
> +
>  #endif /* _EAL_PRIVATE_H_ */
> diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
> index 0e7363d..4e3d4d2 100644
> --- a/lib/librte_eal/common/include/rte_eal.h
> +++ b/lib/librte_eal/common/include/rte_eal.h
> @@ -210,6 +210,74 @@ int rte_eal_init(int argc, char **argv);
>  int rte_eal_primary_proc_alive(const char *config_file_path);
> 
>  /**
> + * Action function typedef used by other components.
> + *
> + * As we create unix socket channel for primary/secondary communication, use
> + * this function typedef to register action for coming messages.
> + */
> +typedef int (*rte_eal_mp_t)(const void *params, int len,
> +			    int fds[], int fds_num);
> +/**
> + * Register an action function for primary/secondary communication.
> + *
> + * Call this function to register an action, if the calling component wants
> + * to response the messages from the corresponding component in its primary
> + * process or secondary processes.
> + *
> + * @param action_name
> + *   The action_name argument plays as the nonredundant key to find the action.
> + *
> + * @param action
> + *   The action argument is the function pointer to the action function.
> + *
> + * @return
> + *  - 0 on success.
> + *  - (<0) on failure.
> + */
> +int rte_eal_mp_action_register(const char *action_name, rte_eal_mp_t action);
> +/**
> + * Unregister an action function for primary/secondary communication.
> + *
> + * Call this function to unregister an action  if the calling component does
> + * not want to response the messages from the corresponding component in its
> + * primary process or secondary processes.
> + *
> + * @param action_name
> + *   The action_name argument plays as the nonredundant key to find the action.
> + *
> + */
> +void rte_eal_mp_action_unregister(const char *name);
> +
> +/**
> + * Send a message to the primary process or the secondary processes.
> + *
> + * This function will send a message which will be responsed by the action
> + * identified by action_name of the process on the other side.
> + *
> + * @param action_name
> + *   The action_name argument is used to identify which action will be used.
> + *
> + * @param params
> + *   The params argument contains the customized message.
> + *
> + * @param len_params
> + *   The len_params argument is the length of the customized message.
> + *
> + * @param fds
> + *   The fds argument is an array of fds sent with sendmsg.
> + *
> + * @param fds_num
> + *   The fds_num argument is number of fds to be sent with sendmsg.
> + *
> + * @return
> + *  - (>=0) on success.
> + *  - (<0) on failure.
> + */
> +int
> +rte_eal_mp_sendmsg(const char *action_name, const void *params,
> +		   int len_params, int fds[], int fds_num);
> +
> +/**
>   * Usage function typedef used by the application usage function.
>   *
>   * Use this function typedef to define and call rte_set_applcation_usage_hook()
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 48f12f4..4b491b9 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -873,6 +873,12 @@ rte_eal_init(int argc, char **argv)
> 
>  	eal_check_mem_on_local_socket();
> 
> +	if (rte_eal_mp_channel_init() < 0) {
> +		rte_eal_init_alert("failed to init mp channel\n");
> +		rte_errno = EFAULT;
> +		return -1;
> +	}
> +
>  	if (eal_plugins_init() < 0)
>  		rte_eal_init_alert("Cannot init plugins\n");
> 
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 8c08b8d..2e1d0e5 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -243,3 +243,11 @@ EXPERIMENTAL {
>  	rte_service_start_with_defaults;
> 
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_eal_primary_secondary_add_action;
> +	rte_eal_primary_secondary_del_action;
> +	rte_eal_primary_secondary_sendmsg;
> +} DPDK_17.11;
> --
> 2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-09-28 15:01     ` Ananyev, Konstantin
@ 2017-09-28 15:29       ` Burakov, Anatoly
  2017-09-29  1:03         ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Burakov, Anatoly @ 2017-09-28 15:29 UTC (permalink / raw)
  To: dev

On 28-Sep-17 4:01 PM, Ananyev, Konstantin wrote:
> Hi Jianfeng,
> 
> 
>> -----Original Message-----
>> From: Tan, Jianfeng
>> Sent: Thursday, September 28, 2017 2:56 PM
>> To: dev@dpdk.org
>> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
>> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net; yliu@fridaylinux.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com;
>> Yigit, Ferruh <ferruh.yigit@intel.com>; Tan, Jianfeng <jianfeng.tan@intel.com>
>> Subject: [PATCH v2 07/12] eal: add channel for primary/secondary communication
>>
>> Previouly, there is only one way for primary/secondary to exchange
>> messages, that is, primary process writes info into some predefind
>> file, and secondary process reads info out. That cannot address
>> the requirements:
>>    a. Secondary wants to send info to primary, for example, secondary
>>       would like to send request (about some specific vdev to primary).
>>    b. Sending info at any time, instead of just initialization time.
>>    c. Share FDs with the other side, for vdev like vhost, related FDs
>>       (memory region, kick) should be shared.
>>
>> This patch proposes to create a communication channel, as an unix
>> socket connection, for above requirements. Primary will listen on
>> the unix socket; secondary will connect this socket to talk.
>>
>> Three new APIs are added:
>>
>>    1. rte_eal_mp_action_register is used to register an action,
>>       indexed by a string; if the calling component wants to
>>       response the messages from the corresponding component in
>>       its primary process or secondary processes.
>>    2. rte_eal_mp_action_unregister is used to unregister the action
>>       if the calling component does not want to response the messages.
>>    3. rte_eal_mp_sendmsg is used to send a message.
> 
> I think we already have similar channel in librte_pdump().
> Also it seems like eal_vfio also has it's own socket to communicate between mp/sp.
> Could we probably make it generic - so same code (and socket) be used by all such  places.
> Konstantin
> 

Agreed, however looking at this, it's already a generic-enough solution, 
and other places could be fixed to use this in later releases. That 
said, i believe this particular part of the patchset should go in as a 
separate patchset and more design consideration and input from others.

-- 
Thanks,
Anatoly

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-09-28 15:29       ` Burakov, Anatoly
@ 2017-09-29  1:03         ` Tan, Jianfeng
  2017-09-29 10:00           ` Burakov, Anatoly
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-29  1:03 UTC (permalink / raw)
  To: Burakov, Anatoly, dev
  Cc: Ananyev, Konstantin, Richardson, Bruce, Pattan, Reshma, viktorin

+ Reshma and Jan.

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Burakov, Anatoly
> Sent: Thursday, September 28, 2017 11:30 PM
> To: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 07/12] eal: add channel for
> primary/secondary communication
> 
> On 28-Sep-17 4:01 PM, Ananyev, Konstantin wrote:
> > Hi Jianfeng,
> >
> >
> >> -----Original Message-----
> >> From: Tan, Jianfeng
> >> Sent: Thursday, September 28, 2017 2:56 PM
> >> To: dev@dpdk.org
> >> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev,
> Konstantin <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
> >> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com;
> >> Yigit, Ferruh <ferruh.yigit@intel.com>; Tan, Jianfeng
> <jianfeng.tan@intel.com>
> >> Subject: [PATCH v2 07/12] eal: add channel for primary/secondary
> communication
> >>
> >> Previouly, there is only one way for primary/secondary to exchange
> >> messages, that is, primary process writes info into some predefind
> >> file, and secondary process reads info out. That cannot address
> >> the requirements:
> >>    a. Secondary wants to send info to primary, for example, secondary
> >>       would like to send request (about some specific vdev to primary).
> >>    b. Sending info at any time, instead of just initialization time.
> >>    c. Share FDs with the other side, for vdev like vhost, related FDs
> >>       (memory region, kick) should be shared.
> >>
> >> This patch proposes to create a communication channel, as an unix
> >> socket connection, for above requirements. Primary will listen on
> >> the unix socket; secondary will connect this socket to talk.
> >>
> >> Three new APIs are added:
> >>
> >>    1. rte_eal_mp_action_register is used to register an action,
> >>       indexed by a string; if the calling component wants to
> >>       response the messages from the corresponding component in
> >>       its primary process or secondary processes.
> >>    2. rte_eal_mp_action_unregister is used to unregister the action
> >>       if the calling component does not want to response the messages.
> >>    3. rte_eal_mp_sendmsg is used to send a message.
> >
> > I think we already have similar channel in librte_pdump().
> > Also it seems like eal_vfio also has it's own socket to communicate
> between mp/sp.
> > Could we probably make it generic - so same code (and socket) be used by
> all such  places.
> > Konstantin
> >
> 
> Agreed, however looking at this, it's already a generic-enough solution,
> and other places could be fixed to use this in later releases.

Yes, to provide a generic communication way, instead of one channel for each subsystem, is the goal of this patch.

Reshma and Jan, can I ask comment from you to have a look if the way of this patch is generic enough to cover pdump and vfio-sync's requirement?

Possible limitation of this patch (so far) is that it only provides an async way for request/response, do we need synchronous way?

> That said, i believe this particular part of the patchset should go in as a
> separate patchset and more design consideration and input from others.

OK, let's collect more info here, and then take out this patch out as a separate patch.

Thanks,
Jianfeng


^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-09-28 13:50     ` Tan, Jianfeng
@ 2017-09-29  1:24       ` Yuanhan Liu
  2017-09-29 10:09         ` Burakov, Anatoly
  0 siblings, 1 reply; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-29  1:24 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: dev, Richardson, Bruce, Ananyev, Konstantin, De Lara Guarch,
	Pablo, thomas, maxime.coquelin, mtetsuyah, Yigit, Ferruh

On Thu, Sep 28, 2017 at 01:50:20PM +0000, Tan, Jianfeng wrote:
> > > +int
> > > +rte_eal_primary_secondary_add_action(const char *action_name,
> > > +				     rte_eal_primary_secondary_t action)
> > > +{
> > > +	struct action_entry *entry = malloc(sizeof(struct action_entry));
> > > +
> > > +	if (entry == NULL)
> > > +		return -ENOMEM;
> > > +
> > > +	strncpy(entry->action_name, action_name,
> > MAX_ACTION_NAME_LEN);
> > > +	entry->action = action;
> > > +	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
> > 
> > Since you intended to support "one primary process and multiple secondary
> > process", here we need a lock to protect the list.
> 
> Only one thread of each process (either primary or secondary) does the register. So I wonder we don't have to add lock? Of course, no harm to add a lock.

Right, I was wrong. I was thinking secondary processes could start at the
same time, that we need a lock here. But as you said, the list is process
specific: each process has it's own copy. No locked is needed then.

> > 
> > Another wonder is do we really need that, I mean 1:N model?
> 
> I'm open to suggestions. IMO, not much extra code for 1:N model than 1:1 model. So not necessary to restrict that.

Fair enough. I was just wondering; I have no objection though.

> > > +/** Path of primary/secondary communication unix socket file. */
> > > +#define PRIMARY_SECONDARY_UNIX_PATH_FMT "%s/.%s_unix"
> > > +static inline const char *
> > > +eal_primary_secondary_unix_path(void)
> > > +{
> > > +	static char buffer[PATH_MAX]; /* static so auto-zeroed */
> > > +	const char *directory = default_config_dir;
> > > +	const char *home_dir = getenv("HOME");
> > 
> > It's not a good practice to generate such file at HOME dir. User would
> > be surprised to find it at HOME dir. In the worst case, user might delete
> > it.
> 
> This way is the legacy way in DPDK, for example the config path. So I think we should fix that in another patch.

Yes, I think so.

	--yliu
> 
> > 
> > The more common way is to put it to tmp dir, like "/tmp".
> 
> Thanks,
> Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-28 13:55   ` [PATCH v2 12/12] net/vhost: support to run in the " Jianfeng Tan
@ 2017-09-29  8:28     ` Yuanhan Liu
  2017-09-30  4:03       ` Tan, Jianfeng
  2017-09-30  8:23     ` Yuanhan Liu
  1 sibling, 1 reply; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-29  8:28 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit

On Thu, Sep 28, 2017 at 01:55:59PM +0000, Jianfeng Tan wrote:
>  static int
> +share_device(int vid)
> +{
> +	uint32_t i, vring_num;
> +	int len;
> +	int fds[8];
> +	struct rte_vhost_memory *mem;
> +	struct vhost_params *params;
> +	struct rte_vhost_vring vring;
> +
> +	/* share mem table */
> +	if (rte_vhost_get_mem_table(vid, &mem) < 0) {
> +		RTE_LOG(ERR, PMD, "Failed to get mem table\n");
> +		return 0;
> +	}
> +	for (i = 0; i < mem->nregions; ++i)
> +		fds[i] = mem->regions[i].fd;
> +
> +	len = sizeof(struct rte_vhost_mem_region) * mem->nregions;
> +	params = malloc(sizeof(*params) + len);
> +	if (params == NULL) {
> +		RTE_LOG(ERR, PMD, "Failed to allocate memory\n");
> +		return -1;
> +	}
> +
> +	params->type = VHOST_MSG_TYPE_REGIONS;
> +	params->vid = vid;
> +	memcpy(params->regions, mem->regions, len);
> +
> +	if (rte_eal_mp_sendmsg("vhost pmd", params, sizeof(*params) + len,

To me, it's not a good idea to identify an object by a string. The common
practice is to use a handler, which could either be a struct or a nubmer.

> +			       fds, mem->nregions) < 0) {
> +		RTE_LOG(ERR, PMD, "Failed to share mem table\n");
> +		free(params);
> +		return -1;
> +	}
> +
> +	/* share callfd and kickfd */
> +	params->type = VHOST_MSG_TYPE_SET_FDS;
> +	vring_num = rte_vhost_get_vring_num(vid);
> +	for (i = 0; i < vring_num; i++) {
> +		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {

If you save the fds here, you don't have to get it every time when there
is a new secondary process attached. Then as I have suggested firstly,
you don't have to introduce callfd_pri in the vhost lib.

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-09-29  1:03         ` Tan, Jianfeng
@ 2017-09-29 10:00           ` Burakov, Anatoly
  2017-09-30  4:07             ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Burakov, Anatoly @ 2017-09-29 10:00 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: Ananyev, Konstantin, Richardson, Bruce, Pattan, Reshma, viktorin

On 29-Sep-17 2:03 AM, Tan, Jianfeng wrote:
> + Reshma and Jan.
> 
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Burakov, Anatoly
>> Sent: Thursday, September 28, 2017 11:30 PM
>> To: dev@dpdk.org
>> Subject: Re: [dpdk-dev] [PATCH v2 07/12] eal: add channel for
>> primary/secondary communication
>>
>> On 28-Sep-17 4:01 PM, Ananyev, Konstantin wrote:
>>> Hi Jianfeng,
>>>
>>>
>>>> -----Original Message-----
>>>> From: Tan, Jianfeng
>>>> Sent: Thursday, September 28, 2017 2:56 PM
>>>> To: dev@dpdk.org
>>>> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev,
>> Konstantin <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
>>>> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
>> yliu@fridaylinux.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com;
>>>> Yigit, Ferruh <ferruh.yigit@intel.com>; Tan, Jianfeng
>> <jianfeng.tan@intel.com>
>>>> Subject: [PATCH v2 07/12] eal: add channel for primary/secondary
>> communication
>>>>
>>>> Previouly, there is only one way for primary/secondary to exchange
>>>> messages, that is, primary process writes info into some predefind
>>>> file, and secondary process reads info out. That cannot address
>>>> the requirements:
>>>>     a. Secondary wants to send info to primary, for example, secondary
>>>>        would like to send request (about some specific vdev to primary).
>>>>     b. Sending info at any time, instead of just initialization time.
>>>>     c. Share FDs with the other side, for vdev like vhost, related FDs
>>>>        (memory region, kick) should be shared.
>>>>
>>>> This patch proposes to create a communication channel, as an unix
>>>> socket connection, for above requirements. Primary will listen on
>>>> the unix socket; secondary will connect this socket to talk.
>>>>
>>>> Three new APIs are added:
>>>>
>>>>     1. rte_eal_mp_action_register is used to register an action,
>>>>        indexed by a string; if the calling component wants to
>>>>        response the messages from the corresponding component in
>>>>        its primary process or secondary processes.
>>>>     2. rte_eal_mp_action_unregister is used to unregister the action
>>>>        if the calling component does not want to response the messages.
>>>>     3. rte_eal_mp_sendmsg is used to send a message.
>>>
>>> I think we already have similar channel in librte_pdump().
>>> Also it seems like eal_vfio also has it's own socket to communicate
>> between mp/sp.
>>> Could we probably make it generic - so same code (and socket) be used by
>> all such  places.
>>> Konstantin
>>>
>>
>> Agreed, however looking at this, it's already a generic-enough solution,
>> and other places could be fixed to use this in later releases.
> 
> Yes, to provide a generic communication way, instead of one channel for each subsystem, is the goal of this patch.
> 
> Reshma and Jan, can I ask comment from you to have a look if the way of this patch is generic enough to cover pdump and vfio-sync's requirement?
> 
> Possible limitation of this patch (so far) is that it only provides an async way for request/response, do we need synchronous way?
> 
>> That said, i believe this particular part of the patchset should go in as a
>> separate patchset and more design consideration and input from others.
> 
> OK, let's collect more info here, and then take out this patch out as a separate patch.
> 
> Thanks,
> Jianfeng
> 
Hi Jianfeng,

Yes, i believe VFIO does need synchronous communcation, because it 
relies on passing fd's from primary to secondary, on request. It could 
be rewritten to be asynchronous, similarly to how you handle vdevs here, 
but as it stands, it assumes synchronous communication.

-- 
Thanks,
Anatoly

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-09-29  1:24       ` Yuanhan Liu
@ 2017-09-29 10:09         ` Burakov, Anatoly
  2017-09-29 10:25           ` Yuanhan Liu
  0 siblings, 1 reply; 158+ messages in thread
From: Burakov, Anatoly @ 2017-09-29 10:09 UTC (permalink / raw)
  To: dev

On 29-Sep-17 2:24 AM, Yuanhan Liu wrote:
> On Thu, Sep 28, 2017 at 01:50:20PM +0000, Tan, Jianfeng wrote:
>>>> +/** Path of primary/secondary communication unix socket file. */
>>>> +#define PRIMARY_SECONDARY_UNIX_PATH_FMT "%s/.%s_unix"
>>>> +static inline const char *
>>>> +eal_primary_secondary_unix_path(void)
>>>> +{
>>>> +	static char buffer[PATH_MAX]; /* static so auto-zeroed */
>>>> +	const char *directory = default_config_dir;
>>>> +	const char *home_dir = getenv("HOME");
>>>
>>> It's not a good practice to generate such file at HOME dir. User would
>>> be surprised to find it at HOME dir. In the worst case, user might delete
>>> it.
>>
>> This way is the legacy way in DPDK, for example the config path. So I think we should fix that in another patch.
> 
> Yes, I think so.
> 
> 	--yliu
>>
>>>
>>> The more common way is to put it to tmp dir, like "/tmp".
>>
>> Thanks,
>> Jianfeng
> 

The way VFIO does it is, if we have permissions, we put the socket file 
in /var/run (which i also think is a better place for a socket than 
/tmp). If we don't, we fall back to HOME.

-- 
Thanks,
Anatoly

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 06/12] eal: add channel for primary/secondary communication
  2017-09-29 10:09         ` Burakov, Anatoly
@ 2017-09-29 10:25           ` Yuanhan Liu
  0 siblings, 0 replies; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-29 10:25 UTC (permalink / raw)
  To: Burakov, Anatoly; +Cc: dev

On Fri, Sep 29, 2017 at 11:09:23AM +0100, Burakov, Anatoly wrote:
> On 29-Sep-17 2:24 AM, Yuanhan Liu wrote:
> >On Thu, Sep 28, 2017 at 01:50:20PM +0000, Tan, Jianfeng wrote:
> >>>>+/** Path of primary/secondary communication unix socket file. */
> >>>>+#define PRIMARY_SECONDARY_UNIX_PATH_FMT "%s/.%s_unix"
> >>>>+static inline const char *
> >>>>+eal_primary_secondary_unix_path(void)
> >>>>+{
> >>>>+	static char buffer[PATH_MAX]; /* static so auto-zeroed */
> >>>>+	const char *directory = default_config_dir;
> >>>>+	const char *home_dir = getenv("HOME");
> >>>
> >>>It's not a good practice to generate such file at HOME dir. User would
> >>>be surprised to find it at HOME dir. In the worst case, user might delete
> >>>it.
> >>
> >>This way is the legacy way in DPDK, for example the config path. So I think we should fix that in another patch.
> >
> >Yes, I think so.
> >
> >	--yliu
> >>
> >>>
> >>>The more common way is to put it to tmp dir, like "/tmp".
> >>
> >>Thanks,
> >>Jianfeng
> >
> 
> The way VFIO does it is, if we have permissions, we put the socket file in
> /var/run (which i also think is a better place for a socket than /tmp). If
> we don't, we fall back to HOME.

I have no objection with /var/run. But HOME, no.

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-29  8:28     ` Yuanhan Liu
@ 2017-09-30  4:03       ` Tan, Jianfeng
  2017-09-30  8:16         ` Yuanhan Liu
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-30  4:03 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit

Hi Yuanhan,


On 9/29/2017 4:28 PM, Yuanhan Liu wrote:
> On Thu, Sep 28, 2017 at 01:55:59PM +0000, Jianfeng Tan wrote:
>>   static int
>> +share_device(int vid)
>> +{
>> +	uint32_t i, vring_num;
>> +	int len;
>> +	int fds[8];
>> +	struct rte_vhost_memory *mem;
>> +	struct vhost_params *params;
>> +	struct rte_vhost_vring vring;
>> +
>> +	/* share mem table */
>> +	if (rte_vhost_get_mem_table(vid, &mem) < 0) {
>> +		RTE_LOG(ERR, PMD, "Failed to get mem table\n");
>> +		return 0;
>> +	}
>> +	for (i = 0; i < mem->nregions; ++i)
>> +		fds[i] = mem->regions[i].fd;
>> +
>> +	len = sizeof(struct rte_vhost_mem_region) * mem->nregions;
>> +	params = malloc(sizeof(*params) + len);
>> +	if (params == NULL) {
>> +		RTE_LOG(ERR, PMD, "Failed to allocate memory\n");
>> +		return -1;
>> +	}
>> +
>> +	params->type = VHOST_MSG_TYPE_REGIONS;
>> +	params->vid = vid;
>> +	memcpy(params->regions, mem->regions, len);
>> +
>> +	if (rte_eal_mp_sendmsg("vhost pmd", params, sizeof(*params) + len,
> To me, it's not a good idea to identify an object by a string. The common
> practice is to use a handler, which could either be a struct or a nubmer.

My point is that if we choose the way you suggested, we need somewhere 
to maintain them. For example, every time we need register a new action, 
we need to update that file to add a new entry (number).

In current way, the duplicated register with the same name will fail, 
developers is responsible to check that.

>
>> +			       fds, mem->nregions) < 0) {
>> +		RTE_LOG(ERR, PMD, "Failed to share mem table\n");
>> +		free(params);
>> +		return -1;
>> +	}
>> +
>> +	/* share callfd and kickfd */
>> +	params->type = VHOST_MSG_TYPE_SET_FDS;
>> +	vring_num = rte_vhost_get_vring_num(vid);
>> +	for (i = 0; i < vring_num; i++) {
>> +		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
> If you save the fds here, you don't have to get it every time when there
> is a new secondary process attached. Then as I have suggested firstly,
> you don't have to introduce callfd_pri in the vhost lib.

If we don't introduce callfd_pri, when we do virtqueue cleanup (or 
similar operations) in vhost lib, it will wrongly close fds belonging to 
secondary process.

You remind me that, instead of introduce callfd_pri, we can introduce 
callfd_effective, to reduce the modification lines.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-09-29 10:00           ` Burakov, Anatoly
@ 2017-09-30  4:07             ` Tan, Jianfeng
  2017-10-02 10:08               ` Burakov, Anatoly
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-30  4:07 UTC (permalink / raw)
  To: Burakov, Anatoly, dev
  Cc: Ananyev, Konstantin, Richardson, Bruce, Pattan, Reshma, viktorin



On 9/29/2017 6:00 PM, Burakov, Anatoly wrote:
> On 29-Sep-17 2:03 AM, Tan, Jianfeng wrote:
>> + Reshma and Jan.
>>
>>> -----Original Message-----
>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Burakov, Anatoly
>>> Sent: Thursday, September 28, 2017 11:30 PM
>>> To: dev@dpdk.org
>>> Subject: Re: [dpdk-dev] [PATCH v2 07/12] eal: add channel for
>>> primary/secondary communication
>>>
>>> On 28-Sep-17 4:01 PM, Ananyev, Konstantin wrote:
>>>> Hi Jianfeng,
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Tan, Jianfeng
>>>>> Sent: Thursday, September 28, 2017 2:56 PM
>>>>> To: dev@dpdk.org
>>>>> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev,
>>> Konstantin <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
>>>>> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
>>> yliu@fridaylinux.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com;
>>>>> Yigit, Ferruh <ferruh.yigit@intel.com>; Tan, Jianfeng
>>> <jianfeng.tan@intel.com>
>>>>> Subject: [PATCH v2 07/12] eal: add channel for primary/secondary
>>> communication
>>>>>
>>>>> Previouly, there is only one way for primary/secondary to exchange
>>>>> messages, that is, primary process writes info into some predefind
>>>>> file, and secondary process reads info out. That cannot address
>>>>> the requirements:
>>>>>     a. Secondary wants to send info to primary, for example, 
>>>>> secondary
>>>>>        would like to send request (about some specific vdev to 
>>>>> primary).
>>>>>     b. Sending info at any time, instead of just initialization time.
>>>>>     c. Share FDs with the other side, for vdev like vhost, related 
>>>>> FDs
>>>>>        (memory region, kick) should be shared.
>>>>>
>>>>> This patch proposes to create a communication channel, as an unix
>>>>> socket connection, for above requirements. Primary will listen on
>>>>> the unix socket; secondary will connect this socket to talk.
>>>>>
>>>>> Three new APIs are added:
>>>>>
>>>>>     1. rte_eal_mp_action_register is used to register an action,
>>>>>        indexed by a string; if the calling component wants to
>>>>>        response the messages from the corresponding component in
>>>>>        its primary process or secondary processes.
>>>>>     2. rte_eal_mp_action_unregister is used to unregister the action
>>>>>        if the calling component does not want to response the 
>>>>> messages.
>>>>>     3. rte_eal_mp_sendmsg is used to send a message.
>>>>
>>>> I think we already have similar channel in librte_pdump().
>>>> Also it seems like eal_vfio also has it's own socket to communicate
>>> between mp/sp.
>>>> Could we probably make it generic - so same code (and socket) be 
>>>> used by
>>> all such  places.
>>>> Konstantin
>>>>
>>>
>>> Agreed, however looking at this, it's already a generic-enough 
>>> solution,
>>> and other places could be fixed to use this in later releases.
>>
>> Yes, to provide a generic communication way, instead of one channel 
>> for each subsystem, is the goal of this patch.
>>
>> Reshma and Jan, can I ask comment from you to have a look if the way 
>> of this patch is generic enough to cover pdump and vfio-sync's 
>> requirement?
>>
>> Possible limitation of this patch (so far) is that it only provides 
>> an async way for request/response, do we need synchronous way?
>>
>>> That said, i believe this particular part of the patchset should go 
>>> in as a
>>> separate patchset and more design consideration and input from others.
>>
>> OK, let's collect more info here, and then take out this patch out as 
>> a separate patch.
>>
>> Thanks,
>> Jianfeng
>>
> Hi Jianfeng,
>
> Yes, i believe VFIO does need synchronous communcation, because it 
> relies on passing fd's from primary to secondary, on request. It could 
> be rewritten to be asynchronous, similarly to how you handle vdevs 
> here, but as it stands, it assumes synchronous communication.
>

Good to know, thanks Anatoly. Even it can be rewritten to do in asyn 
way, do we need to propose sync way now?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-30  4:03       ` Tan, Jianfeng
@ 2017-09-30  8:16         ` Yuanhan Liu
  2017-09-30 10:06           ` Tan, Jianfeng
  2017-09-30 11:49           ` Yuanhan Liu
  0 siblings, 2 replies; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-30  8:16 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit

On Sat, Sep 30, 2017 at 12:03:33PM +0800, Tan, Jianfeng wrote:
> >>+	if (rte_eal_mp_sendmsg("vhost pmd", params, sizeof(*params) + len,
> >To me, it's not a good idea to identify an object by a string. The common
> >practice is to use a handler, which could either be a struct or a nubmer.
> 
> My point is that if we choose the way you suggested, we need somewhere to
> maintain them. For example, every time we need register a new action, we
> need to update that file to add a new entry (number).

Not really. You could let the register function to return a struct, in
which there is a name field.

Anyway, I think it's not a big deal to turn it to struct, judging that
it may only contain one field only: the name. But at least, you should
not type the same string everywhere. Use macro instead.

> In current way, the duplicated register with the same name will fail,
> developers is responsible to check that.
> 
> >
> >>+			       fds, mem->nregions) < 0) {
> >>+		RTE_LOG(ERR, PMD, "Failed to share mem table\n");
> >>+		free(params);
> >>+		return -1;
> >>+	}
> >>+
> >>+	/* share callfd and kickfd */
> >>+	params->type = VHOST_MSG_TYPE_SET_FDS;
> >>+	vring_num = rte_vhost_get_vring_num(vid);
> >>+	for (i = 0; i < vring_num; i++) {
> >>+		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
> >If you save the fds here, you don't have to get it every time when there
> >is a new secondary process attached. Then as I have suggested firstly,
> >you don't have to introduce callfd_pri in the vhost lib.
> 
> If we don't introduce callfd_pri, when we do virtqueue cleanup (or similar
> operations) in vhost lib, it will wrongly close fds belonging to secondary
> process.
> 
> You remind me that, instead of introduce callfd_pri, we can introduce
> callfd_effective, to reduce the modification lines.

It's not about how many lines are modified. You were adding "effective"
fds, which is a semantic change. It makes the logic a bit more complex.
What's worse, it even doesn't resolve the issue completely.

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-09-28  8:09             ` Tan, Jianfeng
@ 2017-09-30  8:18               ` Yuanhan Liu
  2017-09-30 10:50                 ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-30  8:18 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev, maxime.coquelin, mtetsuyah

On Thu, Sep 28, 2017 at 08:09:38AM +0000, Tan, Jianfeng wrote:
> > Actually, the key (and typical) issue of multi-process here is the fds are
> > process specific, while they are stored in the shared memory. That means
> > only one will take effect eventually. Worse, the old ones are lost.
> > 
> > So, I think to make it right in this case, you should move the fds from
> > the shared memory and store them in the memory of the corresponding
> > process.
> > If that's done, all processes could have its own valid fds, then every
> > process could do the kick (if that's really necessary).
> > 
> > You could check following commit for more info.
> > 553f45932fb7 ("net/virtio: store PCI operators pointer locally")
> 
> Have referred to the above solution, but seems not feasible for this case since there are too many queues. For example, if we define an array like this:
>   int vhost_callfds[index_by_vid][index_by_queue_id];
> The size would be MAX_VHOST_DEVICE * VHOST_MAX_VRING * 8Byte = 2Mbyte.

I think you can do it in a dynamic way, like what we did for vhost_dev
allocation?

	--yliu
> 
> Instead, can we propose something like process_id to index array located at shared memory?
> 
> Thanks,
> Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-28 13:55   ` [PATCH v2 12/12] net/vhost: support to run in the " Jianfeng Tan
  2017-09-29  8:28     ` Yuanhan Liu
@ 2017-09-30  8:23     ` Yuanhan Liu
  2017-09-30 10:53       ` Tan, Jianfeng
  2017-09-30 11:34       ` Yuanhan Liu
  1 sibling, 2 replies; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-30  8:23 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit

On Thu, Sep 28, 2017 at 01:55:59PM +0000, Jianfeng Tan wrote:
> +static int
>  new_device(int vid)
>  {
>  	struct rte_eth_dev *eth_dev;
> @@ -610,6 +685,8 @@ new_device(int vid)
>  	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
>  				      NULL, NULL);
>  
> +	share_device(vid);
> +

Another question is, have you considered/tested the case when the VM
changes the qeueue number later?

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-30  8:16         ` Yuanhan Liu
@ 2017-09-30 10:06           ` Tan, Jianfeng
  2017-09-30 11:49           ` Yuanhan Liu
  1 sibling, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-30 10:06 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit



On 9/30/2017 4:16 PM, Yuanhan Liu wrote:
> On Sat, Sep 30, 2017 at 12:03:33PM +0800, Tan, Jianfeng wrote:
>>>> +	if (rte_eal_mp_sendmsg("vhost pmd", params, sizeof(*params) + len,
>>> To me, it's not a good idea to identify an object by a string. The common
>>> practice is to use a handler, which could either be a struct or a nubmer.
>> My point is that if we choose the way you suggested, we need somewhere to
>> maintain them. For example, every time we need register a new action, we
>> need to update that file to add a new entry (number).
> Not really. You could let the register function to return a struct, in
> which there is a name field.
>
> Anyway, I think it's not a big deal to turn it to struct, judging that
> it may only contain one field only: the name. But at least, you should
> not type the same string everywhere. Use macro instead.

Agreed. Will fix that.

>
>> In current way, the duplicated register with the same name will fail,
>> developers is responsible to check that.
>>
>>>> +			       fds, mem->nregions) < 0) {
>>>> +		RTE_LOG(ERR, PMD, "Failed to share mem table\n");
>>>> +		free(params);
>>>> +		return -1;
>>>> +	}
>>>> +
>>>> +	/* share callfd and kickfd */
>>>> +	params->type = VHOST_MSG_TYPE_SET_FDS;
>>>> +	vring_num = rte_vhost_get_vring_num(vid);
>>>> +	for (i = 0; i < vring_num; i++) {
>>>> +		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
>>> If you save the fds here, you don't have to get it every time when there
>>> is a new secondary process attached. Then as I have suggested firstly,
>>> you don't have to introduce callfd_pri in the vhost lib.
>> If we don't introduce callfd_pri, when we do virtqueue cleanup (or similar
>> operations) in vhost lib, it will wrongly close fds belonging to secondary
>> process.
>>
>> You remind me that, instead of introduce callfd_pri, we can introduce
>> callfd_effective, to reduce the modification lines.
> It's not about how many lines are modified. You were adding "effective"
> fds, which is a semantic change. It makes the logic a bit more complex.
> What's worse, it even doesn't resolve the issue completely.

Yes, it still has limitation. Just wonder if possible to move event fd 
write out of vhost lib.

Thanks,
Jianfeng

>
> 	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH 10/12] vhost: support to kick in secondary process
  2017-09-30  8:18               ` Yuanhan Liu
@ 2017-09-30 10:50                 ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-30 10:50 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, maxime.coquelin, mtetsuyah



On 9/30/2017 4:18 PM, Yuanhan Liu wrote:
> On Thu, Sep 28, 2017 at 08:09:38AM +0000, Tan, Jianfeng wrote:
>>> Actually, the key (and typical) issue of multi-process here is the fds are
>>> process specific, while they are stored in the shared memory. That means
>>> only one will take effect eventually. Worse, the old ones are lost.
>>>
>>> So, I think to make it right in this case, you should move the fds from
>>> the shared memory and store them in the memory of the corresponding
>>> process.
>>> If that's done, all processes could have its own valid fds, then every
>>> process could do the kick (if that's really necessary).
>>>
>>> You could check following commit for more info.
>>> 553f45932fb7 ("net/virtio: store PCI operators pointer locally")
>> Have referred to the above solution, but seems not feasible for this case since there are too many queues. For example, if we define an array like this:
>>    int vhost_callfds[index_by_vid][index_by_queue_id];
>> The size would be MAX_VHOST_DEVICE * VHOST_MAX_VRING * 8Byte = 2Mbyte.
> I think you can do it in a dynamic way, like what we did for vhost_dev
> allocation?

I'll give it a try, thanks!

Thanks,
Jianfeng


>
> 	--yliu
>> Instead, can we propose something like process_id to index array located at shared memory?
>>
>> Thanks,
>> Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-30  8:23     ` Yuanhan Liu
@ 2017-09-30 10:53       ` Tan, Jianfeng
  2017-09-30 11:34       ` Yuanhan Liu
  1 sibling, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-09-30 10:53 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit



On 9/30/2017 4:23 PM, Yuanhan Liu wrote:
> On Thu, Sep 28, 2017 at 01:55:59PM +0000, Jianfeng Tan wrote:
>> +static int
>>   new_device(int vid)
>>   {
>>   	struct rte_eth_dev *eth_dev;
>> @@ -610,6 +685,8 @@ new_device(int vid)
>>   	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
>>   				      NULL, NULL);
>>   
>> +	share_device(vid);
>> +
> Another question is, have you considered/tested the case when the VM
> changes the qeueue number later?

Yes, that is a covered test case, we use ethtool to increase the 
combined queue number; see cover letter for detail.

Thanks,
Jianfeng

> 	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-30  8:23     ` Yuanhan Liu
  2017-09-30 10:53       ` Tan, Jianfeng
@ 2017-09-30 11:34       ` Yuanhan Liu
  2017-10-01 23:46         ` Tan, Jianfeng
  1 sibling, 1 reply; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-30 11:34 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit


On Thu, Sep 30, 2017 at 12:53:00PM +0000, Jianfeng Tan wrote:
>On 9/30/2017 4:23 PM, Yuanhan Liu wrote:
> > On Thu, Sep 28, 2017 at 01:55:59PM +0000, Jianfeng Tan wrote:
> >> +static int
> >>   new_device(int vid)
> >>   {
> >>   	struct rte_eth_dev *eth_dev;
> >> @@ -610,6 +685,8 @@ new_device(int vid)
> >>   	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
> >>   				      NULL, NULL);
> >>   
> >> +	share_device(vid);
> >> +
> > Another question is, have you considered/tested the case when the VM
> > changes the qeueue number later?
> 
> Yes, that is a covered test case, we use ethtool to increase the 
> combined queue number; see cover letter for detail.

Sorry I missed that!

However, I'm not quite sure I understood you:

    Step 5: enable multi queue in VM1 and VM2.
      $ ethtool -L ethX combined 2
    
    Note in this test case, only queue 1, i.e., secondary process can process
    packets. To use queue 1, basically, we can run command like:
      $ taskset -c 1 <commands>

Do you mean the secondary can't rx/tx pkts from/to the 2nd queue?
And you are asking the user to add "taskset -c 1" each time he
wants to run a command inside the VM?

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-30  8:16         ` Yuanhan Liu
  2017-09-30 10:06           ` Tan, Jianfeng
@ 2017-09-30 11:49           ` Yuanhan Liu
  2017-10-01 23:48             ` Tan, Jianfeng
  1 sibling, 1 reply; 158+ messages in thread
From: Yuanhan Liu @ 2017-09-30 11:49 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit

On Sat, Sep 30, 2017 at 12:06:44PM 0000, Jianfeng Tan wrote:
> >>>> +	/* share callfd and kickfd */
> >>>> +	params->type = VHOST_MSG_TYPE_SET_FDS;
> >>>> +	vring_num = rte_vhost_get_vring_num(vid);
> >>>> +	for (i = 0; i < vring_num; i++) {
> >>>> +		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
> >>> If you save the fds here, you don't have to get it every time when there
> >>> is a new secondary process attached. Then as I have suggested firstly,
> >>> you don't have to introduce callfd_pri in the vhost lib.
> >> If we don't introduce callfd_pri, when we do virtqueue cleanup (or similar
> >> operations) in vhost lib, it will wrongly close fds belonging to secondary
> >> process.
> >>
> >> You remind me that, instead of introduce callfd_pri, we can introduce
> >> callfd_effective, to reduce the modification lines.
> > It's not about how many lines are modified. You were adding "effective"
> > fds, which is a semantic change. It makes the logic a bit more complex.
> > What's worse, it even doesn't resolve the issue completely.
> 
> Yes, it still has limitation. Just wonder if possible to move event fd 
> write out of vhost lib.

It could be another solution: we have the valid fd and vring_avail
outside the vhost lib. It's just that the callfd write is inside
the vhost lib. If you just take it out (remove it), it breaks some
users who rely on it: it's an API behaviour change.

	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-30 11:34       ` Yuanhan Liu
@ 2017-10-01 23:46         ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-01 23:46 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit



On 9/30/2017 7:34 PM, Yuanhan Liu wrote:
> On Thu, Sep 30, 2017 at 12:53:00PM +0000, Jianfeng Tan wrote:
>> On 9/30/2017 4:23 PM, Yuanhan Liu wrote:
>>> On Thu, Sep 28, 2017 at 01:55:59PM +0000, Jianfeng Tan wrote:
>>>> +static int
>>>>    new_device(int vid)
>>>>    {
>>>>    	struct rte_eth_dev *eth_dev;
>>>> @@ -610,6 +685,8 @@ new_device(int vid)
>>>>    	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
>>>>    				      NULL, NULL);
>>>>    
>>>> +	share_device(vid);
>>>> +
>>> Another question is, have you considered/tested the case when the VM
>>> changes the qeueue number later?
>> Yes, that is a covered test case, we use ethtool to increase the
>> combined queue number; see cover letter for detail.
> Sorry I missed that!
>
> However, I'm not quite sure I understood you:
>
>      Step 5: enable multi queue in VM1 and VM2.
>        $ ethtool -L ethX combined 2
>      
>      Note in this test case, only queue 1, i.e., secondary process can process
>      packets. To use queue 1, basically, we can run command like:
>        $ taskset -c 1 <commands>
>
> Do you mean the secondary can't rx/tx pkts from/to the 2nd queue?
> And you are asking the user to add "taskset -c 1" each time he
> wants to run a command inside the VM?

No, the result is because the logic of this example, symmetric_mp, is 
that primary process works on the queue pair 0; and secondary process 
works on queue pair 1. And because of the limitation we mentioned 
earlier, primary process can process the virtqueue but cannot kick the 
queue pair 0 (wrong callfd). But secondary process can work on both 
queue pair 0 and 1 in theory, unfortunately, cannot find an existing 
example to test that.

Thanks,
Jianfeng

>
> 	--yliu

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 12/12] net/vhost: support to run in the secondary process
  2017-09-30 11:49           ` Yuanhan Liu
@ 2017-10-01 23:48             ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-01 23:48 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, bruce.richardson, konstantin.ananyev, pablo.de.lara.guarch,
	thomas, maxime.coquelin, mtetsuyah, ferruh.yigit



On 9/30/2017 7:49 PM, Yuanhan Liu wrote:
> On Sat, Sep 30, 2017 at 12:06:44PM 0000, Jianfeng Tan wrote:
>>>>>> +	/* share callfd and kickfd */
>>>>>> +	params->type = VHOST_MSG_TYPE_SET_FDS;
>>>>>> +	vring_num = rte_vhost_get_vring_num(vid);
>>>>>> +	for (i = 0; i < vring_num; i++) {
>>>>>> +		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
>>>>> If you save the fds here, you don't have to get it every time when there
>>>>> is a new secondary process attached. Then as I have suggested firstly,
>>>>> you don't have to introduce callfd_pri in the vhost lib.
>>>> If we don't introduce callfd_pri, when we do virtqueue cleanup (or similar
>>>> operations) in vhost lib, it will wrongly close fds belonging to secondary
>>>> process.
>>>>
>>>> You remind me that, instead of introduce callfd_pri, we can introduce
>>>> callfd_effective, to reduce the modification lines.
>>> It's not about how many lines are modified. You were adding "effective"
>>> fds, which is a semantic change. It makes the logic a bit more complex.
>>> What's worse, it even doesn't resolve the issue completely.
>> Yes, it still has limitation. Just wonder if possible to move event fd
>> write out of vhost lib.
> It could be another solution: we have the valid fd and vring_avail
> outside the vhost lib. It's just that the callfd write is inside
> the vhost lib. If you just take it out (remove it), it breaks some
> users who rely on it: it's an API behaviour change.

Make sense.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-09-30  4:07             ` Tan, Jianfeng
@ 2017-10-02 10:08               ` Burakov, Anatoly
  0 siblings, 0 replies; 158+ messages in thread
From: Burakov, Anatoly @ 2017-10-02 10:08 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: Ananyev, Konstantin, Richardson, Bruce, Pattan, Reshma, viktorin

On 30-Sep-17 5:07 AM, Tan, Jianfeng wrote:
> 
> 
> On 9/29/2017 6:00 PM, Burakov, Anatoly wrote:
>> On 29-Sep-17 2:03 AM, Tan, Jianfeng wrote:
>>> + Reshma and Jan.
>>>
>>>> -----Original Message-----
>>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Burakov, Anatoly
>>>> Sent: Thursday, September 28, 2017 11:30 PM
>>>> To: dev@dpdk.org
>>>> Subject: Re: [dpdk-dev] [PATCH v2 07/12] eal: add channel for
>>>> primary/secondary communication
>>>>
>>>> On 28-Sep-17 4:01 PM, Ananyev, Konstantin wrote:
>>>>> Hi Jianfeng,
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Tan, Jianfeng
>>>>>> Sent: Thursday, September 28, 2017 2:56 PM
>>>>>> To: dev@dpdk.org
>>>>>> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Ananyev,
>>>> Konstantin <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
>>>>>> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
>>>> yliu@fridaylinux.org; maxime.coquelin@redhat.com; mtetsuyah@gmail.com;
>>>>>> Yigit, Ferruh <ferruh.yigit@intel.com>; Tan, Jianfeng
>>>> <jianfeng.tan@intel.com>
>>>>>> Subject: [PATCH v2 07/12] eal: add channel for primary/secondary
>>>> communication
>>>>>>
>>>>>> Previouly, there is only one way for primary/secondary to exchange
>>>>>> messages, that is, primary process writes info into some predefind
>>>>>> file, and secondary process reads info out. That cannot address
>>>>>> the requirements:
>>>>>>     a. Secondary wants to send info to primary, for example, 
>>>>>> secondary
>>>>>>        would like to send request (about some specific vdev to 
>>>>>> primary).
>>>>>>     b. Sending info at any time, instead of just initialization time.
>>>>>>     c. Share FDs with the other side, for vdev like vhost, related 
>>>>>> FDs
>>>>>>        (memory region, kick) should be shared.
>>>>>>
>>>>>> This patch proposes to create a communication channel, as an unix
>>>>>> socket connection, for above requirements. Primary will listen on
>>>>>> the unix socket; secondary will connect this socket to talk.
>>>>>>
>>>>>> Three new APIs are added:
>>>>>>
>>>>>>     1. rte_eal_mp_action_register is used to register an action,
>>>>>>        indexed by a string; if the calling component wants to
>>>>>>        response the messages from the corresponding component in
>>>>>>        its primary process or secondary processes.
>>>>>>     2. rte_eal_mp_action_unregister is used to unregister the action
>>>>>>        if the calling component does not want to response the 
>>>>>> messages.
>>>>>>     3. rte_eal_mp_sendmsg is used to send a message.
>>>>>
>>>>> I think we already have similar channel in librte_pdump().
>>>>> Also it seems like eal_vfio also has it's own socket to communicate
>>>> between mp/sp.
>>>>> Could we probably make it generic - so same code (and socket) be 
>>>>> used by
>>>> all such  places.
>>>>> Konstantin
>>>>>
>>>>
>>>> Agreed, however looking at this, it's already a generic-enough 
>>>> solution,
>>>> and other places could be fixed to use this in later releases.
>>>
>>> Yes, to provide a generic communication way, instead of one channel 
>>> for each subsystem, is the goal of this patch.
>>>
>>> Reshma and Jan, can I ask comment from you to have a look if the way 
>>> of this patch is generic enough to cover pdump and vfio-sync's 
>>> requirement?
>>>
>>> Possible limitation of this patch (so far) is that it only provides 
>>> an async way for request/response, do we need synchronous way?
>>>
>>>> That said, i believe this particular part of the patchset should go 
>>>> in as a
>>>> separate patchset and more design consideration and input from others.
>>>
>>> OK, let's collect more info here, and then take out this patch out as 
>>> a separate patch.
>>>
>>> Thanks,
>>> Jianfeng
>>>
>> Hi Jianfeng,
>>
>> Yes, i believe VFIO does need synchronous communcation, because it 
>> relies on passing fd's from primary to secondary, on request. It could 
>> be rewritten to be asynchronous, similarly to how you handle vdevs 
>> here, but as it stands, it assumes synchronous communication.
>>
> 
> Good to know, thanks Anatoly. Even it can be rewritten to do in asyn 
> way, do we need to propose sync way now?
> 
> Thanks,
> Jianfeng
> 

I believe that we do, because we can't assume that everything can be 
rewritten to be asynchronous. I'm open to other opinions though :)

-- 
Thanks,
Anatoly

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-09-28 13:55   ` [PATCH v2 07/12] eal: add channel for primary/secondary communication Jianfeng Tan
  2017-09-28 15:01     ` Ananyev, Konstantin
@ 2017-10-05 12:01     ` Jan Blunck
  2017-10-09  1:27       ` Tan, Jianfeng
  1 sibling, 1 reply; 158+ messages in thread
From: Jan Blunck @ 2017-10-05 12:01 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, Bruce Richardson, Ananyev, Konstantin, De Lara Guarch,
	Pablo, Thomas Monjalon, yliu, Maxime Coquelin, Tetsuya Mukawa,
	Ferruh Yigit

On Thu, Sep 28, 2017 at 3:55 PM, Jianfeng Tan <jianfeng.tan@intel.com> wrote:
> Previouly, there is only one way for primary/secondary to exchange
> messages, that is, primary process writes info into some predefind
> file, and secondary process reads info out. That cannot address
> the requirements:
>   a. Secondary wants to send info to primary, for example, secondary
>      would like to send request (about some specific vdev to primary).
>   b. Sending info at any time, instead of just initialization time.
>   c. Share FDs with the other side, for vdev like vhost, related FDs
>      (memory region, kick) should be shared.
>
> This patch proposes to create a communication channel, as an unix
> socket connection, for above requirements. Primary will listen on
> the unix socket; secondary will connect this socket to talk.
>
> Three new APIs are added:
>
>   1. rte_eal_mp_action_register is used to register an action,
>      indexed by a string; if the calling component wants to
>      response the messages from the corresponding component in
>      its primary process or secondary processes.
>   2. rte_eal_mp_action_unregister is used to unregister the action
>      if the calling component does not want to response the messages.
>   3. rte_eal_mp_sendmsg is used to send a message.
>

Sorry, but I fail to see how this is something that should be solved
in the DPDK. This is about application interprocess communication.
>From my point of view this has absolutely nothing to do with the DPDK.

>From my point of view the DPDK should not become another operating
system abstraction library outside of what is absolutely required. We
already dictate way too much (e.g. threading model, config files, ...)
for the users of the DPDK.

Cheers,
Jan


> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   8 +
>  lib/librte_eal/common/eal_common_proc.c         | 498 ++++++++++++++++++++++++
>  lib/librte_eal/common/eal_filesystem.h          |  18 +
>  lib/librte_eal/common/eal_private.h             |  10 +
>  lib/librte_eal/common/include/rte_eal.h         |  68 ++++
>  lib/librte_eal/linuxapp/eal/eal.c               |   6 +
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
>  7 files changed, 616 insertions(+)
>
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index 47a09ea..f895916 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -238,3 +238,11 @@ EXPERIMENTAL {
>         rte_service_start_with_defaults;
>
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +       global:
> +
> +       rte_eal_primary_secondary_add_action;
> +       rte_eal_primary_secondary_del_action;
> +       rte_eal_primary_secondary_sendmsg;
> +} DPDK_17.11;
> diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
> index 60526ca..eb5a502 100644
> --- a/lib/librte_eal/common/eal_common_proc.c
> +++ b/lib/librte_eal/common/eal_common_proc.c
> @@ -33,8 +33,21 @@
>  #include <stdio.h>
>  #include <fcntl.h>
>  #include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <sys/epoll.h>
> +#include <limits.h>
> +#include <unistd.h>
> +#include <sys/un.h>
> +#include <errno.h>
> +#include <pthread.h>
> +
> +#include <rte_log.h>
>  #include <rte_eal.h>
> +#include <rte_lcore.h>
> +#include <rte_common.h>
>
> +#include "eal_private.h"
>  #include "eal_filesystem.h"
>  #include "eal_internal_cfg.h"
>
> @@ -59,3 +72,488 @@ rte_eal_primary_proc_alive(const char *config_file_path)
>
>         return !!ret;
>  }
> +
> +struct action_entry {
> +       TAILQ_ENTRY(action_entry) next;      /**< Next attached action entry */
> +
> +#define MAX_ACTION_NAME_LEN    64
> +       char action_name[MAX_ACTION_NAME_LEN];
> +       rte_eal_mp_t action;
> +};
> +
> +/** Double linked list of actions. */
> +TAILQ_HEAD(action_entry_list, action_entry);
> +
> +static struct action_entry_list action_entry_list =
> +       TAILQ_HEAD_INITIALIZER(action_entry_list);
> +
> +static struct action_entry *
> +find_action_entry_by_name(const char *name)
> +{
> +       int len = strlen(name);
> +       struct action_entry *entry;
> +
> +       TAILQ_FOREACH(entry, &action_entry_list, next) {
> +               if (strncmp(entry->action_name, name, len) == 0)
> +                       break;
> +       }
> +
> +       return entry;
> +}
> +
> +int
> +rte_eal_mp_action_register(const char *action_name, rte_eal_mp_t action)
> +{
> +       struct action_entry *entry = malloc(sizeof(struct action_entry));
> +
> +       if (entry == NULL)
> +               return -ENOMEM;
> +
> +       if (find_action_entry_by_name(action_name) != NULL)
> +               return -EEXIST;
> +
> +       strncpy(entry->action_name, action_name, MAX_ACTION_NAME_LEN);
> +       entry->action = action;
> +       TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
> +       return 0;
> +}
> +
> +void
> +rte_eal_mp_action_unregister(const char *name)
> +{
> +       struct action_entry *entry = find_action_entry_by_name(name);
> +
> +       TAILQ_REMOVE(&action_entry_list, entry, next);
> +       free(entry);
> +}
> +
> +/* The maximum amount of fd for one recvmsg/sendmsg */
> +#define SCM_MAX_FD             253
> +#define MAX_SECONDARY_PROCS    8
> +#define MAX_MESSAGE_LENGTH     1024
> +
> +struct mp_fds {
> +       int efd;
> +
> +       union {
> +               /* fds for primary process */
> +               struct {
> +                       int listen;
> +                       /* fds used to send msg to secondary process(es) */
> +                       int secondaries[MAX_SECONDARY_PROCS];
> +               };
> +
> +               /* fds for secondary process */
> +               struct {
> +                       /* fds used to send msg to the primary process */
> +                       int primary;
> +               };
> +       };
> +};
> +
> +static struct mp_fds mp_fds;
> +
> +struct msg_hdr {
> +       char action_name[MAX_ACTION_NAME_LEN];
> +       int fds_num;
> +       int len_params;
> +       char params[0];
> +} __rte_packed;
> +
> +static int
> +add_sec_proc(int fd)
> +{
> +       int i;
> +
> +       for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +               if (mp_fds.secondaries[i] == -1)
> +                       break;
> +
> +       if (i >= MAX_SECONDARY_PROCS)
> +               return -1;
> +
> +       mp_fds.secondaries[i] = fd;
> +
> +       return i;
> +}
> +
> +static void
> +del_sec_proc(int fd)
> +{
> +       int i;
> +
> +       for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
> +               if (mp_fds.secondaries[i] == fd) {
> +                       mp_fds.secondaries[i] = -1;
> +                       break;
> +               }
> +       }
> +}
> +
> +static int
> +read_msg(int sockfd, char *buf, int buflen, int *fds, int fds_num)
> +{
> +       struct iovec iov;
> +       struct msghdr msgh;
> +       size_t fdsize = fds_num * sizeof(int);
> +       char control[CMSG_SPACE(fdsize)];
> +       struct cmsghdr *cmsg;
> +       struct msg_hdr *hdr = (struct msg_hdr *)buf;
> +       int ret, total;
> +
> +       /* read msg_hdr */
> +       memset(&msgh, 0, sizeof(msgh));
> +       iov.iov_base = hdr;
> +       iov.iov_len  = sizeof(*hdr);
> +
> +       msgh.msg_iov = &iov;
> +       msgh.msg_iovlen = 1;
> +       msgh.msg_control = control;
> +       msgh.msg_controllen = sizeof(control);
> +
> +       ret = recvmsg(sockfd, &msgh, 0);
> +       if (ret != sizeof(struct msg_hdr)) {
> +               RTE_LOG(ERR, EAL, "recvmsg failed\n");
> +               return ret;
> +       }
> +
> +       if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
> +               RTE_LOG(ERR, EAL, "truncted msg\n");
> +               return -1;
> +       }
> +       total = ret;
> +
> +       /* read auxiliary FDs if any */
> +       for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
> +               cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
> +               if ((cmsg->cmsg_level == SOL_SOCKET) &&
> +                       (cmsg->cmsg_type == SCM_RIGHTS)) {
> +                       memcpy(fds, CMSG_DATA(cmsg), fdsize);
> +                       break;
> +               }
> +       }
> +
> +       /* read params */
> +       if (hdr->len_params) {
> +               if (hdr->len_params > buflen - (int)sizeof(*hdr))
> +                       rte_exit(EXIT_FAILURE, "params too long\n");
> +
> +               ret = read(sockfd, &hdr->params, hdr->len_params);
> +               if (ret != hdr->len_params)
> +                       rte_exit(EXIT_FAILURE, "failed to recv params\n");
> +
> +               total += ret;
> +       }
> +
> +       RTE_LOG(INFO, EAL, "read msg: %s, %d\n", hdr->action_name,
> +               (int)sizeof(*hdr) + hdr->len_params);
> +       return total;
> +}
> +
> +static int
> +process_msg(int fd)
> +{
> +       int len;
> +       int params_len;
> +       char buf[MAX_MESSAGE_LENGTH];
> +       int fds[SCM_MAX_FD];
> +       struct msg_hdr *hdr;
> +       struct action_entry *entry;
> +
> +       len = read_msg(fd, buf, MAX_MESSAGE_LENGTH, fds, SCM_MAX_FD);
> +       if (len <= 0) {
> +               RTE_LOG(ERR, EAL, "failed to read message: %s\n",
> +                       strerror(errno));
> +               return -1;
> +       }
> +
> +       hdr = (struct msg_hdr *) buf;
> +
> +       entry = find_action_entry_by_name(hdr->action_name);
> +       if (entry == NULL) {
> +               RTE_LOG(ERR, EAL, "cannot find action by: %s\n",
> +                       hdr->action_name);
> +               return -1;
> +       }
> +
> +       params_len = len - sizeof(struct msg_hdr);
> +       entry->action(hdr->params, params_len, fds, hdr->fds_num);
> +
> +       return 0;
> +}
> +
> +static int
> +add_secondary(void)
> +{
> +       int fd;
> +       struct epoll_event ev;
> +
> +       while (1) {
> +               fd = accept(mp_fds.listen, NULL, NULL);
> +               if (fd < 0 && errno == EAGAIN)
> +                       break;
> +               else if (fd < 0) {
> +                       RTE_LOG(ERR, EAL, "primary failed to accept: %s\n",
> +                               strerror(errno));
> +                       return -1;
> +               }
> +
> +               ev.events = EPOLLIN | EPOLLRDHUP;
> +               ev.data.fd = fd;
> +               if (epoll_ctl(mp_fds.efd, EPOLL_CTL_ADD, fd, &ev) < 0) {
> +                       RTE_LOG(ERR, EAL, "failed to add secondary: %s\n",
> +                               strerror(errno));
> +                       break;
> +               }
> +               if (add_sec_proc(fd) < 0) {
> +                       RTE_LOG(ERR, EAL, "too many secondary processes\n");
> +                       close(fd);
> +                       break;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static void *
> +mp_handler(void *arg __rte_unused)
> +{
> +       int fd;
> +       int i, n;
> +       struct epoll_event ev;
> +       struct epoll_event *events;
> +       int is_primary = rte_eal_process_type() == RTE_PROC_PRIMARY;
> +
> +       ev.events = EPOLLIN | EPOLLRDHUP;
> +       ev.data.fd = (is_primary) ? mp_fds.listen : mp_fds.primary;
> +       if (epoll_ctl(mp_fds.efd, EPOLL_CTL_ADD, ev.data.fd, &ev) < 0) {
> +               RTE_LOG(ERR, EAL, "failed to epoll_ctl: %s\n",
> +                       strerror(errno));
> +               exit(EXIT_FAILURE);
> +       }
> +
> +       events = calloc(20, sizeof ev);
> +
> +       while (1) {
> +               n = epoll_wait(mp_fds.efd, events, 20, -1);
> +               for (i = 0; i < n; i++) {
> +                       if (is_primary && events[i].data.fd == mp_fds.listen) {
> +                               if (events[i].events != EPOLLIN) {
> +                                       RTE_LOG(ERR, EAL, "what happens?\n");
> +                                       exit(EXIT_FAILURE);
> +                               }
> +
> +                               if (add_secondary() < 0)
> +                                       break;
> +
> +                               continue;
> +                       }
> +
> +                       fd = events[i].data.fd;
> +
> +                       if ((events[i].events & EPOLLIN)) {
> +                               if (process_msg(fd) < 0) {
> +                                       RTE_LOG(ERR, EAL,
> +                                               "failed to process msg\n");
> +                                       if (!is_primary)
> +                                               exit(EXIT_FAILURE);
> +                               }
> +                               continue;
> +                       }
> +
> +                       /* EPOLLERR, EPOLLHUP, etc */
> +                       if (is_primary) {
> +                               RTE_LOG(ERR, EAL, "secondary exit: %d\n", fd);
> +                               epoll_ctl(mp_fds.efd, EPOLL_CTL_DEL, fd, NULL);
> +                               del_sec_proc(fd);
> +                               close(fd);
> +                       } else {
> +                               RTE_LOG(ERR, EAL, "primary exits, so do I\n");
> +                               /* Exit secondary when primary exits? */
> +                               exit(EXIT_FAILURE);
> +                       }
> +               }
> +       }
> +
> +       return NULL;
> +}
> +
> +int
> +rte_eal_mp_channel_init(void)
> +{
> +       int i, fd, ret;
> +       const char *path;
> +       struct sockaddr_un un;
> +       pthread_t tid;
> +       char thread_name[RTE_MAX_THREAD_NAME_LEN];
> +
> +       mp_fds.efd = epoll_create1(0);
> +       if (mp_fds.efd < 0) {
> +               RTE_LOG(ERR, EAL, "epoll_create1 failed\n");
> +               return -1;
> +       }
> +
> +       fd = socket(AF_UNIX, SOCK_STREAM, 0);
> +       if (fd < 0) {
> +               RTE_LOG(ERR, EAL, "Failed to create unix socket\n");
> +               return -1;
> +       }
> +
> +       memset(&un, 0, sizeof(un));
> +       un.sun_family = AF_UNIX;
> +       path = eal_mp_unix_path();
> +       strncpy(un.sun_path, path, sizeof(un.sun_path));
> +       un.sun_path[sizeof(un.sun_path) - 1] = '\0';
> +
> +       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +               for (i = 0; i < MAX_SECONDARY_PROCS; ++i)
> +                       mp_fds.secondaries[i] = -1;
> +
> +               if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
> +                       RTE_LOG(ERR, EAL, "cannot set nonblocking mode\n");
> +                       close(fd);
> +                       return -1;
> +               }
> +
> +               /* The file still exists since last run */
> +               unlink(path);
> +
> +               ret = bind(fd, (struct sockaddr *)&un, sizeof(un));
> +               if (ret < 0) {
> +                       RTE_LOG(ERR, EAL, "failed to bind to %s: %s\n",
> +                               path, strerror(errno));
> +                       close(fd);
> +                       return -1;
> +               }
> +               RTE_LOG(INFO, EAL, "primary bind to %s\n", path);
> +
> +               ret = listen(fd, 1024);
> +               if (ret < 0) {
> +                       RTE_LOG(ERR, EAL, "failed to listen: %s\n",
> +                               strerror(errno));
> +                       close(fd);
> +                       return -1;
> +               }
> +               mp_fds.listen = fd;
> +       } else {
> +               ret = connect(fd, (struct sockaddr *)&un, sizeof(un));
> +               if (ret < 0) {
> +                       RTE_LOG(ERR, EAL, "failed to connect primary\n");
> +                       return -1;
> +               }
> +               mp_fds.primary = fd;
> +       }
> +
> +       ret = pthread_create(&tid, NULL, mp_handler, NULL);
> +       if (ret < 0) {
> +               RTE_LOG(ERR, EAL, "failed to create thead: %s\n",
> +                       strerror(errno));
> +               close(fd);
> +               close(mp_fds.efd);
> +               return -1;
> +       }
> +
> +       snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
> +                "rte_mp_handle");
> +       ret = rte_thread_setname(tid, thread_name);
> +       if (ret < 0) {
> +               RTE_LOG(ERR, EAL, "failed to set thead name\n");
> +               close(fd);
> +               close(mp_fds.efd);
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +static int
> +send_msg(int fd, struct msghdr *p_msgh)
> +{
> +       int ret;
> +
> +       do {
> +               ret = sendmsg(fd, p_msgh, 0);
> +       } while (ret < 0 && errno == EINTR);
> +
> +       if (ret < 0)
> +               RTE_LOG(ERR, EAL, "failed to send msg: %s\n", strerror(errno));
> +
> +       return ret;
> +}
> +
> +int
> +rte_eal_mp_sendmsg(const char *action_name,
> +                                 const void *params,
> +                                 int len_params,
> +                                 int fds[],
> +                                 int fds_num)
> +{
> +       int i;
> +       int ret = 0;
> +       struct msghdr msgh;
> +       struct iovec iov;
> +       size_t fd_size = fds_num * sizeof(int);
> +       char control[CMSG_SPACE(fd_size)];
> +       struct cmsghdr *cmsg;
> +       struct msg_hdr *msg;
> +       int len_msg;
> +
> +       if (fds_num > SCM_MAX_FD) {
> +               RTE_LOG(ERR, EAL,
> +                       "Cannot send more than %d FDs\n", SCM_MAX_FD);
> +               return -E2BIG;
> +       }
> +
> +       len_msg = sizeof(struct msg_hdr) + len_params;
> +       if (len_msg > MAX_MESSAGE_LENGTH) {
> +               RTE_LOG(ERR, EAL, "Message is too long\n");
> +               return -ENOMEM;
> +       }
> +
> +       RTE_LOG(INFO, EAL, "send msg: %s, %d\n", action_name, len_msg);
> +
> +       msg = malloc(len_msg);
> +       if (!msg) {
> +               RTE_LOG(ERR, EAL, "Cannot alloc memory for msg\n");
> +               return -ENOMEM;
> +       }
> +       memset(msg, 0, len_msg);
> +       strcpy(msg->action_name, action_name);
> +       msg->fds_num = fds_num;
> +       msg->len_params = len_params;
> +       memcpy(msg->params, params, len_params);
> +
> +       memset(&msgh, 0, sizeof(msgh));
> +       memset(control, 0, sizeof(control));
> +
> +       iov.iov_base = (uint8_t *)msg;
> +       iov.iov_len = len_msg;
> +
> +       msgh.msg_iov = &iov;
> +       msgh.msg_iovlen = 1;
> +       msgh.msg_control = control;
> +       msgh.msg_controllen = sizeof(control);
> +
> +       cmsg = CMSG_FIRSTHDR(&msgh);
> +       cmsg->cmsg_len = CMSG_LEN(fd_size);
> +       cmsg->cmsg_level = SOL_SOCKET;
> +       cmsg->cmsg_type = SCM_RIGHTS;
> +       memcpy(CMSG_DATA(cmsg), fds, fd_size);
> +
> +       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +               for (i = 0; i < MAX_SECONDARY_PROCS; ++i) {
> +                       if (mp_fds.secondaries[i] == -1)
> +                               continue;
> +
> +                       ret = send_msg(mp_fds.secondaries[i], &msgh);
> +                       if (ret < 0)
> +                               break;
> +               }
> +       } else {
> +               ret = send_msg(mp_fds.primary, &msgh);
> +       }
> +
> +       free(msg);
> +
> +       return ret;
> +}
> diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
> index 8acbd99..3d9514f 100644
> --- a/lib/librte_eal/common/eal_filesystem.h
> +++ b/lib/librte_eal/common/eal_filesystem.h
> @@ -67,6 +67,24 @@ eal_runtime_config_path(void)
>         return buffer;
>  }
>
> +/** Path of primary/secondary communication unix socket file. */
> +#define MP_UNIX_PATH_FMT "%s/.%s_unix"
> +static inline const char *
> +eal_mp_unix_path(void)
> +{
> +       static char buffer[PATH_MAX]; /* static so auto-zeroed */
> +       const char *directory = default_config_dir;
> +       const char *home_dir = getenv("HOME");
> +
> +       if (getuid() != 0 && home_dir != NULL)
> +               directory = home_dir;
> +       snprintf(buffer, sizeof(buffer) - 1, MP_UNIX_PATH_FMT,
> +                directory, internal_config.hugefile_prefix);
> +
> +       return buffer;
> +
> +}
> +
>  /** Path of hugepage info file. */
>  #define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
>
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 597d82e..7fbfbdf 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -355,4 +355,14 @@ bool rte_eal_using_phys_addrs(void);
>   */
>  struct rte_bus *rte_bus_find_by_device_name(const char *str);
>
> +/**
> + * Create the unix channel for primary/secondary communication.
> + *
> + * @return
> + *   0 on success;
> + *   (<0) on failure.
> + */
> +
> +int rte_eal_mp_channel_init(void);
> +
>  #endif /* _EAL_PRIVATE_H_ */
> diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
> index 0e7363d..4e3d4d2 100644
> --- a/lib/librte_eal/common/include/rte_eal.h
> +++ b/lib/librte_eal/common/include/rte_eal.h
> @@ -210,6 +210,74 @@ int rte_eal_init(int argc, char **argv);
>  int rte_eal_primary_proc_alive(const char *config_file_path);
>
>  /**
> + * Action function typedef used by other components.
> + *
> + * As we create unix socket channel for primary/secondary communication, use
> + * this function typedef to register action for coming messages.
> + */
> +typedef int (*rte_eal_mp_t)(const void *params, int len,
> +                           int fds[], int fds_num);
> +/**
> + * Register an action function for primary/secondary communication.
> + *
> + * Call this function to register an action, if the calling component wants
> + * to response the messages from the corresponding component in its primary
> + * process or secondary processes.
> + *
> + * @param action_name
> + *   The action_name argument plays as the nonredundant key to find the action.
> + *
> + * @param action
> + *   The action argument is the function pointer to the action function.
> + *
> + * @return
> + *  - 0 on success.
> + *  - (<0) on failure.
> + */
> +int rte_eal_mp_action_register(const char *action_name, rte_eal_mp_t action);
> +/**
> + * Unregister an action function for primary/secondary communication.
> + *
> + * Call this function to unregister an action  if the calling component does
> + * not want to response the messages from the corresponding component in its
> + * primary process or secondary processes.
> + *
> + * @param action_name
> + *   The action_name argument plays as the nonredundant key to find the action.
> + *
> + */
> +void rte_eal_mp_action_unregister(const char *name);
> +
> +/**
> + * Send a message to the primary process or the secondary processes.
> + *
> + * This function will send a message which will be responsed by the action
> + * identified by action_name of the process on the other side.
> + *
> + * @param action_name
> + *   The action_name argument is used to identify which action will be used.
> + *
> + * @param params
> + *   The params argument contains the customized message.
> + *
> + * @param len_params
> + *   The len_params argument is the length of the customized message.
> + *
> + * @param fds
> + *   The fds argument is an array of fds sent with sendmsg.
> + *
> + * @param fds_num
> + *   The fds_num argument is number of fds to be sent with sendmsg.
> + *
> + * @return
> + *  - (>=0) on success.
> + *  - (<0) on failure.
> + */
> +int
> +rte_eal_mp_sendmsg(const char *action_name, const void *params,
> +                  int len_params, int fds[], int fds_num);
> +
> +/**
>   * Usage function typedef used by the application usage function.
>   *
>   * Use this function typedef to define and call rte_set_applcation_usage_hook()
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 48f12f4..4b491b9 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -873,6 +873,12 @@ rte_eal_init(int argc, char **argv)
>
>         eal_check_mem_on_local_socket();
>
> +       if (rte_eal_mp_channel_init() < 0) {
> +               rte_eal_init_alert("failed to init mp channel\n");
> +               rte_errno = EFAULT;
> +               return -1;
> +       }
> +
>         if (eal_plugins_init() < 0)
>                 rte_eal_init_alert("Cannot init plugins\n");
>
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 8c08b8d..2e1d0e5 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -243,3 +243,11 @@ EXPERIMENTAL {
>         rte_service_start_with_defaults;
>
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +       global:
> +
> +       rte_eal_primary_secondary_add_action;
> +       rte_eal_primary_secondary_del_action;
> +       rte_eal_primary_secondary_sendmsg;
> +} DPDK_17.11;
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 08/12] bus/vdev: scan and probe vdev in secondary processes
  2017-09-28 13:55   ` [PATCH v2 08/12] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
@ 2017-10-05 13:04     ` Jan Blunck
  2017-10-09  1:08       ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Jan Blunck @ 2017-10-05 13:04 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, Bruce Richardson, Ananyev, Konstantin, De Lara Guarch,
	Pablo, Thomas Monjalon, yliu, Maxime Coquelin, Tetsuya Mukawa,
	Ferruh Yigit

On Thu, Sep 28, 2017 at 3:55 PM, Jianfeng Tan <jianfeng.tan@intel.com> wrote:
> Base on primary/secondary communication channel, we add vdev action
> to scan virtual devices in secondary processes.
>

This doesn't need to be in vdev. You application could just hotplug
the drivers with exactly the same parameters as the primary process.
The driver need to be aware of the primary/secondary process split
though.


> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/bus/vdev/vdev.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 100 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
> index e0ba0da..1d1690f 100644
> --- a/drivers/bus/vdev/vdev.c
> +++ b/drivers/bus/vdev/vdev.c
> @@ -104,7 +104,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
>
>         name = rte_vdev_device_name(dev);
>
> -       VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
> +       VDEV_LOG(DEBUG, "Search driver %s to probe device %s", name,
>                 rte_vdev_device_name(dev));
>
>         if (vdev_parse(name, &driver))
> @@ -190,7 +190,7 @@ rte_vdev_init(const char *name, const char *args)
>         ret = vdev_probe_all_drivers(dev);
>         if (ret) {
>                 if (ret > 0)
> -                       VDEV_LOG(ERR, "no driver found for %s\n", name);
> +                       VDEV_LOG(ERR, "no driver found for %s", name);
>                 goto fail;
>         }
>
> @@ -213,7 +213,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
>         const struct rte_vdev_driver *driver;
>
>         if (!dev->device.driver) {
> -               VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
> +               VDEV_LOG(DEBUG, "no driver attach to device %s", name);
>                 return 1;
>         }
>
> @@ -252,12 +252,105 @@ rte_vdev_uninit(const char *name)
>         return 0;
>  }
>
> +struct vdev_action_params {
> +#define VDEV_SCAN_REQUEST      1
> +#define VDEV_SCAN_RESPONSE     2
> +       int type;
> +       char name[32];
> +};
> +
> +static int vdev_plug(struct rte_device *dev);
> +
> +static int
> +vdev_action(const void *params, int len,
> +           int fds[] __rte_unused,
> +           int fds_num __rte_unused)
> +{
> +       struct rte_vdev_device *dev;
> +       struct rte_devargs *devargs;
> +       struct vdev_action_params ou_params;
> +       const struct vdev_action_params *in_params = params;
> +
> +       switch (in_params->type) {
> +       case VDEV_SCAN_REQUEST:
> +               ou_params.type = VDEV_SCAN_RESPONSE;
> +               TAILQ_FOREACH(dev, &vdev_device_list, next) {
> +                       VDEV_LOG(INFO, "push vdev, %s", dev->device.name);
> +                       strncpy(ou_params.name, dev->device.name, 32);
> +                       rte_eal_mp_sendmsg("vdev", &ou_params,
> +                                                         len, NULL, 0);
> +               }
> +               break;
> +       case VDEV_SCAN_RESPONSE:
> +               VDEV_LOG(INFO, "get vdev, %s", in_params->name);
> +
> +               if (strlen(in_params->name) == 0) {
> +                       VDEV_LOG(ERR, "invalid name was passed");
> +                       break;
> +               }
> +
> +               dev = find_vdev(in_params->name);
> +               if (dev) {
> +                       VDEV_LOG(ERR, "vdev already exists: %s", in_params->name);
> +                       break;
> +               }
> +
> +               devargs = alloc_devargs(in_params->name, NULL);
> +               if (!devargs) {
> +                       VDEV_LOG(ERR, "failed to allocate memory");
> +                       break;
> +               }
> +
> +               dev = calloc(1, sizeof(*dev));
> +               if (!dev) {
> +                       VDEV_LOG(ERR, "failed to allocate memory");
> +                       free(devargs);
> +                       break;
> +               }
> +
> +               dev->device.devargs = devargs;
> +               dev->device.numa_node = 0; /* to be corrected in probe() */
> +               dev->device.name = devargs->name;
> +
> +               TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
> +               TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
> +
> +               if (vdev_plug(&dev->device) < 0) {
> +                       VDEV_LOG(ERR, "failed to plug device %s", in_params->name);
> +                       free(devargs);
> +                       free(dev);
> +               } else
> +                       VDEV_LOG(INFO, "plug in device: %s", in_params->name);
> +
> +               break;
> +       default:
> +               VDEV_LOG(ERR, "vdev cannot recognize this message");
> +       }
> +
> +       return 0;
> +}
> +
>  static int
>  vdev_scan(void)
>  {
>         struct rte_vdev_device *dev;
>         struct rte_devargs *devargs;
>
> +       if (rte_eal_mp_action_register("vdev", vdev_action) < 0) {
> +               VDEV_LOG(ERR, "vdev fails to add action");
> +               return -1;
> +       }
> +
> +       if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
> +               struct vdev_action_params params;
> +
> +               params.type = VDEV_SCAN_REQUEST;
> +               rte_eal_mp_sendmsg("vdev", &params,
> +                                                 sizeof(params), NULL, 0);
> +
> +               return 0;
> +       }
> +
>         /* for virtual devices we scan the devargs_list populated via cmdline */
>         TAILQ_FOREACH(devargs, &devargs_list, next) {
>
> @@ -287,6 +380,9 @@ vdev_probe(void)
>  {
>         struct rte_vdev_device *dev;
>
> +       if (rte_eal_process_type() == RTE_PROC_SECONDARY)
> +               return 0;
> +
>         /* call the init function for each virtual device */
>         TAILQ_FOREACH(dev, &vdev_device_list, next) {
>
> @@ -294,7 +390,7 @@ vdev_probe(void)
>                         continue;
>
>                 if (vdev_probe_all_drivers(dev)) {
> -                       VDEV_LOG(ERR, "failed to initialize %s device\n",
> +                       VDEV_LOG(ERR, "failed to initialize %s device",
>                                 rte_vdev_device_name(dev));
>                         return -1;
>                 }
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 03/12] cryptodev: avoid dependency on rte_vdev.h
  2017-09-28 13:55   ` [PATCH v2 03/12] cryptodev: avoid dependency on rte_vdev.h Jianfeng Tan
@ 2017-10-05 13:13     ` Jan Blunck
  2017-10-09  1:04       ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Jan Blunck @ 2017-10-05 13:13 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, Bruce Richardson, Ananyev, Konstantin, De Lara Guarch,
	Pablo, Thomas Monjalon, yliu, Maxime Coquelin, Tetsuya Mukawa,
	Ferruh Yigit

On Thu, Sep 28, 2017 at 3:55 PM, Jianfeng Tan <jianfeng.tan@intel.com> wrote:
> The helper API, rte_cryptodev_vdev_pmd_init(), has a parameter of
> struct rte_vdev_device *, which needs to include rte_vdev.h.
>
> We will move vdev into drivers/bus, so we need to avoid such
> dependency. And also, we cannot break the ABI.
>
> This patch changes that pointer to void *, and defines an internal
> structure same with struct rte_vdev_device.
>

This code duplication is unnecessary. Also you are doing evil thinks
and define a type with the same name in multiple places. Look at my
series how to do this properly.


> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_cryptodev/rte_cryptodev_pmd.c  |   9 +-
>  lib/librte_cryptodev/rte_cryptodev_vdev.c | 161 ++++++++++++++++++++++++++++++
>  lib/librte_cryptodev/rte_cryptodev_vdev.h |   3 +-
>  3 files changed, 169 insertions(+), 4 deletions(-)
>  create mode 100644 lib/librte_cryptodev/rte_cryptodev_vdev.c
>
> diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
> index a57faad..60b3980 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
> +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
> @@ -75,9 +75,14 @@ rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
>         return 0;
>  }
>
> +struct vdev_device {
> +       TAILQ_ENTRY(rte_vdev_device) next;
> +       struct rte_device device;
> +};
> +
>  struct rte_cryptodev *
>  rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
> -               int socket_id, struct rte_vdev_device *vdev)
> +               int socket_id, void *vdev)
>  {
>         struct rte_cryptodev *cryptodev;
>
> @@ -99,7 +104,7 @@ rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
>                                         " data");
>         }
>
> -       cryptodev->device = &vdev->device;
> +       cryptodev->device = &((struct vdev_device *)vdev)->device;
>
>         /* initialise user call-back tail queue */
>         TAILQ_INIT(&(cryptodev->link_intr_cbs));
> diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.c b/lib/librte_cryptodev/rte_cryptodev_vdev.c
> new file mode 100644
> index 0000000..4af8d51
> --- /dev/null
> +++ b/lib/librte_cryptodev/rte_cryptodev_vdev.c
> @@ -0,0 +1,161 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of the copyright holder nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <sys/queue.h>
> +
> +#include "rte_cryptodev_vdev.h"
> +#include "rte_cryptodev_pci.h"
> +#include "rte_cryptodev_pmd.h"
> +
> +/**
> + * Parse name from argument
> + */
> +static int
> +rte_cryptodev_vdev_parse_name_arg(const char *key __rte_unused,
> +               const char *value, void *extra_args)
> +{
> +       struct rte_crypto_vdev_init_params *params = extra_args;
> +
> +       if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
> +               CDEV_LOG_ERR("Invalid name %s, should be less than "
> +                               "%u bytes", value,
> +                               RTE_CRYPTODEV_NAME_MAX_LEN - 1);
> +               return -1;
> +       }
> +
> +       strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
> +
> +       return 0;
> +}
> +
> +/**
> + * Parse integer from argument
> + */
> +static int
> +rte_cryptodev_vdev_parse_integer_arg(const char *key __rte_unused,
> +               const char *value, void *extra_args)
> +{
> +       int *i = extra_args;
> +
> +       *i = atoi(value);
> +       if (*i < 0) {
> +               CDEV_LOG_ERR("Argument has to be positive.");
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +struct vdev_device {
> +       TAILQ_ENTRY(rte_vdev_device) next;
> +       struct rte_device device;
> +};
> +
> +struct rte_cryptodev *
> +rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
> +               int socket_id, void *vdev)
> +{
> +       struct rte_cryptodev *cryptodev;
> +
> +       /* allocate device structure */
> +       cryptodev = rte_cryptodev_pmd_allocate(name, socket_id);
> +       if (cryptodev == NULL)
> +               return NULL;
> +
> +       /* allocate private device structure */
> +       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +               cryptodev->data->dev_private =
> +                               rte_zmalloc_socket("cryptodev device private",
> +                                               dev_private_size,
> +                                               RTE_CACHE_LINE_SIZE,
> +                                               socket_id);
> +
> +               if (cryptodev->data->dev_private == NULL)
> +                       rte_panic("Cannot allocate memzone for private device"
> +                                       " data");
> +       }
> +
> +       cryptodev->device = &((struct vdev_device *)vdev)->device;
> +
> +       /* initialise user call-back tail queue */
> +       TAILQ_INIT(&(cryptodev->link_intr_cbs));
> +
> +       return cryptodev;
> +}
> +
> +int
> +rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
> +               const char *input_args)
> +{
> +       struct rte_kvargs *kvlist = NULL;
> +       int ret = 0;
> +
> +       if (params == NULL)
> +               return -EINVAL;
> +
> +       if (input_args) {
> +               kvlist = rte_kvargs_parse(input_args,
> +                               cryptodev_vdev_valid_params);
> +               if (kvlist == NULL)
> +                       return -1;
> +
> +               ret = rte_kvargs_process(kvlist,
> +                                       RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
> +                                       &rte_cryptodev_vdev_parse_integer_arg,
> +                                       &params->max_nb_queue_pairs);
> +               if (ret < 0)
> +                       goto free_kvlist;
> +
> +               ret = rte_kvargs_process(kvlist,
> +                                       RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
> +                                       &rte_cryptodev_vdev_parse_integer_arg,
> +                                       &params->max_nb_sessions);
> +               if (ret < 0)
> +                       goto free_kvlist;
> +
> +               ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
> +                                       &rte_cryptodev_vdev_parse_integer_arg,
> +                                       &params->socket_id);
> +               if (ret < 0)
> +                       goto free_kvlist;
> +
> +               ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
> +                                       &rte_cryptodev_vdev_parse_name_arg,
> +                                       params);
> +               if (ret < 0)
> +                       goto free_kvlist;
> +       }
> +
> +free_kvlist:
> +       rte_kvargs_free(kvlist);
> +       return ret;
> +}
> diff --git a/lib/librte_cryptodev/rte_cryptodev_vdev.h b/lib/librte_cryptodev/rte_cryptodev_vdev.h
> index 94ab9d3..1142d1d 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_vdev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev_vdev.h
> @@ -33,7 +33,6 @@
>  #ifndef _RTE_CRYPTODEV_VDEV_H_
>  #define _RTE_CRYPTODEV_VDEV_H_
>
> -#include <rte_vdev.h>
>  #include <inttypes.h>
>
>  #include "rte_cryptodev.h"
> @@ -80,7 +79,7 @@ struct rte_crypto_vdev_init_params {
>   */
>  struct rte_cryptodev *
>  rte_cryptodev_vdev_pmd_init(const char *name, size_t dev_private_size,
> -               int socket_id, struct rte_vdev_device *vdev);
> +               int socket_id, void *vdev);
>
>  /**
>   * @internal
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 09/12] ethdev: support attach vdev in secondary process
  2017-09-28 13:55   ` [PATCH v2 09/12] ethdev: support attach vdev in secondary process Jianfeng Tan
@ 2017-10-05 14:26     ` Jan Blunck
  2017-10-09  0:56       ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Jan Blunck @ 2017-10-05 14:26 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, Bruce Richardson, Ananyev, Konstantin, De Lara Guarch,
	Pablo, Thomas Monjalon, yliu, Maxime Coquelin, Tetsuya Mukawa,
	Ferruh Yigit

On Thu, Sep 28, 2017 at 3:55 PM, Jianfeng Tan <jianfeng.tan@intel.com> wrote:
> When vdev driver requests an ethdev entry in secondary process,
> we will identify the correct entry in rte_eth_dev_data array
> and return the correct entry in the rte_eth_devices arrays.
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_ether/rte_ethdev_vdev.h | 26 +++++++++++++++-----------
>  1 file changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/lib/librte_ether/rte_ethdev_vdev.h b/lib/librte_ether/rte_ethdev_vdev.h
> index 4d2c3e2..460749b 100644
> --- a/lib/librte_ether/rte_ethdev_vdev.h
> +++ b/lib/librte_ether/rte_ethdev_vdev.h
> @@ -58,25 +58,29 @@ rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size)
>         struct rte_eth_dev *eth_dev;
>         const char *name = rte_vdev_device_name(dev);
>
> -       eth_dev = rte_eth_dev_allocate(name);
> -       if (!eth_dev)
> -               return NULL;
> -
> -       if (private_data_size) {
> -               eth_dev->data->dev_private = rte_zmalloc_socket(name,
> -                       private_data_size, RTE_CACHE_LINE_SIZE,
> -                       dev->device.numa_node);
> -               if (!eth_dev->data->dev_private) {
> -                       rte_eth_dev_release_port(eth_dev);
> +       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +               eth_dev = rte_eth_dev_allocate(name);
> +               if (!eth_dev)
>                         return NULL;
> +
> +               if (private_data_size) {
> +                       eth_dev->data->dev_private = rte_zmalloc_socket(name,
> +                                       private_data_size, RTE_CACHE_LINE_SIZE,
> +                                       dev->device.numa_node);
> +                       if (!eth_dev->data->dev_private) {
> +                               rte_eth_dev_release_port(eth_dev);
> +                               return NULL;
> +                       }
>                 }
> +       } else {
> +               eth_dev = rte_eth_dev_attach_secondary(name);

I don't see the point why the secondary process should call
rte_eth_vdev_allocate() in the first place. The driver needs to setup
the IPC anyway so it should just call rte_eth_dev_attach_secondary()
instead.


>         }
>
>         eth_dev->device = &dev->device;
>         eth_dev->intr_handle = NULL;
> -
>         eth_dev->data->kdrv = RTE_KDRV_NONE;
>         eth_dev->data->numa_node = dev->device.numa_node;
> +
>         return eth_dev;
>  }
>
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 09/12] ethdev: support attach vdev in secondary process
  2017-10-05 14:26     ` Jan Blunck
@ 2017-10-09  0:56       ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-09  0:56 UTC (permalink / raw)
  To: Jan Blunck
  Cc: dev, Richardson, Bruce, Ananyev, Konstantin, De Lara Guarch,
	Pablo, Thomas Monjalon, yliu, Maxime Coquelin, Tetsuya Mukawa,
	Yigit, Ferruh

Hi Jan,

> -----Original Message-----
> From: jblunck@gmail.com [mailto:jblunck@gmail.com] On Behalf Of Jan
> Blunck
> Sent: Thursday, October 5, 2017 10:27 PM
> To: Tan, Jianfeng
> Cc: dev; Richardson, Bruce; Ananyev, Konstantin; De Lara Guarch, Pablo;
> Thomas Monjalon; yliu@fridaylinux.org; Maxime Coquelin; Tetsuya Mukawa;
> Yigit, Ferruh
> Subject: Re: [dpdk-dev] [PATCH v2 09/12] ethdev: support attach vdev in
> secondary process
> 
> On Thu, Sep 28, 2017 at 3:55 PM, Jianfeng Tan <jianfeng.tan@intel.com>
> wrote:
> > When vdev driver requests an ethdev entry in secondary process,
> > we will identify the correct entry in rte_eth_dev_data array
> > and return the correct entry in the rte_eth_devices arrays.
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  lib/librte_ether/rte_ethdev_vdev.h | 26 +++++++++++++++-----------
> >  1 file changed, 15 insertions(+), 11 deletions(-)
> >
> > diff --git a/lib/librte_ether/rte_ethdev_vdev.h
> b/lib/librte_ether/rte_ethdev_vdev.h
> > index 4d2c3e2..460749b 100644
> > --- a/lib/librte_ether/rte_ethdev_vdev.h
> > +++ b/lib/librte_ether/rte_ethdev_vdev.h
> > @@ -58,25 +58,29 @@ rte_eth_vdev_allocate(struct rte_vdev_device
> *dev, size_t private_data_size)
> >         struct rte_eth_dev *eth_dev;
> >         const char *name = rte_vdev_device_name(dev);
> >
> > -       eth_dev = rte_eth_dev_allocate(name);
> > -       if (!eth_dev)
> > -               return NULL;
> > -
> > -       if (private_data_size) {
> > -               eth_dev->data->dev_private = rte_zmalloc_socket(name,
> > -                       private_data_size, RTE_CACHE_LINE_SIZE,
> > -                       dev->device.numa_node);
> > -               if (!eth_dev->data->dev_private) {
> > -                       rte_eth_dev_release_port(eth_dev);
> > +       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > +               eth_dev = rte_eth_dev_allocate(name);
> > +               if (!eth_dev)
> >                         return NULL;
> > +
> > +               if (private_data_size) {
> > +                       eth_dev->data->dev_private = rte_zmalloc_socket(name,
> > +                                       private_data_size, RTE_CACHE_LINE_SIZE,
> > +                                       dev->device.numa_node);
> > +                       if (!eth_dev->data->dev_private) {
> > +                               rte_eth_dev_release_port(eth_dev);
> > +                               return NULL;
> > +                       }
> >                 }
> > +       } else {
> > +               eth_dev = rte_eth_dev_attach_secondary(name);
> 
> I don't see the point why the secondary process should call
> rte_eth_vdev_allocate() in the first place. The driver needs to setup
> the IPC anyway so it should just call rte_eth_dev_attach_secondary()
> instead.
	
Hmm... make sense. Will fix it in the next version.

Thanks for the input.

Thanks,
Jianfeng


^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 03/12] cryptodev: avoid dependency on rte_vdev.h
  2017-10-05 13:13     ` Jan Blunck
@ 2017-10-09  1:04       ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-09  1:04 UTC (permalink / raw)
  To: Jan Blunck
  Cc: dev, Richardson, Bruce, Ananyev, Konstantin, De Lara Guarch,
	Pablo, Thomas Monjalon, yliu, Maxime Coquelin, Tetsuya Mukawa,
	Yigit, Ferruh

Hi Jan,

> -----Original Message-----
> From: jblunck@gmail.com [mailto:jblunck@gmail.com] On Behalf Of Jan
> Blunck
> Sent: Thursday, October 5, 2017 9:14 PM
> To: Tan, Jianfeng
> Cc: dev; Richardson, Bruce; Ananyev, Konstantin; De Lara Guarch, Pablo;
> Thomas Monjalon; yliu@fridaylinux.org; Maxime Coquelin; Tetsuya Mukawa;
> Yigit, Ferruh
> Subject: Re: [dpdk-dev] [PATCH v2 03/12] cryptodev: avoid dependency on
> rte_vdev.h
> 
> On Thu, Sep 28, 2017 at 3:55 PM, Jianfeng Tan <jianfeng.tan@intel.com>
> wrote:
> > The helper API, rte_cryptodev_vdev_pmd_init(), has a parameter of
> > struct rte_vdev_device *, which needs to include rte_vdev.h.
> >
> > We will move vdev into drivers/bus, so we need to avoid such
> > dependency. And also, we cannot break the ABI.
> >
> > This patch changes that pointer to void *, and defines an internal
> > structure same with struct rte_vdev_device.
> >
> 
> This code duplication is unnecessary. Also you are doing evil thinks
> and define a type with the same name in multiple places. Look at my
> series how to do this properly.
> 

Moving related things into header file is also my plan. Thank for doing that, I'll rebase on your patchset.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 08/12] bus/vdev: scan and probe vdev in secondary processes
  2017-10-05 13:04     ` Jan Blunck
@ 2017-10-09  1:08       ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-09  1:08 UTC (permalink / raw)
  To: Jan Blunck
  Cc: dev, Richardson, Bruce, Ananyev, Konstantin, De Lara Guarch,
	Pablo, Thomas Monjalon, yliu, Maxime Coquelin, Tetsuya Mukawa,
	Yigit, Ferruh

Hi Jan,

> -----Original Message-----
> From: jblunck@gmail.com [mailto:jblunck@gmail.com] On Behalf Of Jan
> Blunck
> Sent: Thursday, October 5, 2017 9:05 PM
> To: Tan, Jianfeng
> Cc: dev; Richardson, Bruce; Ananyev, Konstantin; De Lara Guarch, Pablo;
> Thomas Monjalon; yliu@fridaylinux.org; Maxime Coquelin; Tetsuya Mukawa;
> Yigit, Ferruh
> Subject: Re: [dpdk-dev] [PATCH v2 08/12] bus/vdev: scan and probe vdev in
> secondary processes
> 
> On Thu, Sep 28, 2017 at 3:55 PM, Jianfeng Tan <jianfeng.tan@intel.com>
> wrote:
> > Base on primary/secondary communication channel, we add vdev action
> > to scan virtual devices in secondary processes.
> >
> 
> This doesn't need to be in vdev. You application could just hotplug
> the drivers with exactly the same parameters as the primary process.
> The driver need to be aware of the primary/secondary process split
> though.
> 

This patch can make sure the virtual devices can be discovered and attached automatically by the secondary process. Of course, we can also add parameter to indicate if a vdev expects to be discovered and initialized automatically.
How do you think?

Thanks,
Jianfeng


^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v2 07/12] eal: add channel for primary/secondary communication
  2017-10-05 12:01     ` Jan Blunck
@ 2017-10-09  1:27       ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-09  1:27 UTC (permalink / raw)
  To: Jan Blunck
  Cc: dev, Richardson, Bruce, Ananyev, Konstantin, De Lara Guarch,
	Pablo, Thomas Monjalon, yliu, Maxime Coquelin, Tetsuya Mukawa,
	Yigit, Ferruh

Hi Jan,

> -----Original Message-----
> From: jblunck@gmail.com [mailto:jblunck@gmail.com] On Behalf Of Jan
> Blunck
> Sent: Thursday, October 5, 2017 8:02 PM
> To: Tan, Jianfeng
> Cc: dev; Richardson, Bruce; Ananyev, Konstantin; De Lara Guarch, Pablo;
> Thomas Monjalon; yliu@fridaylinux.org; Maxime Coquelin; Tetsuya Mukawa;
> Yigit, Ferruh
> Subject: Re: [dpdk-dev] [PATCH v2 07/12] eal: add channel for
> primary/secondary communication
> 
> On Thu, Sep 28, 2017 at 3:55 PM, Jianfeng Tan <jianfeng.tan@intel.com>
> wrote:
> > Previouly, there is only one way for primary/secondary to exchange
> > messages, that is, primary process writes info into some predefind
> > file, and secondary process reads info out. That cannot address
> > the requirements:
> >   a. Secondary wants to send info to primary, for example, secondary
> >      would like to send request (about some specific vdev to primary).
> >   b. Sending info at any time, instead of just initialization time.
> >   c. Share FDs with the other side, for vdev like vhost, related FDs
> >      (memory region, kick) should be shared.
> >
> > This patch proposes to create a communication channel, as an unix
> > socket connection, for above requirements. Primary will listen on
> > the unix socket; secondary will connect this socket to talk.
> >
> > Three new APIs are added:
> >
> >   1. rte_eal_mp_action_register is used to register an action,
> >      indexed by a string; if the calling component wants to
> >      response the messages from the corresponding component in
> >      its primary process or secondary processes.
> >   2. rte_eal_mp_action_unregister is used to unregister the action
> >      if the calling component does not want to response the messages.
> >   3. rte_eal_mp_sendmsg is used to send a message.
> >
> 
> Sorry, but I fail to see how this is something that should be solved
> in the DPDK. This is about application interprocess communication.
> From my point of view this has absolutely nothing to do with the DPDK.

IMO, it's a refinement of current primary/secondary model. (BTW, the primary/secondary model is inherent in DPDK at very early stage, and proved to be useful for application design)

And as previous reviewers point out, there are already some mechanisms in each component (eal init, vfio, pdump) to do the primary/secondary communication. This patch is targeted to converge them into one generic mechanism.

In the other side, we don't want the applications developers to take care of the communication information inside DPDK library, right?

> 
> From my point of view the DPDK should not become another operating
> system abstraction library outside of what is absolutely required. We
> already dictate way too much (e.g. threading model, config files, ...)
> for the users of the DPDK.

I agree in some extent. But for threading model, we do have the use cases, like quick restart, fault isolation,etc.

Thanks,
Jianfeng
 

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v3 0/5] move vdev into drivers/bus
  2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
                   ` (12 preceding siblings ...)
  2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
@ 2017-10-09  3:20 ` Jianfeng Tan
  2017-10-09  3:20   ` [PATCH v3 1/5] cryptodev: remove crypto vdev init API Jianfeng Tan
                     ` (14 more replies)
  13 siblings, 15 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09  3:20 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

This patch set depends on:
  http://dpdk.org/ml/archives/dev/2017-October/077855.html

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we tend to move all bus drivers from EAL
to drivers/bus/. This patch set targets vdev bus.

Jianfeng Tan (5):
  cryptodev: remove crypto vdev init API
  eal: avoid calling rte_vdev_init()
  bus: introduce RTE_LOGTYPE_BUS for bus drivers
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: normalize log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 drivers/bus/Makefile                           |   2 +
 drivers/bus/fslmc/fslmc_bus.c                  |   9 +-
 drivers/bus/fslmc/fslmc_logs.h                 |  42 +--
 drivers/bus/fslmc/fslmc_vfio.c                 |   4 +-
 drivers/bus/vdev/Makefile                      |  55 ++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |  10 +
 drivers/bus/vdev/rte_vdev.h                    | 153 +++++++++++
 drivers/bus/vdev/vdev.c                        | 344 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  40 +++
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   1 -
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  21 +-
 lib/librte_eal/common/eal_common_log.c         |   1 +
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_log.h        |   1 +
 lib/librte_eal/common/include/rte_vdev.h       | 131 ----------
 lib/librte_eal/linuxapp/eal/Makefile           |   1 -
 mk/rte.app.mk                                  |   1 +
 24 files changed, 628 insertions(+), 590 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v3 1/5] cryptodev: remove crypto vdev init API
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-09  3:20   ` Jianfeng Tan
  2017-10-09  3:20   ` [PATCH v3 2/5] eal: avoid calling rte_vdev_init() Jianfeng Tan
                     ` (13 subsequent siblings)
  14 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09  3:20 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 4 files changed, 29 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index f4269f0..85a9287 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -78,11 +78,6 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * cryptodev: the following function will be static in 17.11 and included
   by all crypto drivers, therefore, will not be public:
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 5e8f7f4..f2c55cc 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index ad97ff9..c5d6939 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -433,23 +433,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index abdbbda..b07f4ca 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v3 2/5] eal: avoid calling rte_vdev_init()
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
  2017-10-09  3:20   ` [PATCH v3 1/5] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-09  3:20   ` Jianfeng Tan
  2017-10-09  3:20   ` [PATCH v3 3/5] bus: introduce RTE_LOGTYPE_BUS for bus drivers Jianfeng Tan
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09  3:20 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..87e2bf8 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,12 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v3 3/5] bus: introduce RTE_LOGTYPE_BUS for bus drivers
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
  2017-10-09  3:20   ` [PATCH v3 1/5] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-10-09  3:20   ` [PATCH v3 2/5] eal: avoid calling rte_vdev_init() Jianfeng Tan
@ 2017-10-09  3:20   ` Jianfeng Tan
  2017-10-09  3:20   ` [PATCH v3 4/5] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09  3:20 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Introduce a new log type, RTE_LOGTYPE_BUS, for bus drivers. And
change fslmc to use this type for logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/fslmc/fslmc_bus.c           |  9 +++----
 drivers/bus/fslmc/fslmc_logs.h          | 42 ++++-----------------------------
 drivers/bus/fslmc/fslmc_vfio.c          |  4 +---
 lib/librte_eal/common/eal_common_log.c  |  1 +
 lib/librte_eal/common/include/rte_log.h |  1 +
 5 files changed, 11 insertions(+), 46 deletions(-)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 0a8229f..236ec3a 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -34,7 +34,6 @@
 #include <dirent.h>
 #include <stdbool.h>
 
-#include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
@@ -42,11 +41,9 @@
 #include <rte_memcpy.h>
 #include <rte_ethdev.h>
 
-#include <rte_fslmc.h>
-#include <fslmc_vfio.h>
-
-#define FSLMC_BUS_LOG(level, fmt, args...) \
-	RTE_LOG(level, EAL, fmt "\n", ##args)
+#include "rte_fslmc.h"
+#include "fslmc_vfio.h"
+#include "fslmc_logs.h"
 
 #define VFIO_IOMMU_GROUP_PATH "/sys/kernel/iommu_groups"
 
diff --git a/drivers/bus/fslmc/fslmc_logs.h b/drivers/bus/fslmc/fslmc_logs.h
index 1f7c24b..dbf2281 100644
--- a/drivers/bus/fslmc/fslmc_logs.h
+++ b/drivers/bus/fslmc/fslmc_logs.h
@@ -33,44 +33,12 @@
 #ifndef _FSLMC_LOGS_H_
 #define _FSLMC_LOGS_H_
 
-#define PMD_INIT_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)
+#include <rte_log.h>
 
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_INIT
-#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
-#else
-#define PMD_INIT_FUNC_TRACE() do { } while (0)
-#endif
+#define FSLMC_BUS_LOG(level, fmt, args...) \
+	RTE_LOG(level, BUS, "%s(): " fmt "\n", __func__, ##args)
 
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_RX
-#define PMD_RX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_RX_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX
-#define PMD_TX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX_FREE
-#define PMD_TX_FREE_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_TX_FREE_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
-#define PMD_DRV_LOG_RAW(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt, __func__, ## args)
-#else
-#define PMD_DRV_LOG_RAW(level, fmt, args...) do { } while (0)
-#endif
-
-#define PMD_DRV_LOG(level, fmt, args...) \
-	PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
+#define FSLMC_VFIO_LOG(level, fmt, args...) \
+	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
 
 #endif /* _FSLMC_LOGS_H_ */
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 7831201..984ff84 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -63,9 +63,7 @@
 
 #include "portal/dpaa2_hw_pvt.h"
 #include "portal/dpaa2_hw_dpio.h"
-
-#define FSLMC_VFIO_LOG(level, fmt, args...) \
-	RTE_LOG(level, EAL, fmt "\n", ##args)
+#include "fslmc_logs.h"
 
 /** Pathname of FSL-MC devices directory. */
 #define SYSFS_FSL_MC_DEVICES "/sys/bus/fsl-mc/devices"
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index b62b0a6..93cb615 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -279,6 +279,7 @@ static const struct logtype logtype_strings[] = {
 	{RTE_LOGTYPE_CRYPTODEV,  "cryptodev"},
 	{RTE_LOGTYPE_EFD,        "efd"},
 	{RTE_LOGTYPE_EVENTDEV,   "eventdev"},
+	{RTE_LOGTYPE_BUS,        "bus"},
 	{RTE_LOGTYPE_USER1,      "user1"},
 	{RTE_LOGTYPE_USER2,      "user2"},
 	{RTE_LOGTYPE_USER3,      "user3"},
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index ec8dba7..c1bb4c7 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -87,6 +87,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
+#define RTE_LOGTYPE_BUS       20 /**< Log related to bus. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v3 4/5] bus/vdev: move to vdev bus to drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (2 preceding siblings ...)
  2017-10-09  3:20   ` [PATCH v3 3/5] bus: introduce RTE_LOGTYPE_BUS for bus drivers Jianfeng Tan
@ 2017-10-09  3:20   ` Jianfeng Tan
  2017-10-09  3:20   ` [PATCH v3 5/5] bus/vdev: normalize log type Jianfeng Tan
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09  3:20 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 drivers/bus/Makefile                      |   2 +
 drivers/bus/vdev/Makefile                 |  55 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |  10 +
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 343 ++++++++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/Makefile        |   1 -
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 -----------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   1 -
 mk/rte.app.mk                             |   1 +
 13 files changed, 571 insertions(+), 499 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 22068c5..c6f2aae 100644
--- a/config/common_base
+++ b/config/common_base
@@ -754,3 +754,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 6cb6466..f93633c 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -38,4 +38,6 @@ DEPDIRS-dpaa = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..6c48ba0
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,55 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..69740c3
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,10 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+	rte_cryptodev_vdev_pmd_init
+	rte_cryptodev_vdev_parse_init_params
+};
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..8a1b00a
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,343 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 317a75e..8a3376c 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..7eeb06a 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5386d3a..8bfc343 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -166,28 +166,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -312,4 +290,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 21e0b4a..22ac5cd 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,7 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a788be2..7d31595 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -98,6 +98,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v3 5/5] bus/vdev: normalize log type
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (3 preceding siblings ...)
  2017-10-09  3:20   ` [PATCH v3 4/5] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-09  3:20   ` Jianfeng Tan
  2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (9 subsequent siblings)
  14 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09  3:20 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use RTE_LOGTYPE_BUS for logging in vdev bus.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      |  9 +++++----
 drivers/bus/vdev/vdev_logs.h | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 8a1b00a..e0ba0da 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,7 @@
 #include <rte_errno.h>
 
 #include "rte_vdev.h"
+#include "vdev_logs.h"
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +104,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -189,7 +190,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -212,7 +213,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -293,7 +294,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..09ff973
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,40 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#define VDEV_LOG(level, fmt, args...) \
+	RTE_LOG(level, BUS, "%s(): " fmt "\n", __func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v4 0/5] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (4 preceding siblings ...)
  2017-10-09  3:20   ` [PATCH v3 5/5] bus/vdev: normalize log type Jianfeng Tan
@ 2017-10-09 10:55   ` Jianfeng Tan
  2017-10-09 10:55     ` [PATCH v4 1/5] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
                       ` (5 more replies)
  2017-10-09 11:27   ` [PATCH v5 " Jianfeng Tan
                     ` (8 subsequent siblings)
  14 siblings, 6 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 10:55 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v4:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.

This patch set depends on:
  http://dpdk.org/ml/archives/dev/2017-October/077855.html

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we tend to move all bus drivers from EAL
to drivers/bus/. This patch set targets vdev bus.


Jianfeng Tan (5):
  bus/vdev: scan and probe vdev in secondary processes
  ethdev: support attach vdev in secondary process
  vhost: allocate virtio_net in memzone
  vhost: support to kick in secondary process
  net/vhost: support to run in the secondary process

 drivers/bus/vdev/vdev.c                | 104 ++++++++++++++++-
 drivers/net/vhost/rte_eth_vhost.c      | 200 ++++++++++++++++++++++++++++++---
 lib/librte_ether/rte_ethdev_vdev.h     |  26 +++--
 lib/librte_vhost/rte_vhost.h           |   3 +
 lib/librte_vhost/rte_vhost_version.map |   7 ++
 lib/librte_vhost/socket.c              |   2 +
 lib/librte_vhost/vhost.c               |  71 ++++++++++--
 lib/librte_vhost/vhost.h               |   7 +-
 lib/librte_vhost/vhost_user.c          |  17 +--
 9 files changed, 392 insertions(+), 45 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v4 1/5] bus/vdev: scan and probe vdev in secondary processes
  2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-09 10:55     ` Jianfeng Tan
  2017-10-09 10:55     ` [PATCH v4 2/5] ethdev: support attach vdev in secondary process Jianfeng Tan
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 10:55 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Base on primary/secondary communication channel, we add vdev action
to scan virtual devices in secondary processes.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 100 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index e0ba0da..1d1690f 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -104,7 +104,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +190,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			VDEV_LOG(ERR, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s", name);
 		goto fail;
 	}
 
@@ -213,7 +213,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s", name);
 		return 1;
 	}
 
@@ -252,12 +252,105 @@ rte_vdev_uninit(const char *name)
 	return 0;
 }
 
+struct vdev_action_params {
+#define VDEV_SCAN_REQUEST	1
+#define VDEV_SCAN_RESPONSE	2
+	int type;
+	char name[32];
+};
+
+static int vdev_plug(struct rte_device *dev);
+
+static int
+vdev_action(const void *params, int len,
+	    int fds[] __rte_unused,
+	    int fds_num __rte_unused)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	struct vdev_action_params ou_params;
+	const struct vdev_action_params *in_params = params;
+
+	switch (in_params->type) {
+	case VDEV_SCAN_REQUEST:
+		ou_params.type = VDEV_SCAN_RESPONSE;
+		TAILQ_FOREACH(dev, &vdev_device_list, next) {
+			VDEV_LOG(INFO, "push vdev, %s", dev->device.name);
+			strncpy(ou_params.name, dev->device.name, 32);
+			rte_eal_mp_sendmsg("vdev", &ou_params,
+							  len, NULL, 0);
+		}
+		break;
+	case VDEV_SCAN_RESPONSE:
+		VDEV_LOG(INFO, "get vdev, %s", in_params->name);
+
+		if (strlen(in_params->name) == 0) {
+			VDEV_LOG(ERR, "invalid name was passed");
+			break;
+		}
+
+		dev = find_vdev(in_params->name);
+		if (dev) {
+			VDEV_LOG(ERR, "vdev already exists: %s", in_params->name);
+			break;
+		}
+
+		devargs = alloc_devargs(in_params->name, NULL);
+		if (!devargs) {
+			VDEV_LOG(ERR, "failed to allocate memory");
+			break;
+		}
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev) {
+			VDEV_LOG(ERR, "failed to allocate memory");
+			free(devargs);
+			break;
+		}
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = 0; /* to be corrected in probe() */
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+
+		if (vdev_plug(&dev->device) < 0) {
+			VDEV_LOG(ERR, "failed to plug device %s", in_params->name);
+			free(devargs);
+			free(dev);
+		} else
+			VDEV_LOG(INFO, "plug in device: %s", in_params->name);
+
+		break;
+	default:
+		VDEV_LOG(ERR, "vdev cannot recognize this message");
+	}
+
+	return 0;
+}
+
 static int
 vdev_scan(void)
 {
 	struct rte_vdev_device *dev;
 	struct rte_devargs *devargs;
 
+	if (rte_eal_mp_action_register("vdev", vdev_action) < 0) {
+		VDEV_LOG(ERR, "vdev fails to add action");
+		return -1;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		struct vdev_action_params params;
+
+		params.type = VDEV_SCAN_REQUEST;
+		rte_eal_mp_sendmsg("vdev", &params,
+						  sizeof(params), NULL, 0);
+
+		return 0;
+	}
+
 	/* for virtual devices we scan the devargs_list populated via cmdline */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
 
@@ -287,6 +380,9 @@ vdev_probe(void)
 {
 	struct rte_vdev_device *dev;
 
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return 0;
+
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(dev, &vdev_device_list, next) {
 
@@ -294,7 +390,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			VDEV_LOG(ERR, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v4 2/5] ethdev: support attach vdev in secondary process
  2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
  2017-10-09 10:55     ` [PATCH v4 1/5] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
@ 2017-10-09 10:55     ` Jianfeng Tan
  2017-10-09 10:55     ` [PATCH v4 3/5] vhost: allocate virtio_net in memzone Jianfeng Tan
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 10:55 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

When vdev driver requests an ethdev entry in secondary process,
we will identify the correct entry in rte_eth_dev_data array
and return the correct entry in the rte_eth_devices arrays.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev_vdev.h | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev_vdev.h b/lib/librte_ether/rte_ethdev_vdev.h
index 4d2c3e2..460749b 100644
--- a/lib/librte_ether/rte_ethdev_vdev.h
+++ b/lib/librte_ether/rte_ethdev_vdev.h
@@ -58,25 +58,29 @@ rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size)
 	struct rte_eth_dev *eth_dev;
 	const char *name = rte_vdev_device_name(dev);
 
-	eth_dev = rte_eth_dev_allocate(name);
-	if (!eth_dev)
-		return NULL;
-
-	if (private_data_size) {
-		eth_dev->data->dev_private = rte_zmalloc_socket(name,
-			private_data_size, RTE_CACHE_LINE_SIZE,
-			dev->device.numa_node);
-		if (!eth_dev->data->dev_private) {
-			rte_eth_dev_release_port(eth_dev);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev = rte_eth_dev_allocate(name);
+		if (!eth_dev)
 			return NULL;
+
+		if (private_data_size) {
+			eth_dev->data->dev_private = rte_zmalloc_socket(name,
+					private_data_size, RTE_CACHE_LINE_SIZE,
+					dev->device.numa_node);
+			if (!eth_dev->data->dev_private) {
+				rte_eth_dev_release_port(eth_dev);
+				return NULL;
+			}
 		}
+	} else {
+		eth_dev = rte_eth_dev_attach_secondary(name);
 	}
 
 	eth_dev->device = &dev->device;
 	eth_dev->intr_handle = NULL;
-
 	eth_dev->data->kdrv = RTE_KDRV_NONE;
 	eth_dev->data->numa_node = dev->device.numa_node;
+
 	return eth_dev;
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v4 3/5] vhost: allocate virtio_net in memzone
  2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
  2017-10-09 10:55     ` [PATCH v4 1/5] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
  2017-10-09 10:55     ` [PATCH v4 2/5] ethdev: support attach vdev in secondary process Jianfeng Tan
@ 2017-10-09 10:55     ` Jianfeng Tan
  2017-10-09 10:55     ` [PATCH v4 4/5] vhost: support to kick in secondary process Jianfeng Tan
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 10:55 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Instead of allocate on the stack, change to allocate in memzone
so that we can retrieve them in secondary processes.

TODO: numa awareness.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_vhost/socket.c |  2 ++
 lib/librte_vhost/vhost.c  | 34 ++++++++++++++++++++++++++++++++--
 lib/librte_vhost/vhost.h  |  4 +++-
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 41aa3f9..35b9751 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -606,6 +606,8 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
 	int ret = -1;
 	struct vhost_user_socket *vsocket;
 
+	alloc_vhost_devices();
+
 	if (!path)
 		return -1;
 
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 0b6aa1c..2b687ea 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -47,15 +47,45 @@
 #include <rte_memory.h>
 #include <rte_malloc.h>
 #include <rte_vhost.h>
+#include <rte_memzone.h>
 
 #include "vhost.h"
 
-struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+#define MZ_VHOST_DEVICES "mz_vhost_devices"
+struct virtio_net **vhost_devices;
+
+void
+alloc_vhost_devices(void)
+{
+	const struct rte_memzone *mz;
+
+	if (vhost_devices != NULL)
+		return;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		mz = rte_memzone_reserve(MZ_VHOST_DEVICES,
+				MAX_VHOST_DEVICE * sizeof(*vhost_devices),
+				rte_socket_id(), 0);
+	} else
+		mz = rte_memzone_lookup(MZ_VHOST_DEVICES);
+
+	if (mz == NULL)
+		rte_panic("Cannot allocate memzone for vhost_devices\n");
+
+	vhost_devices = mz->addr;
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		memset(vhost_devices, 0,
+		       MAX_VHOST_DEVICE * sizeof(*vhost_devices));
+}
 
 struct virtio_net *
 get_device(int vid)
 {
-	struct virtio_net *dev = vhost_devices[vid];
+	struct virtio_net *dev;
+
+	alloc_vhost_devices();
+
+	dev = vhost_devices[vid];
 
 	if (unlikely(!dev)) {
 		RTE_LOG(ERR, VHOST_CONFIG,
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 6fe72ae..bc1f31e 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -278,7 +278,7 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
 
 extern uint64_t VHOST_FEATURES;
 #define MAX_VHOST_DEVICE	1024
-extern struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+extern struct virtio_net **vhost_devices;
 
 /* Convert guest physical address to host physical address */
 static __rte_always_inline phys_addr_t
@@ -300,6 +300,8 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size)
 	return 0;
 }
 
+
+void alloc_vhost_devices(void);
 struct virtio_net *get_device(int vid);
 
 int vhost_new_device(void);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v4 4/5] vhost: support to kick in secondary process
  2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-09 10:55     ` [PATCH v4 3/5] vhost: allocate virtio_net in memzone Jianfeng Tan
@ 2017-10-09 10:55     ` Jianfeng Tan
  2017-10-09 10:55     ` [PATCH v4 5/5] net/vhost: support to run in the " Jianfeng Tan
  2017-10-09 11:08     ` [PATCH v4 0/5] move vdev into drivers/bus Tan, Jianfeng
  5 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 10:55 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

To support kick in secondary process, we propose callfd_pri and
kickfd_pri to store the value in primary process; and by a new
API, rte_vhost_set_vring_effective_fd(), we can set effective
callfd and kickfd which can be used by secondary process.

Note in this case, either primary process or the secondary process
can kick the frontend; that is, they cannot kick a vring at the
same time.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_vhost/rte_vhost.h           |  3 +++
 lib/librte_vhost/rte_vhost_version.map |  7 +++++++
 lib/librte_vhost/vhost.c               | 37 ++++++++++++++++++++++++++++------
 lib/librte_vhost/vhost.h               |  3 +++
 lib/librte_vhost/vhost_user.c          | 17 ++++++++--------
 5 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 8c974eb..c82f249 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -432,6 +432,9 @@ int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 			      struct rte_vhost_vring *vring);
 
+int rte_vhost_set_vring_effective_fd(int vid, uint16_t vring_idx,
+				     int callfd, int kickfd);
+
 /**
  * Get vhost RX queue avail count.
  *
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 1e70495..02142df 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -52,3 +52,10 @@ DPDK_17.08 {
 	rte_vhost_rx_queue_count;
 
 } DPDK_17.05;
+
+DPDK_17.11 {
+	global:
+
+	rte_vhost_set_vring_effective_fd;
+
+} DPDK_17.08;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 2b687ea..11a3db1 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -98,10 +98,10 @@ get_device(int vid)
 static void
 cleanup_vq(struct vhost_virtqueue *vq, int destroy)
 {
-	if ((vq->callfd >= 0) && (destroy != 0))
-		close(vq->callfd);
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
+	if ((vq->callfd_pri >= 0) && (destroy != 0))
+		close(vq->callfd_pri);
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
 }
 
 /*
@@ -146,6 +146,8 @@ init_vring_queue(struct vhost_virtqueue *vq)
 
 	vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
 	vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->kickfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->callfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
 
 	/* Backends are set to -1 indicating an inactive device. */
 	vq->backend = -1;
@@ -435,13 +437,36 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 	vring->used  = vq->used;
 	vring->log_guest_addr  = vq->log_guest_addr;
 
-	vring->callfd  = vq->callfd;
-	vring->kickfd  = vq->kickfd;
+	vring->callfd  = vq->callfd_pri;
+	vring->kickfd  = vq->kickfd_pri;
 	vring->size    = vq->size;
 
 	return 0;
 }
 
+int
+rte_vhost_set_vring_effective_fd(int vid, uint16_t vring_idx,
+				 int callfd, int kickfd)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (!dev)
+		return -1;
+
+	if (vring_idx >= VHOST_MAX_VRING)
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (!vq)
+		return -1;
+
+	vq->callfd = callfd;
+	vq->kickfd = kickfd;
+
+	return 0;
+}
 uint16_t
 rte_vhost_avail_entries(int vid, uint16_t queue_id)
 {
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index bc1f31e..be57c52 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -98,9 +98,12 @@ struct vhost_virtqueue {
 	/* Backend value to determine if device should started/stopped */
 	int			backend;
 	/* Used to notify the guest (trigger interrupt) */
+	int			callfd_pri;
 	int			callfd;
 	/* Currently unused as polling mode is enabled */
+	int			kickfd_pri;
 	int			kickfd;
+
 	int			enabled;
 
 	/* Physical address of used ring, for logging */
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index ad2e8d3..3d1eea4 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -661,10 +661,10 @@ vhost_user_set_vring_call(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 		"vring call idx:%d file:%d\n", file.index, file.fd);
 
 	vq = dev->virtqueue[file.index];
-	if (vq->callfd >= 0)
-		close(vq->callfd);
+	if (vq->callfd_pri >= 0)
+		close(vq->callfd_pri);
 
-	vq->callfd = file.fd;
+	vq->callfd_pri = vq->callfd = file.fd;
 }
 
 static void
@@ -682,9 +682,9 @@ vhost_user_set_vring_kick(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 		"vring kick idx:%d file:%d\n", file.index, file.fd);
 
 	vq = dev->virtqueue[file.index];
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
-	vq->kickfd = file.fd;
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
+	vq->kickfd_pri = vq->kickfd = file.fd;
 }
 
 static void
@@ -731,10 +731,11 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 	 * sent and only sent in vhost_vring_stop.
 	 * TODO: cleanup the vring, it isn't usable since here.
 	 */
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
 
 	vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->kickfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
 
 	if (dev->dequeue_zero_copy)
 		free_zmbufs(vq);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v4 5/5] net/vhost: support to run in the secondary process
  2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
                       ` (3 preceding siblings ...)
  2017-10-09 10:55     ` [PATCH v4 4/5] vhost: support to kick in secondary process Jianfeng Tan
@ 2017-10-09 10:55     ` Jianfeng Tan
  2017-10-09 11:08     ` [PATCH v4 0/5] move vdev into drivers/bus Tan, Jianfeng
  5 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 10:55 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Support to run vhost-pmd vdev in the secondary process. We obtain
information, like memory regions, kickfd, callfd, through
primary/secondary communication channel.

And by invoking rte_vhost_set_vring_effective_fd, we can set the
kickfd which can be recognized by the secondary process.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vhost/rte_eth_vhost.c | 200 +++++++++++++++++++++++++++++++++++---
 1 file changed, 187 insertions(+), 13 deletions(-)

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 04179b4..9d296aa 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -33,6 +33,7 @@
 #include <unistd.h>
 #include <pthread.h>
 #include <stdbool.h>
+#include <sys/mman.h>
 
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
@@ -46,6 +47,20 @@
 
 #include "rte_eth_vhost.h"
 
+#define VHOST_MSG_TYPE_REGIONS	1
+#define VHOST_MSG_TYPE_SET_FDS	2
+#define VHOST_MSG_TYPE_INIT	3
+
+struct vhost_params {
+	int type;
+	union {
+		int vid;
+		int portid;
+	};
+	int vring_idx;
+	struct rte_vhost_mem_region regions[0];
+};
+
 enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM};
 
 #define ETH_VHOST_IFACE_ARG		"iface"
@@ -550,6 +565,66 @@ update_queuing_status(struct rte_eth_dev *dev)
 }
 
 static int
+share_device(int vid)
+{
+	uint32_t i, vring_num;
+	int len;
+	int fds[8];
+	struct rte_vhost_memory *mem;
+	struct vhost_params *params;
+	struct rte_vhost_vring vring;
+
+	/* share mem table */
+	if (rte_vhost_get_mem_table(vid, &mem) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to get mem table\n");
+		return 0;
+	}
+	for (i = 0; i < mem->nregions; ++i)
+		fds[i] = mem->regions[i].fd;
+
+	len = sizeof(struct rte_vhost_mem_region) * mem->nregions;
+	params = malloc(sizeof(*params) + len);
+	if (params == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to allocate memory\n");
+		return -1;
+	}
+
+	params->type = VHOST_MSG_TYPE_REGIONS;
+	params->vid = vid;
+	memcpy(params->regions, mem->regions, len);
+
+	if (rte_eal_mp_sendmsg("vhost pmd", params, sizeof(*params) + len,
+			       fds, mem->nregions) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to share mem table\n");
+		free(params);
+		return -1;
+	}
+
+	/* share callfd and kickfd */
+	params->type = VHOST_MSG_TYPE_SET_FDS;
+	vring_num = rte_vhost_get_vring_num(vid);
+	for (i = 0; i < vring_num; i++) {
+		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
+			RTE_LOG(ERR, PMD, "Failed to get vring, idx = %d\n", i);
+			free(params);
+			return -1;
+		}
+
+		params->vring_idx = i;
+		fds[0] = vring.callfd;
+		fds[1] = vring.kickfd;
+		if (rte_eal_mp_sendmsg("vhost pmd", params,
+				       sizeof(*params), fds, 2) < 0) {
+			RTE_LOG(ERR, PMD, "Failed to set fds\n");
+			return -1;
+		}
+	}
+
+	free(params);
+	return 0;
+}
+
+static int
 new_device(int vid)
 {
 	struct rte_eth_dev *eth_dev;
@@ -610,6 +685,8 @@ new_device(int vid)
 	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
 				      NULL, NULL);
 
+	share_device(vid);
+
 	return 0;
 }
 
@@ -1025,13 +1102,6 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	RTE_LOG(INFO, PMD, "Creating VHOST-USER backend on numa socket %u\n",
 		numa_node);
 
-	/* now do all data allocation - for eth_dev structure and internal
-	 * (private) data
-	 */
-	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
-	if (data == NULL)
-		goto error;
-
 	list = rte_zmalloc_socket(name, sizeof(*list), 0, numa_node);
 	if (list == NULL)
 		goto error;
@@ -1073,11 +1143,7 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	rte_spinlock_init(&vring_state->lock);
 	vring_states[eth_dev->data->port_id] = vring_state;
 
-	/* We'll replace the 'data' originally allocated by eth_dev. So the
-	 * vhost PMD resources won't be shared between multi processes.
-	 */
-	rte_memcpy(data, eth_dev->data, sizeof(*data));
-	eth_dev->data = data;
+	data = eth_dev->data;
 
 	data->nb_rx_queues = queues;
 	data->nb_tx_queues = queues;
@@ -1125,6 +1191,30 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	return -1;
 }
 
+static int
+eth_dev_vhost_attach(struct rte_vdev_device *dev)
+{
+	struct rte_eth_dev *eth_dev = NULL;
+	struct rte_eth_dev_data *data = NULL;
+
+	RTE_LOG(INFO, PMD, "Attach vhost user port\n");
+
+	/* reserve an ethdev entry */
+	eth_dev = rte_eth_vdev_allocate(dev, sizeof(struct pmd_internal));
+	if (eth_dev == NULL)
+		return -1;
+
+	eth_dev->dev_ops = &ops;
+
+	/* finally assign rx and tx ops */
+	eth_dev->rx_pkt_burst = eth_vhost_rx;
+	eth_dev->tx_pkt_burst = eth_vhost_tx;
+
+	data = eth_dev->data;
+
+	return data->port_id;
+}
+
 static inline int
 open_iface(const char *key __rte_unused, const char *value, void *extra_args)
 {
@@ -1154,10 +1244,84 @@ open_int(const char *key __rte_unused, const char *value, void *extra_args)
 }
 
 static int
+vhost_pmd_action(const void *params, int len, int fds[], int fds_num)
+{
+	int i;
+	int vid;
+	void *base_addr;
+	const struct vhost_params *p = params;
+	const struct rte_vhost_mem_region *regions;
+
+	if (len < (int)sizeof(*p)) {
+		RTE_LOG(ERR, PMD, "message if too short\n");
+		return -1;
+	}
+
+	switch (p->type) {
+	case VHOST_MSG_TYPE_REGIONS:
+		regions = p->regions;
+		for (i = 0; i < fds_num; ++i) {
+			base_addr = mmap(regions[i].mmap_addr,
+					 regions[i].mmap_size,
+					 PROT_READ | PROT_WRITE,
+					 MAP_FIXED | MAP_SHARED, fds[i], 0);
+			if (base_addr != regions[i].mmap_addr) {
+				RTE_LOG(ERR, PMD,
+					"vhost in secondary mmap error: %s\n",
+					strerror(errno));
+				break;
+			}
+		}
+		break;
+	case VHOST_MSG_TYPE_SET_FDS:
+		rte_vhost_set_vring_effective_fd(p->vid,
+						 p->vring_idx,
+						 fds[0], fds[1]);
+		break;
+	case VHOST_MSG_TYPE_INIT:
+		vid = rte_eth_vhost_get_vid_from_port_id(p->portid);
+		share_device(vid);
+		break;
+	}
+
+	return 0;
+}
+
+static int
+probe_secondary(struct rte_vdev_device *dev)
+{
+	int portid = eth_dev_vhost_attach(dev);
+	struct rte_eth_dev *eth_dev;
+	struct pmd_internal *internal;
+	struct vhost_params p;
+
+	if (portid < 0)
+		return -1;
+
+	eth_dev = &rte_eth_devices[portid];
+	internal = eth_dev->data->dev_private;
+
+	if (!internal ||
+	    rte_atomic32_read(&internal->dev_attached) == 0) {
+		RTE_LOG(INFO, PMD, "%s is not ready\n", dev->device.name);
+		return 0;
+	}
+
+	p.type = VHOST_MSG_TYPE_INIT;
+	p.portid = portid;
+	if (rte_eal_mp_sendmsg("vhost pmd", &p, sizeof(p), NULL, 0) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to send request for init\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
 rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 {
 	struct rte_kvargs *kvlist = NULL;
-	int ret = 0;
+	int ret;
 	char *iface_name;
 	uint16_t queues;
 	uint64_t flags = 0;
@@ -1167,6 +1331,15 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 	RTE_LOG(INFO, PMD, "Initializing pmd_vhost for %s\n",
 		rte_vdev_device_name(dev));
 
+	ret = rte_eal_mp_action_register("vhost pmd", vhost_pmd_action);
+	if (ret < 0 && ret != -EEXIST) {
+		RTE_LOG(ERR, PMD, "vhost fails to add action\n");
+		return -1;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return probe_secondary(dev);
+
 	kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_arguments);
 	if (kvlist == NULL)
 		return -1;
@@ -1216,6 +1389,7 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 	eth_dev_vhost_create(dev, iface_name, queues, dev->device.numa_node,
 		flags);
 
+	ret = 0;
 out_free:
 	rte_kvargs_free(kvlist);
 	return ret;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v4 0/5] move vdev into drivers/bus
  2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
                       ` (4 preceding siblings ...)
  2017-10-09 10:55     ` [PATCH v4 5/5] net/vhost: support to run in the " Jianfeng Tan
@ 2017-10-09 11:08     ` Tan, Jianfeng
  5 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-09 11:08 UTC (permalink / raw)
  To: dev
  Cc: jblunck, Richardson, Bruce, Ananyev, Konstantin, De Lara Guarch,
	Pablo, thomas, yliu, maxime.coquelin, mtetsuyah, Yigit, Ferruh

Apologize! Just found I sent out the wrong patches. Please ignore this series.

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Monday, October 9, 2017 6:55 PM
> To: dev@dpdk.org
> Cc: jblunck@infradead.org; Richardson, Bruce; Ananyev, Konstantin; De Lara
> Guarch, Pablo; thomas@monjalon.net; yliu@fridaylinux.org;
> maxime.coquelin@redhat.com; mtetsuyah@gmail.com; Yigit, Ferruh; Tan,
> Jianfeng
> Subject: [PATCH v4 0/5] move vdev into drivers/bus
> 
> v4:
>   - Fix issues of compiling shared library.
>   - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
> 
> This patch set depends on:
>   http://dpdk.org/ml/archives/dev/2017-October/077855.html
> 
> This patch set is originated from below series:
>   http://dpdk.org/ml/archives/dev/2017-September/076821.html
> 
> As per previous discussions, we tend to move all bus drivers from EAL
> to drivers/bus/. This patch set targets vdev bus.
> 
> 
> Jianfeng Tan (5):
>   bus/vdev: scan and probe vdev in secondary processes
>   ethdev: support attach vdev in secondary process
>   vhost: allocate virtio_net in memzone
>   vhost: support to kick in secondary process
>   net/vhost: support to run in the secondary process
> 
>  drivers/bus/vdev/vdev.c                | 104 ++++++++++++++++-
>  drivers/net/vhost/rte_eth_vhost.c      | 200
> ++++++++++++++++++++++++++++++---
>  lib/librte_ether/rte_ethdev_vdev.h     |  26 +++--
>  lib/librte_vhost/rte_vhost.h           |   3 +
>  lib/librte_vhost/rte_vhost_version.map |   7 ++
>  lib/librte_vhost/socket.c              |   2 +
>  lib/librte_vhost/vhost.c               |  71 ++++++++++--
>  lib/librte_vhost/vhost.h               |   7 +-
>  lib/librte_vhost/vhost_user.c          |  17 +--
>  9 files changed, 392 insertions(+), 45 deletions(-)
> 
> --
> 2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v5 0/5] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (5 preceding siblings ...)
  2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-09 11:27   ` Jianfeng Tan
  2017-10-09 11:27     ` [PATCH v5 1/5] cryptodev: remove crypto vdev init API Jianfeng Tan
                       ` (4 more replies)
  2017-10-12  8:46   ` [PATCH v6 0/4] move vdev into drivers/bus Jianfeng Tan
                     ` (7 subsequent siblings)
  14 siblings, 5 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 11:27 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set depends on:
  http://dpdk.org/ml/archives/dev/2017-October/077855.html

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we tend to move all bus drivers from EAL
to drivers/bus/. This patch set targets vdev bus.

Jianfeng Tan (5):
  cryptodev: remove crypto vdev init API
  eal: remove dependency on vdev
  bus: introduce new log type for bus drivers
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: normalize log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 drivers/bus/Makefile                           |   3 +
 drivers/bus/fslmc/fslmc_bus.c                  |   9 +-
 drivers/bus/fslmc/fslmc_logs.h                 |  42 +--
 drivers/bus/fslmc/fslmc_vfio.c                 |   4 +-
 drivers/bus/vdev/Makefile                      |  55 ++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |   8 +
 drivers/bus/vdev/rte_vdev.h                    | 153 +++++++++++
 drivers/bus/vdev/vdev.c                        | 345 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  40 +++
 drivers/crypto/Makefile                        |   1 +
 drivers/event/Makefile                         |   2 +-
 drivers/net/Makefile                           |   2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   1 -
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  22 +-
 lib/librte_eal/common/eal_common_log.c         |   1 +
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_log.h        |   1 +
 lib/librte_eal/common/include/rte_vdev.h       | 131 ----------
 lib/librte_eal/linuxapp/eal/Makefile           |   1 -
 mk/rte.app.mk                                  |   1 +
 27 files changed, 632 insertions(+), 592 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v5 1/5] cryptodev: remove crypto vdev init API
  2017-10-09 11:27   ` [PATCH v5 " Jianfeng Tan
@ 2017-10-09 11:27     ` Jianfeng Tan
  2017-10-09 11:27     ` [PATCH v5 2/5] eal: remove dependency on vdev Jianfeng Tan
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 11:27 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 4 files changed, 29 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index f4269f0..85a9287 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -78,11 +78,6 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * cryptodev: the following function will be static in 17.11 and included
   by all crypto drivers, therefore, will not be public:
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 5e8f7f4..f2c55cc 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index ad97ff9..c5d6939 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -433,23 +433,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index abdbbda..b07f4ca 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v5 2/5] eal: remove dependency on vdev
  2017-10-09 11:27   ` [PATCH v5 " Jianfeng Tan
  2017-10-09 11:27     ` [PATCH v5 1/5] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-09 11:27     ` Jianfeng Tan
  2017-10-09 11:27     ` [PATCH v5 3/5] bus: introduce new log type for bus drivers Jianfeng Tan
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 11:27 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..dda8f58 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,13 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL,
+		"Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v5 3/5] bus: introduce new log type for bus drivers
  2017-10-09 11:27   ` [PATCH v5 " Jianfeng Tan
  2017-10-09 11:27     ` [PATCH v5 1/5] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-10-09 11:27     ` [PATCH v5 2/5] eal: remove dependency on vdev Jianfeng Tan
@ 2017-10-09 11:27     ` Jianfeng Tan
  2017-10-11  6:54       ` Shreyansh Jain
  2017-10-09 11:27     ` [PATCH v5 4/5] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
  2017-10-09 11:27     ` [PATCH v5 5/5] bus/vdev: normalize log type Jianfeng Tan
  4 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 11:27 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Introduce a new log type, RTE_LOGTYPE_BUS, for bus drivers. And
change fslmc to use this type for logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/fslmc/fslmc_bus.c           |  9 +++----
 drivers/bus/fslmc/fslmc_logs.h          | 42 ++++-----------------------------
 drivers/bus/fslmc/fslmc_vfio.c          |  4 +---
 lib/librte_eal/common/eal_common_log.c  |  1 +
 lib/librte_eal/common/include/rte_log.h |  1 +
 5 files changed, 11 insertions(+), 46 deletions(-)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 0a8229f..236ec3a 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -34,7 +34,6 @@
 #include <dirent.h>
 #include <stdbool.h>
 
-#include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
@@ -42,11 +41,9 @@
 #include <rte_memcpy.h>
 #include <rte_ethdev.h>
 
-#include <rte_fslmc.h>
-#include <fslmc_vfio.h>
-
-#define FSLMC_BUS_LOG(level, fmt, args...) \
-	RTE_LOG(level, EAL, fmt "\n", ##args)
+#include "rte_fslmc.h"
+#include "fslmc_vfio.h"
+#include "fslmc_logs.h"
 
 #define VFIO_IOMMU_GROUP_PATH "/sys/kernel/iommu_groups"
 
diff --git a/drivers/bus/fslmc/fslmc_logs.h b/drivers/bus/fslmc/fslmc_logs.h
index 1f7c24b..dbf2281 100644
--- a/drivers/bus/fslmc/fslmc_logs.h
+++ b/drivers/bus/fslmc/fslmc_logs.h
@@ -33,44 +33,12 @@
 #ifndef _FSLMC_LOGS_H_
 #define _FSLMC_LOGS_H_
 
-#define PMD_INIT_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)
+#include <rte_log.h>
 
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_INIT
-#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
-#else
-#define PMD_INIT_FUNC_TRACE() do { } while (0)
-#endif
+#define FSLMC_BUS_LOG(level, fmt, args...) \
+	RTE_LOG(level, BUS, "%s(): " fmt "\n", __func__, ##args)
 
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_RX
-#define PMD_RX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_RX_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX
-#define PMD_TX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX_FREE
-#define PMD_TX_FREE_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#else
-#define PMD_TX_FREE_LOG(level, fmt, args...) do { } while (0)
-#endif
-
-#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
-#define PMD_DRV_LOG_RAW(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt, __func__, ## args)
-#else
-#define PMD_DRV_LOG_RAW(level, fmt, args...) do { } while (0)
-#endif
-
-#define PMD_DRV_LOG(level, fmt, args...) \
-	PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
+#define FSLMC_VFIO_LOG(level, fmt, args...) \
+	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
 
 #endif /* _FSLMC_LOGS_H_ */
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 7831201..984ff84 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -63,9 +63,7 @@
 
 #include "portal/dpaa2_hw_pvt.h"
 #include "portal/dpaa2_hw_dpio.h"
-
-#define FSLMC_VFIO_LOG(level, fmt, args...) \
-	RTE_LOG(level, EAL, fmt "\n", ##args)
+#include "fslmc_logs.h"
 
 /** Pathname of FSL-MC devices directory. */
 #define SYSFS_FSL_MC_DEVICES "/sys/bus/fsl-mc/devices"
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index b62b0a6..93cb615 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -279,6 +279,7 @@ static const struct logtype logtype_strings[] = {
 	{RTE_LOGTYPE_CRYPTODEV,  "cryptodev"},
 	{RTE_LOGTYPE_EFD,        "efd"},
 	{RTE_LOGTYPE_EVENTDEV,   "eventdev"},
+	{RTE_LOGTYPE_BUS,        "bus"},
 	{RTE_LOGTYPE_USER1,      "user1"},
 	{RTE_LOGTYPE_USER2,      "user2"},
 	{RTE_LOGTYPE_USER3,      "user3"},
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index ec8dba7..c1bb4c7 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -87,6 +87,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
+#define RTE_LOGTYPE_BUS       20 /**< Log related to bus. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v5 4/5] bus/vdev: move to vdev bus to drivers/bus
  2017-10-09 11:27   ` [PATCH v5 " Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-09 11:27     ` [PATCH v5 3/5] bus: introduce new log type for bus drivers Jianfeng Tan
@ 2017-10-09 11:27     ` Jianfeng Tan
  2017-10-09 11:27     ` [PATCH v5 5/5] bus/vdev: normalize log type Jianfeng Tan
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 11:27 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 drivers/bus/Makefile                      |   3 +
 drivers/bus/vdev/Makefile                 |  55 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |   8 +
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 344 ++++++++++++++++++++++++++++++
 drivers/crypto/Makefile                   |   1 +
 drivers/event/Makefile                    |   2 +-
 drivers/net/Makefile                      |   2 +-
 lib/librte_eal/bsdapp/eal/Makefile        |   1 -
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 -----------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   1 -
 mk/rte.app.mk                             |   1 +
 16 files changed, 574 insertions(+), 501 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 22068c5..c6f2aae 100644
--- a/config/common_base
+++ b/config/common_base
@@ -754,3 +754,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 6cb6466..91ffa87 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -38,4 +38,7 @@ DEPDIRS-dpaa = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+DEPDIRS-vdev = $(core-libs)
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..6c48ba0
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,55 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..6ccb789
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+};
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..a16eb71
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,344 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7a719b9..e487f6c 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
+core-libs += librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DEPDIRS-aesni_gcm = $(core-libs)
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
index 3f6b898..ceedf70 100644
--- a/drivers/event/Makefile
+++ b/drivers/event/Makefile
@@ -31,7 +31,7 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_eventdev
+core-libs := librte_eal librte_eventdev librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV) += skeleton
 DEPDIRS-skeleton = $(core-libs)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b28310b..1039d4e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -37,7 +37,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD),d)
 endif
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-core-libs += librte_net librte_kvargs
+core-libs += librte_net librte_kvargs librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DEPDIRS-af_packet = $(core-libs)
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 317a75e..8a3376c 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..7eeb06a 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5386d3a..8bfc343 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -166,28 +166,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -312,4 +290,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 21e0b4a..22ac5cd 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,7 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a788be2..7d31595 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -98,6 +98,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v5 5/5] bus/vdev: normalize log type
  2017-10-09 11:27   ` [PATCH v5 " Jianfeng Tan
                       ` (3 preceding siblings ...)
  2017-10-09 11:27     ` [PATCH v5 4/5] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-09 11:27     ` Jianfeng Tan
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-09 11:27 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use RTE_LOGTYPE_BUS for logging in vdev bus.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      |  9 +++++----
 drivers/bus/vdev/vdev_logs.h | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index a16eb71..8eccdd5 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,7 @@
 #include <rte_errno.h>
 
 #include "rte_vdev.h"
+#include "vdev_logs.h"
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +104,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +191,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -213,7 +214,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -294,7 +295,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..09ff973
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,40 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#define VDEV_LOG(level, fmt, args...) \
+	RTE_LOG(level, BUS, "%s(): " fmt "\n", __func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v5 3/5] bus: introduce new log type for bus drivers
  2017-10-09 11:27     ` [PATCH v5 3/5] bus: introduce new log type for bus drivers Jianfeng Tan
@ 2017-10-11  6:54       ` Shreyansh Jain
  2017-10-11 10:42         ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Shreyansh Jain @ 2017-10-11  6:54 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit

Hello Jianfeng,

On Monday 09 October 2017 04:57 PM, Jianfeng Tan wrote:
> Introduce a new log type, RTE_LOGTYPE_BUS, for bus drivers. And
> change fslmc to use this type for logging.
> 
> Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>   drivers/bus/fslmc/fslmc_bus.c           |  9 +++----
>   drivers/bus/fslmc/fslmc_logs.h          | 42 ++++-----------------------------
>   drivers/bus/fslmc/fslmc_vfio.c          |  4 +---
>   lib/librte_eal/common/eal_common_log.c  |  1 +
>   lib/librte_eal/common/include/rte_log.h |  1 +
>   5 files changed, 11 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
> index 0a8229f..236ec3a 100644
> --- a/drivers/bus/fslmc/fslmc_bus.c
> +++ b/drivers/bus/fslmc/fslmc_bus.c
> @@ -34,7 +34,6 @@
>   #include <dirent.h>
>   #include <stdbool.h>
>   
> -#include <rte_log.h>
>   #include <rte_bus.h>
>   #include <rte_eal_memconfig.h>
>   #include <rte_malloc.h>
> @@ -42,11 +41,9 @@
>   #include <rte_memcpy.h>
>   #include <rte_ethdev.h>
>   
> -#include <rte_fslmc.h>
> -#include <fslmc_vfio.h>
> -
> -#define FSLMC_BUS_LOG(level, fmt, args...) \
> -	RTE_LOG(level, EAL, fmt "\n", ##args)
> +#include "rte_fslmc.h"
> +#include "fslmc_vfio.h"
> +#include "fslmc_logs.h"
>   
>   #define VFIO_IOMMU_GROUP_PATH "/sys/kernel/iommu_groups"
>   
> diff --git a/drivers/bus/fslmc/fslmc_logs.h b/drivers/bus/fslmc/fslmc_logs.h
> index 1f7c24b..dbf2281 100644
> --- a/drivers/bus/fslmc/fslmc_logs.h
> +++ b/drivers/bus/fslmc/fslmc_logs.h
> @@ -33,44 +33,12 @@
>   #ifndef _FSLMC_LOGS_H_
>   #define _FSLMC_LOGS_H_
>   
> -#define PMD_INIT_LOG(level, fmt, args...) \
> -	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)
> +#include <rte_log.h>
>   
> -#ifdef RTE_LIBRTE_DPAA2_DEBUG_INIT
> -#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
> -#else
> -#define PMD_INIT_FUNC_TRACE() do { } while (0)
> -#endif
> +#define FSLMC_BUS_LOG(level, fmt, args...) \
> +	RTE_LOG(level, BUS, "%s(): " fmt "\n", __func__, ##args)
>   
> -#ifdef RTE_LIBRTE_DPAA2_DEBUG_RX
> -#define PMD_RX_LOG(level, fmt, args...) \
> -	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
> -#else
> -#define PMD_RX_LOG(level, fmt, args...) do { } while (0)
> -#endif
> -
> -#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX
> -#define PMD_TX_LOG(level, fmt, args...) \
> -	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
> -#else
> -#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
> -#endif
> -
> -#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX_FREE
> -#define PMD_TX_FREE_LOG(level, fmt, args...) \
> -	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
> -#else
> -#define PMD_TX_FREE_LOG(level, fmt, args...) do { } while (0)
> -#endif
> -
> -#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
> -#define PMD_DRV_LOG_RAW(level, fmt, args...) \
> -	RTE_LOG(level, PMD, "%s(): " fmt, __func__, ## args)
> -#else
> -#define PMD_DRV_LOG_RAW(level, fmt, args...) do { } while (0)
> -#endif
> -
> -#define PMD_DRV_LOG(level, fmt, args...) \
> -	PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
> +#define FSLMC_VFIO_LOG(level, fmt, args...) \
> +	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)

This change breaks the FSLMC bus driver. There are macros like 
PMD_DRV_LOG which are still in use in the code.
Before removing the above, those would have to be restructured.

I am already working on converting this logging into dynamic logging.
Can you skip this work until then? Does it block your work?

>   
>   #endif /* _FSLMC_LOGS_H_ */

<snip>

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v5 3/5] bus: introduce new log type for bus drivers
  2017-10-11  6:54       ` Shreyansh Jain
@ 2017-10-11 10:42         ` Tan, Jianfeng
  2017-10-11 11:20           ` Shreyansh Jain
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-11 10:42 UTC (permalink / raw)
  To: Shreyansh Jain
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit



On 10/11/2017 2:54 PM, Shreyansh Jain wrote:
> Hello Jianfeng,
>
> On Monday 09 October 2017 04:57 PM, Jianfeng Tan wrote:
>>
[...]
>> -#define PMD_DRV_LOG(level, fmt, args...) \
>> -    PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
>> +#define FSLMC_VFIO_LOG(level, fmt, args...) \
>> +    RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
>
> This change breaks the FSLMC bus driver. There are macros like 
> PMD_DRV_LOG which are still in use in the code.
> Before removing the above, those would have to be restructured.

Just try to change all PMD_DRV_LOG in fslmc to FSLMC_VFIO_LOG. As you 
are working on that, I will drop it.

>
> I am already working on converting this logging into dynamic logging.
> Can you skip this work until then? Does it block your work?

Do you mean you are working on introducing a new log type for bus drivers?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v5 3/5] bus: introduce new log type for bus drivers
  2017-10-11 10:42         ` Tan, Jianfeng
@ 2017-10-11 11:20           ` Shreyansh Jain
  2017-10-12  2:14             ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Shreyansh Jain @ 2017-10-11 11:20 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit

On Wednesday 11 October 2017 04:12 PM, Tan, Jianfeng wrote:
> 
> 
> On 10/11/2017 2:54 PM, Shreyansh Jain wrote:
>> Hello Jianfeng,
>>
>> On Monday 09 October 2017 04:57 PM, Jianfeng Tan wrote:
>>>
> [...]
>>> -#define PMD_DRV_LOG(level, fmt, args...) \
>>> -    PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
>>> +#define FSLMC_VFIO_LOG(level, fmt, args...) \
>>> +    RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
>>
>> This change breaks the FSLMC bus driver. There are macros like 
>> PMD_DRV_LOG which are still in use in the code.
>> Before removing the above, those would have to be restructured.
> 
> Just try to change all PMD_DRV_LOG in fslmc to FSLMC_VFIO_LOG. As you 
> are working on that, I will drop it. >
>>
>> I am already working on converting this logging into dynamic logging.
>> Can you skip this work until then? Does it block your work?
> 
> Do you mean you are working on introducing a new log type for bus drivers?

A dynamic log type using rte_log_register. So, "bus.fslmc", "net.dpaa2" 
and so on. I am not introducing LOGTYPE_BUS.

In past [1], I sent a patch for LOGTYPE_BUS but at that time I 
understood that dynamic logging is the preferred way.

[1] http://dpdk.org/dev/patchwork/patch/24478/


> 
> Thanks,
> Jianfeng
> 

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v5 3/5] bus: introduce new log type for bus drivers
  2017-10-11 11:20           ` Shreyansh Jain
@ 2017-10-12  2:14             ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-12  2:14 UTC (permalink / raw)
  To: Shreyansh Jain
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit



On 10/11/2017 7:20 PM, Shreyansh Jain wrote:
> On Wednesday 11 October 2017 04:12 PM, Tan, Jianfeng wrote:
>>
>>
>> On 10/11/2017 2:54 PM, Shreyansh Jain wrote:
>>> Hello Jianfeng,
>>>
>>> On Monday 09 October 2017 04:57 PM, Jianfeng Tan wrote:
>>>>
>> [...]
>>>> -#define PMD_DRV_LOG(level, fmt, args...) \
>>>> -    PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
>>>> +#define FSLMC_VFIO_LOG(level, fmt, args...) \
>>>> +    RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
>>>
>>> This change breaks the FSLMC bus driver. There are macros like 
>>> PMD_DRV_LOG which are still in use in the code.
>>> Before removing the above, those would have to be restructured.
>>
>> Just try to change all PMD_DRV_LOG in fslmc to FSLMC_VFIO_LOG. As you 
>> are working on that, I will drop it. >
>>>
>>> I am already working on converting this logging into dynamic logging.
>>> Can you skip this work until then? Does it block your work?
>>
>> Do you mean you are working on introducing a new log type for bus 
>> drivers?
>
> A dynamic log type using rte_log_register. So, "bus.fslmc", 
> "net.dpaa2" and so on. I am not introducing LOGTYPE_BUS.
>
> In past [1], I sent a patch for LOGTYPE_BUS but at that time I 
> understood that dynamic logging is the preferred way.
>
> [1] http://dpdk.org/dev/patchwork/patch/24478/

OK, that makes sense. I'll hold this change then. Thanks for your 
insight on this.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v6 0/4] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (6 preceding siblings ...)
  2017-10-09 11:27   ` [PATCH v5 " Jianfeng Tan
@ 2017-10-12  8:46   ` Jianfeng Tan
  2017-10-12  8:46     ` [PATCH v6 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
                       ` (3 more replies)
  2017-10-13  2:04   ` [PATCH v7 0/4] move vdev into drivers/bus Jianfeng Tan
                     ` (6 subsequent siblings)
  14 siblings, 4 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-12  8:46 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v6:
  - Don't introduce the static log type for bug, instead we use dynamic
    log type for vdev, suggested by Shreyansh Jain.

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set depends on:
  http://dpdk.org/ml/archives/dev/2017-October/077855.html

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we tend to move all bus drivers from EAL
to drivers/bus/. This patch set targets vdev bus.


Jianfeng Tan (4):
  cryptodev: remove crypto vdev init API
  eal: remove dependency on vdev
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: change log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 drivers/bus/Makefile                           |   3 +
 drivers/bus/vdev/Makefile                      |  55 ++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |   8 +
 drivers/bus/vdev/rte_vdev.h                    | 153 +++++++++++
 drivers/bus/vdev/vdev.c                        | 356 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  45 ++++
 drivers/crypto/Makefile                        |   1 +
 drivers/event/Makefile                         |   2 +-
 drivers/net/Makefile                           |   2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   1 -
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  22 +-
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_vdev.h       | 131 ---------
 lib/librte_eal/linuxapp/eal/Makefile           |   1 -
 mk/rte.app.mk                                  |   1 +
 22 files changed, 637 insertions(+), 546 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v6 1/4] cryptodev: remove crypto vdev init API
  2017-10-12  8:46   ` [PATCH v6 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-12  8:46     ` Jianfeng Tan
  2017-10-12 10:06       ` Thomas Monjalon
  2017-10-12  8:46     ` [PATCH v6 2/4] eal: remove dependency on vdev Jianfeng Tan
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-12  8:46 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 4 files changed, 29 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index f4269f0..85a9287 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -78,11 +78,6 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * cryptodev: the following function will be static in 17.11 and included
   by all crypto drivers, therefore, will not be public:
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 5e8f7f4..f2c55cc 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index ad97ff9..c5d6939 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -433,23 +433,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index abdbbda..b07f4ca 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v6 2/4] eal: remove dependency on vdev
  2017-10-12  8:46   ` [PATCH v6 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-12  8:46     ` [PATCH v6 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-12  8:46     ` Jianfeng Tan
  2017-10-12  8:46     ` [PATCH v6 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
  2017-10-12  8:46     ` [PATCH v6 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-12  8:46 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..dda8f58 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,13 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL,
+		"Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v6 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-12  8:46   ` [PATCH v6 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-12  8:46     ` [PATCH v6 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-10-12  8:46     ` [PATCH v6 2/4] eal: remove dependency on vdev Jianfeng Tan
@ 2017-10-12  8:46     ` Jianfeng Tan
  2017-10-12  8:46     ` [PATCH v6 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-12  8:46 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 drivers/bus/Makefile                      |   3 +
 drivers/bus/vdev/Makefile                 |  55 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |   8 +
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 344 ++++++++++++++++++++++++++++++
 drivers/crypto/Makefile                   |   1 +
 drivers/event/Makefile                    |   2 +-
 drivers/net/Makefile                      |   2 +-
 lib/librte_eal/bsdapp/eal/Makefile        |   1 -
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 -----------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   1 -
 mk/rte.app.mk                             |   1 +
 16 files changed, 574 insertions(+), 501 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 22068c5..c6f2aae 100644
--- a/config/common_base
+++ b/config/common_base
@@ -754,3 +754,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 6cb6466..91ffa87 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -38,4 +38,7 @@ DEPDIRS-dpaa = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+DEPDIRS-vdev = $(core-libs)
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..6c48ba0
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,55 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..6ccb789
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+};
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..a16eb71
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,344 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7a719b9..e487f6c 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
+core-libs += librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DEPDIRS-aesni_gcm = $(core-libs)
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
index 3f6b898..ceedf70 100644
--- a/drivers/event/Makefile
+++ b/drivers/event/Makefile
@@ -31,7 +31,7 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_eventdev
+core-libs := librte_eal librte_eventdev librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV) += skeleton
 DEPDIRS-skeleton = $(core-libs)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b28310b..1039d4e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -37,7 +37,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD),d)
 endif
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-core-libs += librte_net librte_kvargs
+core-libs += librte_net librte_kvargs librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DEPDIRS-af_packet = $(core-libs)
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 317a75e..8a3376c 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..7eeb06a 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5386d3a..8bfc343 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -166,28 +166,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -312,4 +290,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 21e0b4a..22ac5cd 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,7 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a788be2..7d31595 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -98,6 +98,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v6 4/4] bus/vdev: change log type
  2017-10-12  8:46   ` [PATCH v6 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-12  8:46     ` [PATCH v6 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-12  8:46     ` Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-12  8:46 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use specialized dynamic log type for vdev bus logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Suggested-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      | 20 ++++++++++++++++----
 drivers/bus/vdev/vdev_logs.h | 45 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index a16eb71..be2be6f 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,9 @@
 #include <rte_errno.h>
 
 #include "rte_vdev.h"
+#include "vdev_logs.h"
+
+int vdev_logtype_bus;
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +106,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +193,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -213,7 +216,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -294,7 +297,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
@@ -342,3 +345,12 @@ static struct rte_bus rte_vdev_bus = {
 };
 
 RTE_REGISTER_BUS(vdev, rte_vdev_bus);
+
+RTE_INIT(vdev_init_log);
+static void
+vdev_init_log(void)
+{
+	vdev_logtype_bus = rte_log_register("bus.vdev");
+	if (vdev_logtype_bus >= 0)
+		rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE);
+}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..43b0ab8
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,45 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#include <rte_log.h>
+
+extern int vdev_logtype_bus;
+
+#define VDEV_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, vdev_logtype_bus, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v6 1/4] cryptodev: remove crypto vdev init API
  2017-10-12  8:46     ` [PATCH v6 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-12 10:06       ` Thomas Monjalon
  0 siblings, 0 replies; 158+ messages in thread
From: Thomas Monjalon @ 2017-10-12 10:06 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit

12/10/2017 10:46, Jianfeng Tan:
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> -* cryptodev: the following function is deprecated starting from 17.08 and will
> -  be removed in 17.11:
> -
> -  - ``rte_cryptodev_create_vdev``

You need to add a note in API section of release notes.

If not already done, the ABIVER must be dumped.

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v7 0/4] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (7 preceding siblings ...)
  2017-10-12  8:46   ` [PATCH v6 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-13  2:04   ` Jianfeng Tan
  2017-10-13  2:04     ` [PATCH v7 1/4] ethdev: support attach vdev in secondary process Jianfeng Tan
                       ` (4 more replies)
  2017-10-13 11:51   ` Jianfeng Tan
                     ` (5 subsequent siblings)
  14 siblings, 5 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13  2:04 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v7:
  - Add notice in release note for API change, and bump library version
    of librte_cryptodev and librte_eal, as suggested by Thomas.

v6:
  - Don't introduce the static log type for bug, instead we use dynamic
    log type for vdev, suggested by Shreyansh Jain.

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set depends on:
  http://dpdk.org/ml/archives/dev/2017-October/077855.html

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we tend to move all bus drivers from EAL
to drivers/bus/. This patch set targets vdev bus.


Jianfeng Tan (4):
  ethdev: support attach vdev in secondary process
  vhost: allocate virtio_net in memzone
  vhost: support to kick in secondary process
  net/vhost: support to run in the secondary process

 drivers/net/vhost/rte_eth_vhost.c      | 200 ++++++++++++++++++++++++++++++---
 lib/librte_ether/rte_ethdev_vdev.h     |  26 +++--
 lib/librte_vhost/rte_vhost.h           |   3 +
 lib/librte_vhost/rte_vhost_version.map |   7 ++
 lib/librte_vhost/socket.c              |   2 +
 lib/librte_vhost/vhost.c               |  71 ++++++++++--
 lib/librte_vhost/vhost.h               |   7 +-
 lib/librte_vhost/vhost_user.c          |  17 +--
 8 files changed, 292 insertions(+), 41 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v7 1/4] ethdev: support attach vdev in secondary process
  2017-10-13  2:04   ` [PATCH v7 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-13  2:04     ` Jianfeng Tan
  2017-10-13  2:04     ` [PATCH v7 2/4] vhost: allocate virtio_net in memzone Jianfeng Tan
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13  2:04 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

When vdev driver requests an ethdev entry in secondary process,
we will identify the correct entry in rte_eth_dev_data array
and return the correct entry in the rte_eth_devices arrays.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev_vdev.h | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev_vdev.h b/lib/librte_ether/rte_ethdev_vdev.h
index 4d2c3e2..460749b 100644
--- a/lib/librte_ether/rte_ethdev_vdev.h
+++ b/lib/librte_ether/rte_ethdev_vdev.h
@@ -58,25 +58,29 @@ rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size)
 	struct rte_eth_dev *eth_dev;
 	const char *name = rte_vdev_device_name(dev);
 
-	eth_dev = rte_eth_dev_allocate(name);
-	if (!eth_dev)
-		return NULL;
-
-	if (private_data_size) {
-		eth_dev->data->dev_private = rte_zmalloc_socket(name,
-			private_data_size, RTE_CACHE_LINE_SIZE,
-			dev->device.numa_node);
-		if (!eth_dev->data->dev_private) {
-			rte_eth_dev_release_port(eth_dev);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev = rte_eth_dev_allocate(name);
+		if (!eth_dev)
 			return NULL;
+
+		if (private_data_size) {
+			eth_dev->data->dev_private = rte_zmalloc_socket(name,
+					private_data_size, RTE_CACHE_LINE_SIZE,
+					dev->device.numa_node);
+			if (!eth_dev->data->dev_private) {
+				rte_eth_dev_release_port(eth_dev);
+				return NULL;
+			}
 		}
+	} else {
+		eth_dev = rte_eth_dev_attach_secondary(name);
 	}
 
 	eth_dev->device = &dev->device;
 	eth_dev->intr_handle = NULL;
-
 	eth_dev->data->kdrv = RTE_KDRV_NONE;
 	eth_dev->data->numa_node = dev->device.numa_node;
+
 	return eth_dev;
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v7 2/4] vhost: allocate virtio_net in memzone
  2017-10-13  2:04   ` [PATCH v7 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-13  2:04     ` [PATCH v7 1/4] ethdev: support attach vdev in secondary process Jianfeng Tan
@ 2017-10-13  2:04     ` Jianfeng Tan
  2017-10-13  2:04     ` [PATCH v7 3/4] vhost: support to kick in secondary process Jianfeng Tan
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13  2:04 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Instead of allocate on the stack, change to allocate in memzone
so that we can retrieve them in secondary processes.

TODO: numa awareness.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_vhost/socket.c |  2 ++
 lib/librte_vhost/vhost.c  | 34 ++++++++++++++++++++++++++++++++--
 lib/librte_vhost/vhost.h  |  4 +++-
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 41aa3f9..35b9751 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -606,6 +606,8 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
 	int ret = -1;
 	struct vhost_user_socket *vsocket;
 
+	alloc_vhost_devices();
+
 	if (!path)
 		return -1;
 
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 0b6aa1c..2b687ea 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -47,15 +47,45 @@
 #include <rte_memory.h>
 #include <rte_malloc.h>
 #include <rte_vhost.h>
+#include <rte_memzone.h>
 
 #include "vhost.h"
 
-struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+#define MZ_VHOST_DEVICES "mz_vhost_devices"
+struct virtio_net **vhost_devices;
+
+void
+alloc_vhost_devices(void)
+{
+	const struct rte_memzone *mz;
+
+	if (vhost_devices != NULL)
+		return;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		mz = rte_memzone_reserve(MZ_VHOST_DEVICES,
+				MAX_VHOST_DEVICE * sizeof(*vhost_devices),
+				rte_socket_id(), 0);
+	} else
+		mz = rte_memzone_lookup(MZ_VHOST_DEVICES);
+
+	if (mz == NULL)
+		rte_panic("Cannot allocate memzone for vhost_devices\n");
+
+	vhost_devices = mz->addr;
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		memset(vhost_devices, 0,
+		       MAX_VHOST_DEVICE * sizeof(*vhost_devices));
+}
 
 struct virtio_net *
 get_device(int vid)
 {
-	struct virtio_net *dev = vhost_devices[vid];
+	struct virtio_net *dev;
+
+	alloc_vhost_devices();
+
+	dev = vhost_devices[vid];
 
 	if (unlikely(!dev)) {
 		RTE_LOG(ERR, VHOST_CONFIG,
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 6fe72ae..bc1f31e 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -278,7 +278,7 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
 
 extern uint64_t VHOST_FEATURES;
 #define MAX_VHOST_DEVICE	1024
-extern struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+extern struct virtio_net **vhost_devices;
 
 /* Convert guest physical address to host physical address */
 static __rte_always_inline phys_addr_t
@@ -300,6 +300,8 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size)
 	return 0;
 }
 
+
+void alloc_vhost_devices(void);
 struct virtio_net *get_device(int vid);
 
 int vhost_new_device(void);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v7 3/4] vhost: support to kick in secondary process
  2017-10-13  2:04   ` [PATCH v7 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-13  2:04     ` [PATCH v7 1/4] ethdev: support attach vdev in secondary process Jianfeng Tan
  2017-10-13  2:04     ` [PATCH v7 2/4] vhost: allocate virtio_net in memzone Jianfeng Tan
@ 2017-10-13  2:04     ` Jianfeng Tan
  2017-10-13  2:04     ` [PATCH v7 4/4] net/vhost: support to run in the " Jianfeng Tan
  2017-10-13  8:26     ` [PATCH v7 0/4] move vdev into drivers/bus Thomas Monjalon
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13  2:04 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

To support kick in secondary process, we propose callfd_pri and
kickfd_pri to store the value in primary process; and by a new
API, rte_vhost_set_vring_effective_fd(), we can set effective
callfd and kickfd which can be used by secondary process.

Note in this case, either primary process or the secondary process
can kick the frontend; that is, they cannot kick a vring at the
same time.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_vhost/rte_vhost.h           |  3 +++
 lib/librte_vhost/rte_vhost_version.map |  7 +++++++
 lib/librte_vhost/vhost.c               | 37 ++++++++++++++++++++++++++++------
 lib/librte_vhost/vhost.h               |  3 +++
 lib/librte_vhost/vhost_user.c          | 17 ++++++++--------
 5 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 8c974eb..c82f249 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -432,6 +432,9 @@ int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 			      struct rte_vhost_vring *vring);
 
+int rte_vhost_set_vring_effective_fd(int vid, uint16_t vring_idx,
+				     int callfd, int kickfd);
+
 /**
  * Get vhost RX queue avail count.
  *
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 1e70495..02142df 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -52,3 +52,10 @@ DPDK_17.08 {
 	rte_vhost_rx_queue_count;
 
 } DPDK_17.05;
+
+DPDK_17.11 {
+	global:
+
+	rte_vhost_set_vring_effective_fd;
+
+} DPDK_17.08;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 2b687ea..11a3db1 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -98,10 +98,10 @@ get_device(int vid)
 static void
 cleanup_vq(struct vhost_virtqueue *vq, int destroy)
 {
-	if ((vq->callfd >= 0) && (destroy != 0))
-		close(vq->callfd);
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
+	if ((vq->callfd_pri >= 0) && (destroy != 0))
+		close(vq->callfd_pri);
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
 }
 
 /*
@@ -146,6 +146,8 @@ init_vring_queue(struct vhost_virtqueue *vq)
 
 	vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
 	vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->kickfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->callfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
 
 	/* Backends are set to -1 indicating an inactive device. */
 	vq->backend = -1;
@@ -435,13 +437,36 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 	vring->used  = vq->used;
 	vring->log_guest_addr  = vq->log_guest_addr;
 
-	vring->callfd  = vq->callfd;
-	vring->kickfd  = vq->kickfd;
+	vring->callfd  = vq->callfd_pri;
+	vring->kickfd  = vq->kickfd_pri;
 	vring->size    = vq->size;
 
 	return 0;
 }
 
+int
+rte_vhost_set_vring_effective_fd(int vid, uint16_t vring_idx,
+				 int callfd, int kickfd)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (!dev)
+		return -1;
+
+	if (vring_idx >= VHOST_MAX_VRING)
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (!vq)
+		return -1;
+
+	vq->callfd = callfd;
+	vq->kickfd = kickfd;
+
+	return 0;
+}
 uint16_t
 rte_vhost_avail_entries(int vid, uint16_t queue_id)
 {
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index bc1f31e..be57c52 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -98,9 +98,12 @@ struct vhost_virtqueue {
 	/* Backend value to determine if device should started/stopped */
 	int			backend;
 	/* Used to notify the guest (trigger interrupt) */
+	int			callfd_pri;
 	int			callfd;
 	/* Currently unused as polling mode is enabled */
+	int			kickfd_pri;
 	int			kickfd;
+
 	int			enabled;
 
 	/* Physical address of used ring, for logging */
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index ad2e8d3..3d1eea4 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -661,10 +661,10 @@ vhost_user_set_vring_call(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 		"vring call idx:%d file:%d\n", file.index, file.fd);
 
 	vq = dev->virtqueue[file.index];
-	if (vq->callfd >= 0)
-		close(vq->callfd);
+	if (vq->callfd_pri >= 0)
+		close(vq->callfd_pri);
 
-	vq->callfd = file.fd;
+	vq->callfd_pri = vq->callfd = file.fd;
 }
 
 static void
@@ -682,9 +682,9 @@ vhost_user_set_vring_kick(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 		"vring kick idx:%d file:%d\n", file.index, file.fd);
 
 	vq = dev->virtqueue[file.index];
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
-	vq->kickfd = file.fd;
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
+	vq->kickfd_pri = vq->kickfd = file.fd;
 }
 
 static void
@@ -731,10 +731,11 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 	 * sent and only sent in vhost_vring_stop.
 	 * TODO: cleanup the vring, it isn't usable since here.
 	 */
-	if (vq->kickfd >= 0)
-		close(vq->kickfd);
+	if (vq->kickfd_pri >= 0)
+		close(vq->kickfd_pri);
 
 	vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
+	vq->kickfd_pri = VIRTIO_UNINITIALIZED_EVENTFD;
 
 	if (dev->dequeue_zero_copy)
 		free_zmbufs(vq);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v7 4/4] net/vhost: support to run in the secondary process
  2017-10-13  2:04   ` [PATCH v7 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-13  2:04     ` [PATCH v7 3/4] vhost: support to kick in secondary process Jianfeng Tan
@ 2017-10-13  2:04     ` Jianfeng Tan
  2017-10-13  8:26     ` [PATCH v7 0/4] move vdev into drivers/bus Thomas Monjalon
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13  2:04 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Support to run vhost-pmd vdev in the secondary process. We obtain
information, like memory regions, kickfd, callfd, through
primary/secondary communication channel.

And by invoking rte_vhost_set_vring_effective_fd, we can set the
kickfd which can be recognized by the secondary process.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vhost/rte_eth_vhost.c | 200 +++++++++++++++++++++++++++++++++++---
 1 file changed, 187 insertions(+), 13 deletions(-)

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 04179b4..9d296aa 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -33,6 +33,7 @@
 #include <unistd.h>
 #include <pthread.h>
 #include <stdbool.h>
+#include <sys/mman.h>
 
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
@@ -46,6 +47,20 @@
 
 #include "rte_eth_vhost.h"
 
+#define VHOST_MSG_TYPE_REGIONS	1
+#define VHOST_MSG_TYPE_SET_FDS	2
+#define VHOST_MSG_TYPE_INIT	3
+
+struct vhost_params {
+	int type;
+	union {
+		int vid;
+		int portid;
+	};
+	int vring_idx;
+	struct rte_vhost_mem_region regions[0];
+};
+
 enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM};
 
 #define ETH_VHOST_IFACE_ARG		"iface"
@@ -550,6 +565,66 @@ update_queuing_status(struct rte_eth_dev *dev)
 }
 
 static int
+share_device(int vid)
+{
+	uint32_t i, vring_num;
+	int len;
+	int fds[8];
+	struct rte_vhost_memory *mem;
+	struct vhost_params *params;
+	struct rte_vhost_vring vring;
+
+	/* share mem table */
+	if (rte_vhost_get_mem_table(vid, &mem) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to get mem table\n");
+		return 0;
+	}
+	for (i = 0; i < mem->nregions; ++i)
+		fds[i] = mem->regions[i].fd;
+
+	len = sizeof(struct rte_vhost_mem_region) * mem->nregions;
+	params = malloc(sizeof(*params) + len);
+	if (params == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to allocate memory\n");
+		return -1;
+	}
+
+	params->type = VHOST_MSG_TYPE_REGIONS;
+	params->vid = vid;
+	memcpy(params->regions, mem->regions, len);
+
+	if (rte_eal_mp_sendmsg("vhost pmd", params, sizeof(*params) + len,
+			       fds, mem->nregions) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to share mem table\n");
+		free(params);
+		return -1;
+	}
+
+	/* share callfd and kickfd */
+	params->type = VHOST_MSG_TYPE_SET_FDS;
+	vring_num = rte_vhost_get_vring_num(vid);
+	for (i = 0; i < vring_num; i++) {
+		if (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {
+			RTE_LOG(ERR, PMD, "Failed to get vring, idx = %d\n", i);
+			free(params);
+			return -1;
+		}
+
+		params->vring_idx = i;
+		fds[0] = vring.callfd;
+		fds[1] = vring.kickfd;
+		if (rte_eal_mp_sendmsg("vhost pmd", params,
+				       sizeof(*params), fds, 2) < 0) {
+			RTE_LOG(ERR, PMD, "Failed to set fds\n");
+			return -1;
+		}
+	}
+
+	free(params);
+	return 0;
+}
+
+static int
 new_device(int vid)
 {
 	struct rte_eth_dev *eth_dev;
@@ -610,6 +685,8 @@ new_device(int vid)
 	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
 				      NULL, NULL);
 
+	share_device(vid);
+
 	return 0;
 }
 
@@ -1025,13 +1102,6 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	RTE_LOG(INFO, PMD, "Creating VHOST-USER backend on numa socket %u\n",
 		numa_node);
 
-	/* now do all data allocation - for eth_dev structure and internal
-	 * (private) data
-	 */
-	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
-	if (data == NULL)
-		goto error;
-
 	list = rte_zmalloc_socket(name, sizeof(*list), 0, numa_node);
 	if (list == NULL)
 		goto error;
@@ -1073,11 +1143,7 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	rte_spinlock_init(&vring_state->lock);
 	vring_states[eth_dev->data->port_id] = vring_state;
 
-	/* We'll replace the 'data' originally allocated by eth_dev. So the
-	 * vhost PMD resources won't be shared between multi processes.
-	 */
-	rte_memcpy(data, eth_dev->data, sizeof(*data));
-	eth_dev->data = data;
+	data = eth_dev->data;
 
 	data->nb_rx_queues = queues;
 	data->nb_tx_queues = queues;
@@ -1125,6 +1191,30 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,
 	return -1;
 }
 
+static int
+eth_dev_vhost_attach(struct rte_vdev_device *dev)
+{
+	struct rte_eth_dev *eth_dev = NULL;
+	struct rte_eth_dev_data *data = NULL;
+
+	RTE_LOG(INFO, PMD, "Attach vhost user port\n");
+
+	/* reserve an ethdev entry */
+	eth_dev = rte_eth_vdev_allocate(dev, sizeof(struct pmd_internal));
+	if (eth_dev == NULL)
+		return -1;
+
+	eth_dev->dev_ops = &ops;
+
+	/* finally assign rx and tx ops */
+	eth_dev->rx_pkt_burst = eth_vhost_rx;
+	eth_dev->tx_pkt_burst = eth_vhost_tx;
+
+	data = eth_dev->data;
+
+	return data->port_id;
+}
+
 static inline int
 open_iface(const char *key __rte_unused, const char *value, void *extra_args)
 {
@@ -1154,10 +1244,84 @@ open_int(const char *key __rte_unused, const char *value, void *extra_args)
 }
 
 static int
+vhost_pmd_action(const void *params, int len, int fds[], int fds_num)
+{
+	int i;
+	int vid;
+	void *base_addr;
+	const struct vhost_params *p = params;
+	const struct rte_vhost_mem_region *regions;
+
+	if (len < (int)sizeof(*p)) {
+		RTE_LOG(ERR, PMD, "message if too short\n");
+		return -1;
+	}
+
+	switch (p->type) {
+	case VHOST_MSG_TYPE_REGIONS:
+		regions = p->regions;
+		for (i = 0; i < fds_num; ++i) {
+			base_addr = mmap(regions[i].mmap_addr,
+					 regions[i].mmap_size,
+					 PROT_READ | PROT_WRITE,
+					 MAP_FIXED | MAP_SHARED, fds[i], 0);
+			if (base_addr != regions[i].mmap_addr) {
+				RTE_LOG(ERR, PMD,
+					"vhost in secondary mmap error: %s\n",
+					strerror(errno));
+				break;
+			}
+		}
+		break;
+	case VHOST_MSG_TYPE_SET_FDS:
+		rte_vhost_set_vring_effective_fd(p->vid,
+						 p->vring_idx,
+						 fds[0], fds[1]);
+		break;
+	case VHOST_MSG_TYPE_INIT:
+		vid = rte_eth_vhost_get_vid_from_port_id(p->portid);
+		share_device(vid);
+		break;
+	}
+
+	return 0;
+}
+
+static int
+probe_secondary(struct rte_vdev_device *dev)
+{
+	int portid = eth_dev_vhost_attach(dev);
+	struct rte_eth_dev *eth_dev;
+	struct pmd_internal *internal;
+	struct vhost_params p;
+
+	if (portid < 0)
+		return -1;
+
+	eth_dev = &rte_eth_devices[portid];
+	internal = eth_dev->data->dev_private;
+
+	if (!internal ||
+	    rte_atomic32_read(&internal->dev_attached) == 0) {
+		RTE_LOG(INFO, PMD, "%s is not ready\n", dev->device.name);
+		return 0;
+	}
+
+	p.type = VHOST_MSG_TYPE_INIT;
+	p.portid = portid;
+	if (rte_eal_mp_sendmsg("vhost pmd", &p, sizeof(p), NULL, 0) < 0) {
+		RTE_LOG(ERR, PMD, "Failed to send request for init\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
 rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 {
 	struct rte_kvargs *kvlist = NULL;
-	int ret = 0;
+	int ret;
 	char *iface_name;
 	uint16_t queues;
 	uint64_t flags = 0;
@@ -1167,6 +1331,15 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 	RTE_LOG(INFO, PMD, "Initializing pmd_vhost for %s\n",
 		rte_vdev_device_name(dev));
 
+	ret = rte_eal_mp_action_register("vhost pmd", vhost_pmd_action);
+	if (ret < 0 && ret != -EEXIST) {
+		RTE_LOG(ERR, PMD, "vhost fails to add action\n");
+		return -1;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return probe_secondary(dev);
+
 	kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_arguments);
 	if (kvlist == NULL)
 		return -1;
@@ -1216,6 +1389,7 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
 	eth_dev_vhost_create(dev, iface_name, queues, dev->device.numa_node,
 		flags);
 
+	ret = 0;
 out_free:
 	rte_kvargs_free(kvlist);
 	return ret;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v7 0/4] move vdev into drivers/bus
  2017-10-13  2:04   ` [PATCH v7 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (3 preceding siblings ...)
  2017-10-13  2:04     ` [PATCH v7 4/4] net/vhost: support to run in the " Jianfeng Tan
@ 2017-10-13  8:26     ` Thomas Monjalon
  2017-10-13 11:49       ` Tan, Jianfeng
  4 siblings, 1 reply; 158+ messages in thread
From: Thomas Monjalon @ 2017-10-13  8:26 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit

13/10/2017 04:04, Jianfeng Tan:
> v7:
>   - Add notice in release note for API change, and bump library version
>     of librte_cryptodev and librte_eal, as suggested by Thomas.

The cover letter does not match the patches:

> Jianfeng Tan (4):
>   ethdev: support attach vdev in secondary process
>   vhost: allocate virtio_net in memzone
>   vhost: support to kick in secondary process
>   net/vhost: support to run in the secondary process

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v7 0/4] move vdev into drivers/bus
  2017-10-13  8:26     ` [PATCH v7 0/4] move vdev into drivers/bus Thomas Monjalon
@ 2017-10-13 11:49       ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-13 11:49 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, jblunck, Richardson, Bruce, Ananyev, Konstantin,
	De Lara Guarch, Pablo, yliu, maxime.coquelin, mtetsuyah, Yigit,
	Ferruh



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Friday, October 13, 2017 4:27 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; jblunck@infradead.org; Richardson, Bruce; Ananyev,
> Konstantin; De Lara Guarch, Pablo; yliu@fridaylinux.org;
> maxime.coquelin@redhat.com; mtetsuyah@gmail.com; Yigit, Ferruh
> Subject: Re: [dpdk-dev] [PATCH v7 0/4] move vdev into drivers/bus
> 
> 13/10/2017 04:04, Jianfeng Tan:
> > v7:
> >   - Add notice in release note for API change, and bump library version
> >     of librte_cryptodev and librte_eal, as suggested by Thomas.
> 
> The cover letter does not match the patches:

I'm sorry I've made this mistake twice. Will send out the right version right now.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v7 0/4] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (8 preceding siblings ...)
  2017-10-13  2:04   ` [PATCH v7 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-13 11:51   ` Jianfeng Tan
  2017-10-13 11:51     ` [PATCH v7 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
                       ` (3 more replies)
  2017-10-25 17:10   ` [PATCH v8 0/4] move vdev into drivers/bus Jianfeng Tan
                     ` (4 subsequent siblings)
  14 siblings, 4 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13 11:51 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v7:
  - Add notice in release note for API change, and bump library version
    of librte_cryptodev and librte_eal, as suggested by Thomas.

v6:
  - Don't introduce the static log type for bug, instead we use dynamic
    log type for vdev, suggested by Shreyansh Jain.

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set depends on:
  http://dpdk.org/ml/archives/dev/2017-October/077855.html

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we tend to move all bus drivers from EAL
to drivers/bus/. This patch set targets vdev bus.

Jianfeng Tan (4):
  cryptodev: remove crypto vdev init API
  eal: remove dependency on vdev
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: change log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 doc/guides/rel_notes/release_17_11.rst         |   2 +
 drivers/bus/Makefile                           |   3 +
 drivers/bus/vdev/Makefile                      |  55 ++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |   8 +
 drivers/bus/vdev/rte_vdev.h                    | 153 +++++++++++
 drivers/bus/vdev/vdev.c                        | 356 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  45 ++++
 drivers/crypto/Makefile                        |   1 +
 drivers/event/Makefile                         |   2 +-
 drivers/net/Makefile                           |   2 +-
 lib/librte_cryptodev/Makefile                  |   2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   3 +-
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  22 +-
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_vdev.h       | 131 ---------
 lib/librte_eal/linuxapp/eal/Makefile           |   3 +-
 mk/rte.app.mk                                  |   1 +
 24 files changed, 642 insertions(+), 549 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v7 1/4] cryptodev: remove crypto vdev init API
  2017-10-13 11:51   ` Jianfeng Tan
@ 2017-10-13 11:51     ` Jianfeng Tan
  2017-10-23 10:06       ` De Lara Guarch, Pablo
  2017-10-13 11:51     ` [PATCH v7 2/4] eal: remove dependency on vdev Jianfeng Tan
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13 11:51 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 doc/guides/rel_notes/release_17_11.rst         |  2 ++
 lib/librte_cryptodev/Makefile                  |  2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 6 files changed, 3 insertions(+), 30 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index f4269f0..85a9287 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -78,11 +78,6 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * cryptodev: the following function will be static in 17.11 and included
   by all crypto drivers, therefore, will not be public:
 
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 6a75ae0..6b405af 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -183,6 +183,8 @@ API Changes
 * ``rte_mem_phy2mch`` was used in Xen dom0 to obtain the physical address;
   remove this API as Xen dom0 support was removed.
 
+* ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
+  in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
 ABI Changes
 -----------
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 59d9a4e..47f466d 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -34,7 +34,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cryptodev.a
 
 # library version
-LIBABIVER := 3
+LIBABIVER := 4
 
 # build flags
 CFLAGS += -O3
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 5e8f7f4..f2c55cc 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index ad97ff9..c5d6939 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -433,23 +433,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index abdbbda..b07f4ca 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v7 2/4] eal: remove dependency on vdev
  2017-10-13 11:51   ` Jianfeng Tan
  2017-10-13 11:51     ` [PATCH v7 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-13 11:51     ` Jianfeng Tan
  2017-10-13 11:52     ` [PATCH v7 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
  2017-10-13 11:52     ` [PATCH v7 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13 11:51 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..dda8f58 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,13 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL,
+		"Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v7 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-13 11:51   ` Jianfeng Tan
  2017-10-13 11:51     ` [PATCH v7 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-10-13 11:51     ` [PATCH v7 2/4] eal: remove dependency on vdev Jianfeng Tan
@ 2017-10-13 11:52     ` Jianfeng Tan
  2017-10-23 14:34       ` De Lara Guarch, Pablo
  2017-10-13 11:52     ` [PATCH v7 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13 11:52 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 drivers/bus/Makefile                      |   3 +
 drivers/bus/vdev/Makefile                 |  55 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |   8 +
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 344 ++++++++++++++++++++++++++++++
 drivers/crypto/Makefile                   |   1 +
 drivers/event/Makefile                    |   2 +-
 drivers/net/Makefile                      |   2 +-
 lib/librte_eal/bsdapp/eal/Makefile        |   3 +-
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 -----------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   3 +-
 mk/rte.app.mk                             |   1 +
 16 files changed, 576 insertions(+), 503 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 22068c5..c6f2aae 100644
--- a/config/common_base
+++ b/config/common_base
@@ -754,3 +754,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 6cb6466..91ffa87 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -38,4 +38,7 @@ DEPDIRS-dpaa = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+DEPDIRS-vdev = $(core-libs)
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..6c48ba0
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,55 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..6ccb789
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+};
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..a16eb71
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,344 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7a719b9..e487f6c 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
+core-libs += librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DEPDIRS-aesni_gcm = $(core-libs)
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
index 3f6b898..ceedf70 100644
--- a/drivers/event/Makefile
+++ b/drivers/event/Makefile
@@ -31,7 +31,7 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_eventdev
+core-libs := librte_eal librte_eventdev librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV) += skeleton
 DEPDIRS-skeleton = $(core-libs)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b28310b..1039d4e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -37,7 +37,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD),d)
 endif
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-core-libs += librte_net librte_kvargs
+core-libs += librte_net librte_kvargs librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DEPDIRS-af_packet = $(core-libs)
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 317a75e..5ee65fe 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -48,7 +48,7 @@ LDLIBS += -lgcc_s
 
 EXPORT_MAP := rte_eal_version.map
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 # specific to bsdapp exec-env
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
@@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..7eeb06a 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5386d3a..8bfc343 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -166,28 +166,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -312,4 +290,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 21e0b4a..5296488 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -37,7 +37,7 @@ ARCH_DIR ?= $(RTE_ARCH)
 EXPORT_MAP := rte_eal_version.map
 VPATH += $(RTE_SDK)/lib/librte_eal/common/arch/$(ARCH_DIR)
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 VPATH += $(RTE_SDK)/lib/librte_eal/common
 
@@ -77,7 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a788be2..7d31595 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -98,6 +98,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v7 4/4] bus/vdev: change log type
  2017-10-13 11:51   ` Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-13 11:52     ` [PATCH v7 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-13 11:52     ` Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-13 11:52 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use specialized dynamic log type for vdev bus logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Suggested-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      | 20 ++++++++++++++++----
 drivers/bus/vdev/vdev_logs.h | 45 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index a16eb71..be2be6f 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,9 @@
 #include <rte_errno.h>
 
 #include "rte_vdev.h"
+#include "vdev_logs.h"
+
+int vdev_logtype_bus;
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +106,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +193,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -213,7 +216,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -294,7 +297,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
@@ -342,3 +345,12 @@ static struct rte_bus rte_vdev_bus = {
 };
 
 RTE_REGISTER_BUS(vdev, rte_vdev_bus);
+
+RTE_INIT(vdev_init_log);
+static void
+vdev_init_log(void)
+{
+	vdev_logtype_bus = rte_log_register("bus.vdev");
+	if (vdev_logtype_bus >= 0)
+		rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE);
+}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..43b0ab8
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,45 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#include <rte_log.h>
+
+extern int vdev_logtype_bus;
+
+#define VDEV_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, vdev_logtype_bus, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v7 1/4] cryptodev: remove crypto vdev init API
  2017-10-13 11:51     ` [PATCH v7 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-23 10:06       ` De Lara Guarch, Pablo
  0 siblings, 0 replies; 158+ messages in thread
From: De Lara Guarch, Pablo @ 2017-10-23 10:06 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: jblunck, Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh

Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, October 13, 2017 12:52 PM
> To: dev@dpdk.org
> Cc: jblunck@infradead.org; Richardson, Bruce
> <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh <ferruh.yigit@intel.com>; Tan,
> Jianfeng <jianfeng.tan@intel.com>
> Subject: [PATCH v7 1/4] cryptodev: remove crypto vdev init API
> 
> Remove rte_cryptodev_create_vdev() for duplication.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>

...

> --- a/lib/librte_cryptodev/Makefile
> +++ b/lib/librte_cryptodev/Makefile
> @@ -34,7 +34,7 @@ include $(RTE_SDK)/mk/rte.vars.mk  LIB =
> librte_cryptodev.a
> 
>  # library version
> -LIBABIVER := 3
> +LIBABIVER := 4

Sorry for the late review.
Since you are bumping the ABI version, you should also change it in
"Share Library Versions", in release_17_11.rst.

Thanks,
Pablo

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v7 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-13 11:52     ` [PATCH v7 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-23 14:34       ` De Lara Guarch, Pablo
  0 siblings, 0 replies; 158+ messages in thread
From: De Lara Guarch, Pablo @ 2017-10-23 14:34 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: jblunck, Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh

Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, October 13, 2017 12:52 PM
> To: dev@dpdk.org
> Cc: jblunck@infradead.org; Richardson, Bruce
> <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh <ferruh.yigit@intel.com>; Tan,
> Jianfeng <jianfeng.tan@intel.com>
> Subject: [PATCH v7 3/4] bus/vdev: move to vdev bus to drivers/bus
> 
> Move the vdev bus from lib/librte_eal to drivers/bus.
> 
> As the crypto vdev helper function refers to data structure in rte_vdev.h, so
> we move those helper function into drivers/bus too.

I am seeing some errors with this patch, compiling the test app:

test/test/test_eventdev.c:54:10: error: implicit declaration of function 'rte_vdev_init'
[-Werror=implicit-function-declaration]
   return rte_vdev_init("event_skeleton", NULL);
          ^~~~~~~~~~~~~
test/test/test_eventdev.c:54:3: error: nested extern declaration of 'rte_vdev_init'
[-Werror=nested-externs]
   return rte_vdev_init("event_skeleton", NULL);
   ^~~~~~

Also, I have a couple of comments more below.

...

> +++ b/drivers/bus/vdev/rte_bus_vdev_version.map
> @@ -0,0 +1,8 @@
> +DPDK_17.11 {
> +	global:
> +
> +	rte_vdev_init;
> +	rte_vdev_register;
> +	rte_vdev_uninit;
> +	rte_vdev_unregister;

These functions should be removed from rte_eal_version.map,
for Linux and BSD, right?

Also, should this be documented in release notes?

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v8 0/4] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (9 preceding siblings ...)
  2017-10-13 11:51   ` Jianfeng Tan
@ 2017-10-25 17:10   ` Jianfeng Tan
  2017-10-25 17:10     ` [PATCH v8 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
                       ` (3 more replies)
  2017-10-27  1:06   ` [PATCH v0 0/4] move vdev into drivers/bus Jianfeng Tan
                     ` (3 subsequent siblings)
  14 siblings, 4 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-25 17:10 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v8: (Suggested by Pablo)
  - As we bump the library version and add new library (bus_vdev), we
    need to update those in release note.
  - Fix compiling issue in test as of missing rte_vdev.h.
  - Move vdev API symbols from eal to bus_vdev; update in release note.

v7:
  - Add notice in release note for API change, and bump library version
    of librte_cryptodev and librte_eal, as suggested by Thomas.

v6:
  - Don't introduce the static log type for bug, instead we use dynamic
    log type for vdev, suggested by Shreyansh Jain.

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set depends on:
  http://dpdk.org/ml/archives/dev/2017-October/077855.html

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we tend to move all bus drivers from EAL
to drivers/bus/. This patch set targets vdev bus.


Jianfeng Tan (4):
  cryptodev: remove crypto vdev init API
  eal: remove dependency on vdev
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: change log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 doc/guides/rel_notes/release_17_11.rst         |  14 +-
 drivers/bus/Makefile                           |   3 +
 drivers/bus/vdev/Makefile                      |  55 ++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |   8 +
 drivers/bus/vdev/rte_vdev.h                    | 153 +++++++++++
 drivers/bus/vdev/vdev.c                        | 356 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  45 ++++
 drivers/crypto/Makefile                        |   1 +
 drivers/event/Makefile                         |   2 +-
 drivers/net/Makefile                           |   2 +-
 lib/librte_cryptodev/Makefile                  |   2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   3 +-
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  22 +-
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_vdev.h       | 131 ---------
 lib/librte_eal/linuxapp/eal/Makefile           |   3 +-
 lib/librte_eal/rte_eal_version.map             |   4 -
 mk/rte.app.mk                                  |   1 +
 test/test/test_cryptodev.c                     |   1 +
 test/test/test_event_eth_rx_adapter.c          |   1 +
 test/test/test_eventdev.c                      |   1 +
 test/test/test_eventdev_octeontx.c             |   1 +
 test/test/test_eventdev_sw.c                   |   1 +
 test/test/test_link_bonding_rssconf.c          |   1 +
 31 files changed, 658 insertions(+), 555 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v8 1/4] cryptodev: remove crypto vdev init API
  2017-10-25 17:10   ` [PATCH v8 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-25 17:10     ` Jianfeng Tan
  2017-10-25 17:10     ` [PATCH v8 2/4] eal: remove dependency on vdev Jianfeng Tan
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-25 17:10 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 doc/guides/rel_notes/release_17_11.rst         |  4 +++-
 lib/librte_cryptodev/Makefile                  |  2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 6 files changed, 4 insertions(+), 31 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3a5d093..6d859c0 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -66,11 +66,6 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * cryptodev: the following function will be static in 17.11 and included
   by all crypto drivers, therefore, will not be public:
 
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 3298ef5..898f7a5 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -297,6 +297,8 @@ API Changes
   ``rte_log_get_global_level()``, ``rte_log_set_level()`` and
   ``rte_log_get_level()``.
 
+* ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
+  in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
 ABI Changes
 -----------
@@ -355,7 +357,7 @@ The libraries prepended with a plus sign were incremented in this version.
    + librte_bitratestats.so.2
      librte_cfgfile.so.2
      librte_cmdline.so.2
-     librte_cryptodev.so.3
+     librte_cryptodev.so.4
      librte_distributor.so.1
    + librte_eal.so.6
    + librte_ethdev.so.8
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 455151f..9569c99 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -34,7 +34,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cryptodev.a
 
 # library version
-LIBABIVER := 3
+LIBABIVER := 4
 
 # build flags
 CFLAGS += -O3
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 21da40e..279b861 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index b74bbdd..f8341cf 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -433,23 +433,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 874c1b5..f148872 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v8 2/4] eal: remove dependency on vdev
  2017-10-25 17:10   ` [PATCH v8 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-25 17:10     ` [PATCH v8 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-25 17:10     ` Jianfeng Tan
  2017-10-25 17:10     ` [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
  2017-10-25 17:10     ` [PATCH v8 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-25 17:10 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..dda8f58 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,13 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL,
+		"Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-25 17:10   ` [PATCH v8 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-25 17:10     ` [PATCH v8 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-10-25 17:10     ` [PATCH v8 2/4] eal: remove dependency on vdev Jianfeng Tan
@ 2017-10-25 17:10     ` Jianfeng Tan
  2017-10-25 21:32       ` De Lara Guarch, Pablo
  2017-10-25 23:03       ` Gaëtan Rivet
  2017-10-25 17:10     ` [PATCH v8 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 2 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-25 17:10 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 doc/guides/rel_notes/release_17_11.rst    |  10 +-
 drivers/bus/Makefile                      |   3 +
 drivers/bus/vdev/Makefile                 |  55 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |   8 +
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 344 ++++++++++++++++++++++++++++++
 drivers/crypto/Makefile                   |   1 +
 drivers/event/Makefile                    |   2 +-
 drivers/net/Makefile                      |   2 +-
 lib/librte_eal/bsdapp/eal/Makefile        |   3 +-
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 -----------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   3 +-
 lib/librte_eal/rte_eal_version.map        |   4 -
 mk/rte.app.mk                             |   1 +
 test/test/test_cryptodev.c                |   1 +
 test/test/test_event_eth_rx_adapter.c     |   1 +
 test/test/test_eventdev.c                 |   1 +
 test/test/test_eventdev_octeontx.c        |   1 +
 test/test/test_eventdev_sw.c              |   1 +
 test/test/test_link_bonding_rssconf.c     |   1 +
 24 files changed, 591 insertions(+), 508 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 4ddde59..65b13e5 100644
--- a/config/common_base
+++ b/config/common_base
@@ -800,3 +800,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 898f7a5..79f810a 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -300,6 +300,13 @@ API Changes
 * ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
   in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
+* **Moved the following APIs from eal library to bus_vdev library**
+
+  * ``rte_vdev_init``
+  * ``rte_vdev_register``
+  * ``rte_vdev_uninit``
+  * ``rte_vdev_unregister``
+
 ABI Changes
 -----------
 
@@ -355,11 +362,12 @@ The libraries prepended with a plus sign were incremented in this version.
 
      librte_acl.so.2
    + librte_bitratestats.so.2
+   + librte_bus_vdev.so.1
      librte_cfgfile.so.2
      librte_cmdline.so.2
      librte_cryptodev.so.4
      librte_distributor.so.1
-   + librte_eal.so.6
+   + librte_eal.so.7
    + librte_ethdev.so.8
    + librte_eventdev.so.3
    + librte_flow_classify.so.1
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 4b29e3d..cb12d19 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -36,4 +36,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+DEPDIRS-vdev = $(core-libs)
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..6c48ba0
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,55 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..6ccb789
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+};
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..a16eb71
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,344 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index d551541..1cb4cdb 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
+core-libs += librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
index 05dec1b..9c9ae82 100644
--- a/drivers/event/Makefile
+++ b/drivers/event/Makefile
@@ -31,7 +31,7 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_ether librte_eventdev
+core-libs := librte_eal librte_ether librte_eventdev librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV) += skeleton
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index cf33233..00be153 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -37,7 +37,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD),d)
 endif
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-core-libs += librte_net librte_kvargs
+core-libs += librte_net librte_kvargs librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DIRS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 351fa57..25a48d1 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -48,7 +48,7 @@ LDLIBS += -lgcc_s
 
 EXPORT_MAP := ../../rte_eal_version.map
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 # specific to bsdapp exec-env
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
@@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 6f5b3f3..2fb5635 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -39,7 +39,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 4c4ac7e..8088dcc 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -170,28 +170,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -316,4 +294,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 965da6e..eef80eb 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -37,7 +37,7 @@ ARCH_DIR ?= $(RTE_ARCH)
 EXPORT_MAP := ../../rte_eal_version.map
 VPATH += $(RTE_SDK)/lib/librte_eal/common/arch/$(ARCH_DIR)
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 VPATH += $(RTE_SDK)/lib/librte_eal/common
 
@@ -77,7 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 8eb53ab..f9edb29 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -181,10 +181,6 @@ DPDK_17.05 {
 	rte_pci_unmap_device;
 	rte_pci_unregister;
 	rte_pci_write_config;
-	rte_vdev_init;
-	rte_vdev_register;
-	rte_vdev_uninit;
-	rte_vdev_unregister;
 	vfio_get_container_fd;
 	vfio_get_group_fd;
 	vfio_get_group_no;
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 482656c..6780f4f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -99,6 +99,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index a926779..2e80062 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_pause.h>
+#include <rte_vdev.h>
 
 #include <rte_crypto.h>
 #include <rte_cryptodev.h>
diff --git a/test/test/test_event_eth_rx_adapter.c b/test/test/test_event_eth_rx_adapter.c
index 56ed1f8..c0b864b 100644
--- a/test/test/test_event_eth_rx_adapter.c
+++ b/test/test/test_event_eth_rx_adapter.c
@@ -35,6 +35,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
+#include <rte_vdev.h>
 
 #include <rte_event_eth_rx_adapter.h>
 
diff --git a/test/test/test_eventdev.c b/test/test/test_eventdev.c
index d6ade78..e3d36f3 100644
--- a/test/test/test_eventdev.c
+++ b/test/test/test_eventdev.c
@@ -37,6 +37,7 @@
 #include <rte_memcpy.h>
 #include <rte_eventdev.h>
 #include <rte_dev.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_octeontx.c b/test/test/test_eventdev_octeontx.c
index b88b0d2..ecae3e9 100644
--- a/test/test/test_eventdev_octeontx.c
+++ b/test/test/test_eventdev_octeontx.c
@@ -45,6 +45,7 @@
 #include <rte_lcore.h>
 #include <rte_per_lcore.h>
 #include <rte_random.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_sw.c b/test/test/test_eventdev_sw.c
index 7219886..385e743 100644
--- a/test/test/test_eventdev_sw.c
+++ b/test/test/test_eventdev_sw.c
@@ -49,6 +49,7 @@
 #include <rte_cycles.h>
 #include <rte_eventdev.h>
 #include <rte_pause.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_link_bonding_rssconf.c b/test/test/test_link_bonding_rssconf.c
index 7dccc6e..6199188 100644
--- a/test/test/test_link_bonding_rssconf.c
+++ b/test/test/test_link_bonding_rssconf.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_lcore.h>
 #include <rte_memory.h>
+#include <rte_vdev.h>
 
 #include <rte_string_fns.h>
 #include <rte_errno.h>
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v8 4/4] bus/vdev: change log type
  2017-10-25 17:10   ` [PATCH v8 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-25 17:10     ` [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-25 17:10     ` Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-25 17:10 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use specialized dynamic log type for vdev bus logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Suggested-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      | 20 ++++++++++++++++----
 drivers/bus/vdev/vdev_logs.h | 45 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index a16eb71..be2be6f 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,9 @@
 #include <rte_errno.h>
 
 #include "rte_vdev.h"
+#include "vdev_logs.h"
+
+int vdev_logtype_bus;
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +106,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +193,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -213,7 +216,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -294,7 +297,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
@@ -342,3 +345,12 @@ static struct rte_bus rte_vdev_bus = {
 };
 
 RTE_REGISTER_BUS(vdev, rte_vdev_bus);
+
+RTE_INIT(vdev_init_log);
+static void
+vdev_init_log(void)
+{
+	vdev_logtype_bus = rte_log_register("bus.vdev");
+	if (vdev_logtype_bus >= 0)
+		rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE);
+}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..43b0ab8
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,45 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#include <rte_log.h>
+
+extern int vdev_logtype_bus;
+
+#define VDEV_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, vdev_logtype_bus, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-25 17:10     ` [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-25 21:32       ` De Lara Guarch, Pablo
  2017-10-25 23:03       ` Gaëtan Rivet
  1 sibling, 0 replies; 158+ messages in thread
From: De Lara Guarch, Pablo @ 2017-10-25 21:32 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: jblunck, Richardson, Bruce, Ananyev, Konstantin, thomas, yliu,
	maxime.coquelin, mtetsuyah, Yigit, Ferruh

Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Wednesday, October 25, 2017 6:11 PM
> To: dev@dpdk.org
> Cc: jblunck@infradead.org; Richardson, Bruce
> <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; thomas@monjalon.net;
> yliu@fridaylinux.org; maxime.coquelin@redhat.com;
> mtetsuyah@gmail.com; Yigit, Ferruh <ferruh.yigit@intel.com>; Tan,
> Jianfeng <jianfeng.tan@intel.com>
> Subject: [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus
> 
> Move the vdev bus from lib/librte_eal to drivers/bus.
> 
> As the crypto vdev helper function refers to data structure in rte_vdev.h, so
> we move those helper function into drivers/bus too.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

...

>  ABI Changes
>  -----------
> 
> @@ -355,11 +362,12 @@ The libraries prepended with a plus sign were
> incremented in this version.
> 
>       librte_acl.so.2
>     + librte_bitratestats.so.2
> +   + librte_bus_vdev.so.1
>       librte_cfgfile.so.2
>       librte_cmdline.so.2
>       librte_cryptodev.so.4
>       librte_distributor.so.1
> -   + librte_eal.so.6
> +   + librte_eal.so.7

EAL ABI version has been bumped already in this release,
so there is no need to do it again.

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-25 17:10     ` [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
  2017-10-25 21:32       ` De Lara Guarch, Pablo
@ 2017-10-25 23:03       ` Gaëtan Rivet
  1 sibling, 0 replies; 158+ messages in thread
From: Gaëtan Rivet @ 2017-10-25 23:03 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit

Hello Jianfeng,

On Wed, Oct 25, 2017 at 05:10:45PM +0000, Jianfeng Tan wrote:
> Move the vdev bus from lib/librte_eal to drivers/bus.
> 
> As the crypto vdev helper function refers to data structure
> in rte_vdev.h, so we move those helper function into drivers/bus
> too.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---

<...>

> diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
> index 4b29e3d..cb12d19 100644
> --- a/drivers/bus/Makefile
> +++ b/drivers/bus/Makefile
> @@ -36,4 +36,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
>  
>  DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
>  
> +DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
> +DEPDIRS-vdev = $(core-libs)
> +

This DEPDIRS should not be necessary, see commit:

cbc12b0a96f5 ("mk: do not generate LDLIBS from directorydependencies")

You will need to add the relevant LDLIBS into drivers/bus/vdev/Makefile
however.

>  include $(RTE_SDK)/mk/rte.subdir.mk
> diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
> new file mode 100644
> index 0000000..6c48ba0
> --- /dev/null
> +++ b/drivers/bus/vdev/Makefile
> @@ -0,0 +1,55 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2017 Intel Corporation. All rights reserved.
> +#   All rights reserved.
> +#
> +#   Redistribution and use in source and binary forms, with or without
> +#   modification, are permitted provided that the following conditions
> +#   are met:
> +#
> +#     * Redistributions of source code must retain the above copyright
> +#       notice, this list of conditions and the following disclaimer.
> +#     * Redistributions in binary form must reproduce the above copyright
> +#       notice, this list of conditions and the following disclaimer in
> +#       the documentation and/or other materials provided with the
> +#       distribution.
> +#     * Neither the name of Intel Corporation nor the names of its
> +#       contributors may be used to endorse or promote products derived
> +#       from this software without specific prior written permission.
> +#
> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +#
> +# library name
> +#
> +LIB = librte_bus_vdev.a
> +
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +

Here: missing LDLIBS if above is valid.

> +# versioning export map
> +EXPORT_MAP := rte_bus_vdev_version.map
> +
> +# library version
> +LIBABIVER := 1
> +
> +SRCS-y += vdev.c
> +
> +#
> +# Export include files
> +#
> +SYMLINK-y-include += rte_vdev.h
> +
> +include $(RTE_SDK)/mk/rte.lib.mk

<...>

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v0 0/4] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (10 preceding siblings ...)
  2017-10-25 17:10   ` [PATCH v8 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-27  1:06   ` Jianfeng Tan
  2017-10-27  1:06     ` [PATCH v9 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
                       ` (3 more replies)
  2017-10-27  3:23   ` [PATCH v10 0/4] move vdev into drivers/bus Jianfeng Tan
                     ` (2 subsequent siblings)
  14 siblings, 4 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  1:06 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v9:
  - Avoid bumping library version (eal, crypto) as other commits in this
    release already do that as suggested by Pablo.
  - Move vdev's dir dependency to its own folder as suggested by Gaetan.

v8: (Suggested by Pablo)
  - As we bump the library version and add new library (bus_vdev), we
    need to update those in release note.
  - Fix compiling issue in test as of missing rte_vdev.h.
  - Move vdev API symbols from eal to bus_vdev; update in release note.

v7:
  - Add notice in release note for API change, and bump library version
    of librte_cryptodev and librte_eal, as suggested by Thomas.

v6:
  - Don't introduce the static log type for bug, instead we use dynamic
    log type for vdev, suggested by Shreyansh Jain.

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set depends on:
  http://dpdk.org/ml/archives/dev/2017-October/077855.html

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we tend to move all bus drivers from EAL
to drivers/bus/. This patch set targets vdev bus.

Jianfeng Tan (4):
  cryptodev: remove crypto vdev init API
  eal: remove dependency on vdev
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: change log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 doc/guides/rel_notes/release_17_11.rst         |  10 +
 drivers/bus/Makefile                           |   4 +-
 drivers/bus/vdev/Makefile                      |  57 ++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |   8 +
 drivers/bus/vdev/rte_vdev.h                    | 153 +++++++++++
 drivers/bus/vdev/vdev.c                        | 356 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  45 ++++
 drivers/crypto/Makefile                        |   1 +
 drivers/event/Makefile                         |   2 +-
 drivers/net/Makefile                           |   2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   3 +-
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  22 +-
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_vdev.h       | 131 ---------
 lib/librte_eal/linuxapp/eal/Makefile           |   3 +-
 lib/librte_eal/rte_eal_version.map             |   4 -
 mk/rte.app.mk                                  |   1 +
 test/test/test_cryptodev.c                     |   1 +
 test/test/test_event_eth_rx_adapter.c          |   1 +
 test/test/test_eventdev.c                      |   1 +
 test/test/test_eventdev_octeontx.c             |   1 +
 test/test/test_eventdev_sw.c                   |   1 +
 test/test/test_link_bonding_rssconf.c          |   1 +
 30 files changed, 656 insertions(+), 554 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v9 1/4] cryptodev: remove crypto vdev init API
  2017-10-27  1:06   ` [PATCH v0 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-27  1:06     ` Jianfeng Tan
  2017-10-27  1:06     ` [PATCH v9 2/4] eal: remove dependency on vdev Jianfeng Tan
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  1:06 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 doc/guides/rel_notes/release_17_11.rst         |  2 ++
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 5 files changed, 2 insertions(+), 29 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3a5d093..6d859c0 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -66,11 +66,6 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * cryptodev: the following function will be static in 17.11 and included
   by all crypto drivers, therefore, will not be public:
 
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 3298ef5..06de87b 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -297,6 +297,8 @@ API Changes
   ``rte_log_get_global_level()``, ``rte_log_set_level()`` and
   ``rte_log_get_level()``.
 
+* ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
+  in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
 ABI Changes
 -----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 21da40e..279b861 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index b74bbdd..f8341cf 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -433,23 +433,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 874c1b5..f148872 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v9 2/4] eal: remove dependency on vdev
  2017-10-27  1:06   ` [PATCH v0 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-27  1:06     ` [PATCH v9 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-27  1:06     ` Jianfeng Tan
  2017-10-27  1:06     ` [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
  2017-10-27  1:06     ` [PATCH v9 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  1:06 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..dda8f58 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,13 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL,
+		"Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-27  1:06   ` [PATCH v0 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-27  1:06     ` [PATCH v9 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-10-27  1:06     ` [PATCH v9 2/4] eal: remove dependency on vdev Jianfeng Tan
@ 2017-10-27  1:06     ` Jianfeng Tan
  2017-10-27  7:56       ` Thomas Monjalon
  2017-10-27  1:06     ` [PATCH v9 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  1:06 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 doc/guides/rel_notes/release_17_11.rst    |   8 +
 drivers/bus/Makefile                      |   4 +-
 drivers/bus/vdev/Makefile                 |  57 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |   8 +
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 344 ++++++++++++++++++++++++++++++
 drivers/crypto/Makefile                   |   1 +
 drivers/event/Makefile                    |   2 +-
 drivers/net/Makefile                      |   2 +-
 lib/librte_eal/bsdapp/eal/Makefile        |   3 +-
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 -----------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   3 +-
 lib/librte_eal/rte_eal_version.map        |   4 -
 mk/rte.app.mk                             |   1 +
 test/test/test_cryptodev.c                |   1 +
 test/test/test_event_eth_rx_adapter.c     |   1 +
 test/test/test_eventdev.c                 |   1 +
 test/test/test_eventdev_octeontx.c        |   1 +
 test/test/test_eventdev_sw.c              |   1 +
 test/test/test_link_bonding_rssconf.c     |   1 +
 24 files changed, 591 insertions(+), 509 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 4ddde59..65b13e5 100644
--- a/config/common_base
+++ b/config/common_base
@@ -800,3 +800,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 06de87b..58d4c58 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -300,6 +300,13 @@ API Changes
 * ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
   in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
+* **Moved the following APIs from eal library to bus_vdev library**
+
+  * ``rte_vdev_init``
+  * ``rte_vdev_register``
+  * ``rte_vdev_uninit``
+  * ``rte_vdev_unregister``
+
 ABI Changes
 -----------
 
@@ -355,6 +362,7 @@ The libraries prepended with a plus sign were incremented in this version.
 
      librte_acl.so.2
    + librte_bitratestats.so.2
+   + librte_bus_vdev.so.1
      librte_cfgfile.so.2
      librte_cmdline.so.2
      librte_cryptodev.so.3
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 4b29e3d..038e10c 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -30,10 +30,10 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-
 DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..fe31654
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,57 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+LDLIBS += -lrte_eal
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..6ccb789
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+};
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..a16eb71
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,344 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index d551541..1cb4cdb 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
+core-libs += librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
index 05dec1b..9c9ae82 100644
--- a/drivers/event/Makefile
+++ b/drivers/event/Makefile
@@ -31,7 +31,7 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_ether librte_eventdev
+core-libs := librte_eal librte_ether librte_eventdev librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV) += skeleton
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index cf33233..00be153 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -37,7 +37,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD),d)
 endif
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-core-libs += librte_net librte_kvargs
+core-libs += librte_net librte_kvargs librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DIRS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 351fa57..25a48d1 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -48,7 +48,7 @@ LDLIBS += -lgcc_s
 
 EXPORT_MAP := ../../rte_eal_version.map
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 # specific to bsdapp exec-env
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
@@ -68,7 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 6f5b3f3..2fb5635 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -39,7 +39,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 4c4ac7e..8088dcc 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -170,28 +170,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -316,4 +294,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 965da6e..eef80eb 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -37,7 +37,7 @@ ARCH_DIR ?= $(RTE_ARCH)
 EXPORT_MAP := ../../rte_eal_version.map
 VPATH += $(RTE_SDK)/lib/librte_eal/common/arch/$(ARCH_DIR)
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 VPATH += $(RTE_SDK)/lib/librte_eal/common
 
@@ -77,7 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 8eb53ab..f9edb29 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -181,10 +181,6 @@ DPDK_17.05 {
 	rte_pci_unmap_device;
 	rte_pci_unregister;
 	rte_pci_write_config;
-	rte_vdev_init;
-	rte_vdev_register;
-	rte_vdev_uninit;
-	rte_vdev_unregister;
 	vfio_get_container_fd;
 	vfio_get_group_fd;
 	vfio_get_group_no;
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 482656c..6780f4f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -99,6 +99,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index a926779..2e80062 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_pause.h>
+#include <rte_vdev.h>
 
 #include <rte_crypto.h>
 #include <rte_cryptodev.h>
diff --git a/test/test/test_event_eth_rx_adapter.c b/test/test/test_event_eth_rx_adapter.c
index 56ed1f8..c0b864b 100644
--- a/test/test/test_event_eth_rx_adapter.c
+++ b/test/test/test_event_eth_rx_adapter.c
@@ -35,6 +35,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
+#include <rte_vdev.h>
 
 #include <rte_event_eth_rx_adapter.h>
 
diff --git a/test/test/test_eventdev.c b/test/test/test_eventdev.c
index d6ade78..e3d36f3 100644
--- a/test/test/test_eventdev.c
+++ b/test/test/test_eventdev.c
@@ -37,6 +37,7 @@
 #include <rte_memcpy.h>
 #include <rte_eventdev.h>
 #include <rte_dev.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_octeontx.c b/test/test/test_eventdev_octeontx.c
index b88b0d2..ecae3e9 100644
--- a/test/test/test_eventdev_octeontx.c
+++ b/test/test/test_eventdev_octeontx.c
@@ -45,6 +45,7 @@
 #include <rte_lcore.h>
 #include <rte_per_lcore.h>
 #include <rte_random.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_sw.c b/test/test/test_eventdev_sw.c
index 7219886..385e743 100644
--- a/test/test/test_eventdev_sw.c
+++ b/test/test/test_eventdev_sw.c
@@ -49,6 +49,7 @@
 #include <rte_cycles.h>
 #include <rte_eventdev.h>
 #include <rte_pause.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_link_bonding_rssconf.c b/test/test/test_link_bonding_rssconf.c
index 7dccc6e..6199188 100644
--- a/test/test/test_link_bonding_rssconf.c
+++ b/test/test/test_link_bonding_rssconf.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_lcore.h>
 #include <rte_memory.h>
+#include <rte_vdev.h>
 
 #include <rte_string_fns.h>
 #include <rte_errno.h>
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v9 4/4] bus/vdev: change log type
  2017-10-27  1:06   ` [PATCH v0 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-27  1:06     ` [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-27  1:06     ` Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  1:06 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use specialized dynamic log type for vdev bus logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Suggested-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      | 20 ++++++++++++++++----
 drivers/bus/vdev/vdev_logs.h | 45 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index a16eb71..be2be6f 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,9 @@
 #include <rte_errno.h>
 
 #include "rte_vdev.h"
+#include "vdev_logs.h"
+
+int vdev_logtype_bus;
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +106,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +193,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -213,7 +216,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -294,7 +297,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
@@ -342,3 +345,12 @@ static struct rte_bus rte_vdev_bus = {
 };
 
 RTE_REGISTER_BUS(vdev, rte_vdev_bus);
+
+RTE_INIT(vdev_init_log);
+static void
+vdev_init_log(void)
+{
+	vdev_logtype_bus = rte_log_register("bus.vdev");
+	if (vdev_logtype_bus >= 0)
+		rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE);
+}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..43b0ab8
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,45 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#include <rte_log.h>
+
+extern int vdev_logtype_bus;
+
+#define VDEV_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, vdev_logtype_bus, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v10 0/4] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (11 preceding siblings ...)
  2017-10-27  1:06   ` [PATCH v0 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-27  3:23   ` Jianfeng Tan
  2017-10-27  3:23     ` [PATCH v10 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
                       ` (3 more replies)
  2017-10-30  8:28   ` [PATCH v11 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-11-07  6:54   ` [PATCH v12 0/4] move vdev into drivers/bus Jianfeng Tan
  14 siblings, 4 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  3:23 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v10:
  - Rebase on 17.11-rc2.

v9:
  - Avoid bumping library version (eal, crypto) as other commits in this
    release already do that as suggested by Pablo.
  - Move vdev's dir dependency to its own folder as suggested by Gaetan.

v8: (Suggested by Pablo)
  - As we bump the library version and add new library (bus_vdev), we
    need to update those in release note.
  - Fix compiling issue in test as of missing rte_vdev.h.
  - Move vdev API symbols from eal to bus_vdev; update in release note.

v7:
  - Add notice in release note for API change, and bump library version
    of librte_cryptodev and librte_eal, as suggested by Thomas.

v6:
  - Don't introduce the static log type for bug, instead we use dynamic
    log type for vdev, suggested by Shreyansh Jain.

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we move all bus drivers from EAL to
drivers/bus/. This patch set targets vdev bus.

Jianfeng Tan (4):
  cryptodev: remove crypto vdev init API
  eal: remove dependency on vdev
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: change log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 doc/guides/rel_notes/release_17_11.rst         |  10 +
 drivers/bus/Makefile                           |   4 +-
 drivers/bus/vdev/Makefile                      |  57 ++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |   8 +
 drivers/bus/vdev/rte_vdev.h                    | 153 +++++++++++
 drivers/bus/vdev/vdev.c                        | 356 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  45 ++++
 drivers/crypto/Makefile                        |   1 +
 drivers/event/Makefile                         |   2 +-
 drivers/net/Makefile                           |   2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   3 +-
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  22 +-
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_vdev.h       | 131 ---------
 lib/librte_eal/linuxapp/eal/Makefile           |   3 +-
 lib/librte_eal/rte_eal_version.map             |   4 -
 mk/rte.app.mk                                  |   1 +
 test/test/test_cryptodev.c                     |   1 +
 test/test/test_event_eth_rx_adapter.c          |   1 +
 test/test/test_eventdev.c                      |   1 +
 test/test/test_eventdev_octeontx.c             |   1 +
 test/test/test_eventdev_sw.c                   |   1 +
 test/test/test_link_bonding_rssconf.c          |   1 +
 30 files changed, 656 insertions(+), 554 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v10 1/4] cryptodev: remove crypto vdev init API
  2017-10-27  3:23   ` [PATCH v10 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-27  3:23     ` Jianfeng Tan
  2017-10-27  3:23     ` [PATCH v10 2/4] eal: remove dependency on vdev Jianfeng Tan
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  3:23 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 doc/guides/rel_notes/release_17_11.rst         |  2 ++
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 5 files changed, 2 insertions(+), 29 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index a93c3e1..9120121 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -60,10 +60,5 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * librte_meter: The API will change to accommodate configuration profiles.
   Most of the API functions will have an additional opaque parameter.
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index b96b236..bab5d73 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -403,6 +403,8 @@ API Changes
   the backing device supports the operation or if the operation was
   successfully performed.
 
+* ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
+  in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
 ABI Changes
 -----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 8063211..973c8db 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index a0d3a12..2c1377b 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -435,23 +435,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e82296c..eb47308 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v10 2/4] eal: remove dependency on vdev
  2017-10-27  3:23   ` [PATCH v10 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-27  3:23     ` [PATCH v10 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-27  3:23     ` Jianfeng Tan
  2017-10-27  3:23     ` [PATCH v10 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
  2017-10-27  3:23     ` [PATCH v10 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  3:23 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..dda8f58 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,13 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL,
+		"Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v10 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-27  3:23   ` [PATCH v10 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-27  3:23     ` [PATCH v10 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-10-27  3:23     ` [PATCH v10 2/4] eal: remove dependency on vdev Jianfeng Tan
@ 2017-10-27  3:23     ` Jianfeng Tan
  2017-10-27  3:23     ` [PATCH v10 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  3:23 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                        |   5 +
 doc/guides/rel_notes/release_17_11.rst    |   8 +
 drivers/bus/Makefile                      |   4 +-
 drivers/bus/vdev/Makefile                 |  57 +++++
 drivers/bus/vdev/rte_bus_vdev_version.map |   8 +
 drivers/bus/vdev/rte_vdev.h               | 153 +++++++++++++
 drivers/bus/vdev/vdev.c                   | 344 ++++++++++++++++++++++++++++++
 drivers/crypto/Makefile                   |   1 +
 drivers/event/Makefile                    |   2 +-
 drivers/net/Makefile                      |   2 +-
 lib/librte_eal/bsdapp/eal/Makefile        |   3 +-
 lib/librte_eal/common/Makefile            |   2 +-
 lib/librte_eal/common/eal_common_vdev.c   | 342 -----------------------------
 lib/librte_eal/common/include/rte_dev.h   |  24 +--
 lib/librte_eal/common/include/rte_vdev.h  | 131 ------------
 lib/librte_eal/linuxapp/eal/Makefile      |   3 +-
 lib/librte_eal/rte_eal_version.map        |   4 -
 mk/rte.app.mk                             |   1 +
 test/test/test_cryptodev.c                |   1 +
 test/test/test_event_eth_rx_adapter.c     |   1 +
 test/test/test_eventdev.c                 |   1 +
 test/test/test_eventdev_octeontx.c        |   1 +
 test/test/test_eventdev_sw.c              |   1 +
 test/test/test_link_bonding_rssconf.c     |   1 +
 24 files changed, 591 insertions(+), 509 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/rte_vdev.h
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 82ee754..d39e657 100644
--- a/config/common_base
+++ b/config/common_base
@@ -814,3 +814,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index bab5d73..08b1c3d 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -406,6 +406,13 @@ API Changes
 * ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
   in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
+* **Moved the following APIs from eal library to bus_vdev library**
+
+  * ``rte_vdev_init``
+  * ``rte_vdev_register``
+  * ``rte_vdev_uninit``
+  * ``rte_vdev_unregister``
+
 ABI Changes
 -----------
 
@@ -461,6 +468,7 @@ The libraries prepended with a plus sign were incremented in this version.
 
      librte_acl.so.2
    + librte_bitratestats.so.2
+   + librte_bus_vdev.so.1
      librte_cfgfile.so.2
      librte_cmdline.so.2
    + librte_cryptodev.so.4
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index a220d27..6c7e203 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -30,12 +30,12 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-
 DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 
 DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..fe31654
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,57 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+LDLIBS += -lrte_eal
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..6ccb789
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+};
diff --git a/drivers/bus/vdev/rte_vdev.h b/drivers/bus/vdev/rte_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..a16eb71
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,344 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index d551541..1cb4cdb 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
+core-libs += librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
index 05dec1b..9c9ae82 100644
--- a/drivers/event/Makefile
+++ b/drivers/event/Makefile
@@ -31,7 +31,7 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_ether librte_eventdev
+core-libs := librte_eal librte_ether librte_eventdev librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV) += skeleton
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index cf33233..00be153 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -37,7 +37,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD),d)
 endif
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-core-libs += librte_net librte_kvargs
+core-libs += librte_net librte_kvargs librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DIRS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 934c12b..5d9ace9 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -48,7 +48,7 @@ LDLIBS += -lgcc_s
 
 EXPORT_MAP := ../../rte_eal_version.map
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 # specific to bsdapp exec-env
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
@@ -67,7 +67,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 16a2f26..9effd0d 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -39,7 +39,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 4c4ac7e..8088dcc 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -170,28 +170,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -316,4 +294,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 1d3a42d..2975c25c 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -37,7 +37,7 @@ ARCH_DIR ?= $(RTE_ARCH)
 EXPORT_MAP := ../../rte_eal_version.map
 VPATH += $(RTE_SDK)/lib/librte_eal/common/arch/$(ARCH_DIR)
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 VPATH += $(RTE_SDK)/lib/librte_eal/common
 
@@ -74,7 +74,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index d2a4ff9..5966a03 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -166,10 +166,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_vdev_init;
-	rte_vdev_register;
-	rte_vdev_uninit;
-	rte_vdev_unregister;
 	vfio_get_container_fd;
 	vfio_get_group_fd;
 	vfio_get_group_no;
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 047121d..de2f557 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -101,6 +101,7 @@ _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 72988c5..9045873 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_pause.h>
+#include <rte_vdev.h>
 
 #include <rte_crypto.h>
 #include <rte_cryptodev.h>
diff --git a/test/test/test_event_eth_rx_adapter.c b/test/test/test_event_eth_rx_adapter.c
index 56ed1f8..c0b864b 100644
--- a/test/test/test_event_eth_rx_adapter.c
+++ b/test/test/test_event_eth_rx_adapter.c
@@ -35,6 +35,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
+#include <rte_vdev.h>
 
 #include <rte_event_eth_rx_adapter.h>
 
diff --git a/test/test/test_eventdev.c b/test/test/test_eventdev.c
index 4118b75..a56f5a2 100644
--- a/test/test/test_eventdev.c
+++ b/test/test/test_eventdev.c
@@ -37,6 +37,7 @@
 #include <rte_memcpy.h>
 #include <rte_eventdev.h>
 #include <rte_dev.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_octeontx.c b/test/test/test_eventdev_octeontx.c
index b88b0d2..ecae3e9 100644
--- a/test/test/test_eventdev_octeontx.c
+++ b/test/test/test_eventdev_octeontx.c
@@ -45,6 +45,7 @@
 #include <rte_lcore.h>
 #include <rte_per_lcore.h>
 #include <rte_random.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_sw.c b/test/test/test_eventdev_sw.c
index 5c7751b..5e41140 100644
--- a/test/test/test_eventdev_sw.c
+++ b/test/test/test_eventdev_sw.c
@@ -51,6 +51,7 @@
 #include <rte_pause.h>
 #include <rte_service.h>
 #include <rte_service_component.h>
+#include <rte_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_link_bonding_rssconf.c b/test/test/test_link_bonding_rssconf.c
index 7dccc6e..6199188 100644
--- a/test/test/test_link_bonding_rssconf.c
+++ b/test/test/test_link_bonding_rssconf.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_lcore.h>
 #include <rte_memory.h>
+#include <rte_vdev.h>
 
 #include <rte_string_fns.h>
 #include <rte_errno.h>
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v10 4/4] bus/vdev: change log type
  2017-10-27  3:23   ` [PATCH v10 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-27  3:23     ` [PATCH v10 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-27  3:23     ` Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-27  3:23 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use specialized dynamic log type for vdev bus logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Suggested-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      | 20 ++++++++++++++++----
 drivers/bus/vdev/vdev_logs.h | 45 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index a16eb71..be2be6f 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,9 @@
 #include <rte_errno.h>
 
 #include "rte_vdev.h"
+#include "vdev_logs.h"
+
+int vdev_logtype_bus;
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +106,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +193,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -213,7 +216,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -294,7 +297,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
@@ -342,3 +345,12 @@ static struct rte_bus rte_vdev_bus = {
 };
 
 RTE_REGISTER_BUS(vdev, rte_vdev_bus);
+
+RTE_INIT(vdev_init_log);
+static void
+vdev_init_log(void)
+{
+	vdev_logtype_bus = rte_log_register("bus.vdev");
+	if (vdev_logtype_bus >= 0)
+		rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE);
+}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..43b0ab8
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,45 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#include <rte_log.h>
+
+extern int vdev_logtype_bus;
+
+#define VDEV_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, vdev_logtype_bus, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-27  1:06     ` [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-27  7:56       ` Thomas Monjalon
  2017-10-27  8:19         ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Monjalon @ 2017-10-27  7:56 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit

27/10/2017 03:06, Jianfeng Tan:
> --- /dev/null
> +++ b/drivers/bus/vdev/rte_bus_vdev_version.map
> @@ -0,0 +1,8 @@
> +DPDK_17.11 {
> +       global:
> +
> +       rte_vdev_init;
> +       rte_vdev_register;
> +       rte_vdev_uninit;
> +       rte_vdev_unregister;
> +};

It should not be needed to export the driver ops.

Please can you try to make it private?

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-27  7:56       ` Thomas Monjalon
@ 2017-10-27  8:19         ` Tan, Jianfeng
  2017-10-27  8:53           ` Thomas Monjalon
  0 siblings, 1 reply; 158+ messages in thread
From: Tan, Jianfeng @ 2017-10-27  8:19 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, jblunck, Richardson, Bruce, Ananyev, Konstantin,
	De Lara Guarch, Pablo, yliu, maxime.coquelin, mtetsuyah, Yigit,
	Ferruh



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Friday, October 27, 2017 3:56 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; jblunck@infradead.org; Richardson, Bruce; Ananyev,
> Konstantin; De Lara Guarch, Pablo; yliu@fridaylinux.org;
> maxime.coquelin@redhat.com; mtetsuyah@gmail.com; Yigit, Ferruh
> Subject: Re: [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus
> 
> 27/10/2017 03:06, Jianfeng Tan:
> > --- /dev/null
> > +++ b/drivers/bus/vdev/rte_bus_vdev_version.map
> > @@ -0,0 +1,8 @@
> > +DPDK_17.11 {
> > +       global:
> > +
> > +       rte_vdev_init;
> > +       rte_vdev_register;
> > +       rte_vdev_uninit;
> > +       rte_vdev_unregister;
> > +};
> 
> It should not be needed to export the driver ops.

rte_vdev_register/unregister are needed by vdev PMDs, which are needed to export, isn't it?

And for rte_vdev_init()/rte_vdev_uninit(), do you mean we all change to use rte_eal_dev_attach()/detach()?

> 
> Please can you try to make it private?

Even we want to make it private, I think it needs deprecation notice, which we can further improved for the next release?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-27  8:19         ` Tan, Jianfeng
@ 2017-10-27  8:53           ` Thomas Monjalon
  2017-10-27 16:57             ` Gaëtan Rivet
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Monjalon @ 2017-10-27  8:53 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: dev, jblunck, Richardson, Bruce, Ananyev, Konstantin,
	De Lara Guarch, Pablo, yliu, maxime.coquelin, mtetsuyah, Yigit,
	Ferruh, gaetan.rivet

27/10/2017 10:19, Tan, Jianfeng:
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > 27/10/2017 03:06, Jianfeng Tan:
> > > --- /dev/null
> > > +++ b/drivers/bus/vdev/rte_bus_vdev_version.map
> > > @@ -0,0 +1,8 @@
> > > +DPDK_17.11 {
> > > +       global:
> > > +
> > > +       rte_vdev_init;
> > > +       rte_vdev_register;
> > > +       rte_vdev_uninit;
> > > +       rte_vdev_unregister;
> > > +};
> > 
> > It should not be needed to export the driver ops.
> 
> rte_vdev_register/unregister are needed by vdev PMDs, which are needed to export, isn't it?

Yes you're right, I overlooked it.

> And for rte_vdev_init()/rte_vdev_uninit(), do you mean we all change to use rte_eal_dev_attach()/detach()?

rte_vdev_init() is mostly used in tests.
I changed my mind, you can keep it.
Maybe it would be clearer to rename rte_vdev.h to rte_bus_vdev.h
to mimic what was done for PCI. So rte_bus_*.h are mainly for PMDs
and not to be used by common applications.

> > Please can you try to make it private?
> 
> Even we want to make it private, I think it needs deprecation notice, which we can further improved for the next release?

Yes we can revise usage of rte_vdev_init(), rte_eal_dev_attach() and
rte_eal_hotplug_add() in the next release.

Gaetan, do you have any comment?

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-27  8:53           ` Thomas Monjalon
@ 2017-10-27 16:57             ` Gaëtan Rivet
  0 siblings, 0 replies; 158+ messages in thread
From: Gaëtan Rivet @ 2017-10-27 16:57 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Tan, Jianfeng, dev, jblunck, Richardson, Bruce, Ananyev,
	Konstantin, De Lara Guarch, Pablo, yliu, maxime.coquelin,
	mtetsuyah, Yigit, Ferruh

On Fri, Oct 27, 2017 at 10:53:11AM +0200, Thomas Monjalon wrote:
> 27/10/2017 10:19, Tan, Jianfeng:
> > From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > > 27/10/2017 03:06, Jianfeng Tan:
> > > > --- /dev/null
> > > > +++ b/drivers/bus/vdev/rte_bus_vdev_version.map
> > > > @@ -0,0 +1,8 @@
> > > > +DPDK_17.11 {
> > > > +       global:
> > > > +
> > > > +       rte_vdev_init;
> > > > +       rte_vdev_register;
> > > > +       rte_vdev_uninit;
> > > > +       rte_vdev_unregister;
> > > > +};
> > > 
> > > It should not be needed to export the driver ops.
> > 
> > rte_vdev_register/unregister are needed by vdev PMDs, which are needed to export, isn't it?
> 
> Yes you're right, I overlooked it.
> 
> > And for rte_vdev_init()/rte_vdev_uninit(), do you mean we all change to use rte_eal_dev_attach()/detach()?
> 
> rte_vdev_init() is mostly used in tests.
> I changed my mind, you can keep it.
> Maybe it would be clearer to rename rte_vdev.h to rte_bus_vdev.h
> to mimic what was done for PCI. So rte_bus_*.h are mainly for PMDs
> and not to be used by common applications.
> 
> > > Please can you try to make it private?
> > 
> > Even we want to make it private, I think it needs deprecation notice, which we can further improved for the next release?
> 
> Yes we can revise usage of rte_vdev_init(), rte_eal_dev_attach() and
> rte_eal_hotplug_add() in the next release.
> 
> Gaetan, do you have any comment?

Well, as stated before, I agree that deprecating attach / detach seems
good to me. The hotplug API supersedes it and the only difference from a
user PoV is the artificial restriction to vdev and PCI buses.

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v11 0/4] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (12 preceding siblings ...)
  2017-10-27  3:23   ` [PATCH v10 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-30  8:28   ` Jianfeng Tan
  2017-10-30  8:28     ` [PATCH v11 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
                       ` (3 more replies)
  2017-11-07  6:54   ` [PATCH v12 0/4] move vdev into drivers/bus Jianfeng Tan
  14 siblings, 4 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-30  8:28 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v11:
  - Rename rte_vdev.h to rte_bus_vdev.h as suggested by Thomas.

v10:
  - Rebase on 17.11-rc2.

v9:
  - Avoid bumping library version (eal, crypto) as other commits in this
    release already do that as suggested by Pablo.
  - Move vdev's dir dependency to its own folder as suggested by Gaetan.

v8: (Suggested by Pablo)
  - As we bump the library version and add new library (bus_vdev), we
    need to update those in release note.
  - Fix compiling issue in test as of missing rte_vdev.h.
  - Move vdev API symbols from eal to bus_vdev; update in release note.

v7:
  - Add notice in release note for API change, and bump library version
    of librte_cryptodev and librte_eal, as suggested by Thomas.

v6:
  - Don't introduce the static log type for bug, instead we use dynamic
    log type for vdev, suggested by Shreyansh Jain.

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we move all bus drivers from EAL to
drivers/bus/. This patch set targets vdev bus.


Jianfeng Tan (4):
  cryptodev: remove crypto vdev init API
  eal: remove dependency on vdev
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: change log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 doc/guides/rel_notes/release_17_11.rst         |  11 +
 drivers/bus/Makefile                           |   4 +-
 drivers/bus/vdev/Makefile                      |  57 ++++
 drivers/bus/vdev/rte_bus_vdev.h                | 153 +++++++++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |   8 +
 drivers/bus/vdev/vdev.c                        | 356 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  45 ++++
 drivers/crypto/Makefile                        |   1 +
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c       |   2 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c     |   2 +-
 drivers/crypto/armv8/rte_armv8_pmd.c           |   2 +-
 drivers/crypto/kasumi/rte_kasumi_pmd.c         |   2 +-
 drivers/crypto/mrvl/rte_mrvl_pmd.c             |   2 +-
 drivers/crypto/null/null_crypto_pmd.c          |   2 +-
 drivers/crypto/openssl/rte_openssl_pmd.c       |   2 +-
 drivers/crypto/scheduler/scheduler_pmd.c       |   2 +-
 drivers/crypto/snow3g/rte_snow3g_pmd.c         |   2 +-
 drivers/crypto/zuc/rte_zuc_pmd.c               |   2 +-
 drivers/event/Makefile                         |   2 +-
 drivers/event/dpaa2/dpaa2_eventdev.c           |   2 +-
 drivers/event/octeontx/ssovf_evdev.c           |   2 +-
 drivers/event/skeleton/skeleton_eventdev.c     |   2 +-
 drivers/event/sw/sw_evdev.c                    |   2 +-
 drivers/net/Makefile                           |   2 +-
 drivers/net/af_packet/rte_eth_af_packet.c      |   2 +-
 drivers/net/bonding/rte_eth_bond_api.c         |   2 +-
 drivers/net/bonding/rte_eth_bond_pmd.c         |   2 +-
 drivers/net/failsafe/failsafe.c                |   2 +-
 drivers/net/kni/rte_eth_kni.c                  |   2 +-
 drivers/net/mrvl/mrvl_ethdev.c                 |   2 +-
 drivers/net/null/rte_eth_null.c                |   2 +-
 drivers/net/octeontx/octeontx_ethdev.c         |   2 +-
 drivers/net/pcap/rte_eth_pcap.c                |   2 +-
 drivers/net/ring/rte_eth_ring.c                |   2 +-
 drivers/net/softnic/rte_eth_softnic.c          |   2 +-
 drivers/net/tap/rte_eth_tap.c                  |   2 +-
 drivers/net/vhost/rte_eth_vhost.c              |   2 +-
 drivers/net/virtio/virtio_user_ethdev.c        |   2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   3 +-
 lib/librte_eal/common/.eal_common_dev.c.swp    | Bin 0 -> 16384 bytes
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  22 +-
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_vdev.h       | 131 ---------
 lib/librte_eal/linuxapp/eal/Makefile           |   3 +-
 lib/librte_eal/rte_eal_version.map             |   4 -
 lib/librte_ether/rte_ethdev_vdev.h             |   2 +-
 lib/librte_eventdev/rte_eventdev_pmd_vdev.h    |   2 +-
 mk/rte.app.mk                                  |   1 +
 test/test/autotest_data.pyc                    | Bin 0 -> 6122 bytes
 test/test/autotest_test_funcs.pyc              | Bin 0 -> 6812 bytes
 test/test/test_cryptodev.c                     |   1 +
 test/test/test_event_eth_rx_adapter.c          |   1 +
 test/test/test_eventdev.c                      |   1 +
 test/test/test_eventdev_octeontx.c             |   1 +
 test/test/test_eventdev_sw.c                   |   1 +
 test/test/test_link_bonding_rssconf.c          |   1 +
 63 files changed, 687 insertions(+), 584 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev.h
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 create mode 100644 lib/librte_eal/common/.eal_common_dev.c.swp
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h
 create mode 100644 test/test/autotest_data.pyc
 create mode 100644 test/test/autotest_test_funcs.pyc

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v11 1/4] cryptodev: remove crypto vdev init API
  2017-10-30  8:28   ` [PATCH v11 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-10-30  8:28     ` Jianfeng Tan
  2017-10-30  8:28     ` [PATCH v11 2/4] eal: remove dependency on vdev Jianfeng Tan
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-30  8:28 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 doc/guides/rel_notes/release_17_11.rst         |  2 ++
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 5 files changed, 2 insertions(+), 29 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index a93c3e1..9120121 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -60,10 +60,5 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * librte_meter: The API will change to accommodate configuration profiles.
   Most of the API functions will have an additional opaque parameter.
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index b96b236..bab5d73 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -403,6 +403,8 @@ API Changes
   the backing device supports the operation or if the operation was
   successfully performed.
 
+* ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
+  in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
 ABI Changes
 -----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 8063211..973c8db 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index a0d3a12..2c1377b 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -435,23 +435,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e82296c..eb47308 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v11 2/4] eal: remove dependency on vdev
  2017-10-30  8:28   ` [PATCH v11 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-30  8:28     ` [PATCH v11 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-10-30  8:28     ` Jianfeng Tan
  2017-10-30  8:28     ` [PATCH v11 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
  2017-10-30  8:28     ` [PATCH v11 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-30  8:28 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..dda8f58 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,13 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL,
+		"Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v11 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-30  8:28   ` [PATCH v11 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-10-30  8:28     ` [PATCH v11 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-10-30  8:28     ` [PATCH v11 2/4] eal: remove dependency on vdev Jianfeng Tan
@ 2017-10-30  8:28     ` Jianfeng Tan
  2017-11-07  2:43       ` Thomas Monjalon
  2017-10-30  8:28     ` [PATCH v11 4/4] bus/vdev: change log type Jianfeng Tan
  3 siblings, 1 reply; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-30  8:28 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                          |   5 +
 doc/guides/rel_notes/release_17_11.rst      |   9 +
 drivers/bus/Makefile                        |   4 +-
 drivers/bus/vdev/Makefile                   |  57 +++++
 drivers/bus/vdev/rte_bus_vdev.h             | 153 +++++++++++++
 drivers/bus/vdev/rte_bus_vdev_version.map   |   8 +
 drivers/bus/vdev/vdev.c                     | 344 ++++++++++++++++++++++++++++
 drivers/crypto/Makefile                     |   1 +
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c    |   2 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c  |   2 +-
 drivers/crypto/armv8/rte_armv8_pmd.c        |   2 +-
 drivers/crypto/kasumi/rte_kasumi_pmd.c      |   2 +-
 drivers/crypto/mrvl/rte_mrvl_pmd.c          |   2 +-
 drivers/crypto/null/null_crypto_pmd.c       |   2 +-
 drivers/crypto/openssl/rte_openssl_pmd.c    |   2 +-
 drivers/crypto/scheduler/scheduler_pmd.c    |   2 +-
 drivers/crypto/snow3g/rte_snow3g_pmd.c      |   2 +-
 drivers/crypto/zuc/rte_zuc_pmd.c            |   2 +-
 drivers/event/Makefile                      |   2 +-
 drivers/event/dpaa2/dpaa2_eventdev.c        |   2 +-
 drivers/event/octeontx/ssovf_evdev.c        |   2 +-
 drivers/event/skeleton/skeleton_eventdev.c  |   2 +-
 drivers/event/sw/sw_evdev.c                 |   2 +-
 drivers/net/Makefile                        |   2 +-
 drivers/net/af_packet/rte_eth_af_packet.c   |   2 +-
 drivers/net/bonding/rte_eth_bond_api.c      |   2 +-
 drivers/net/bonding/rte_eth_bond_pmd.c      |   2 +-
 drivers/net/failsafe/failsafe.c             |   2 +-
 drivers/net/kni/rte_eth_kni.c               |   2 +-
 drivers/net/mrvl/mrvl_ethdev.c              |   2 +-
 drivers/net/null/rte_eth_null.c             |   2 +-
 drivers/net/octeontx/octeontx_ethdev.c      |   2 +-
 drivers/net/pcap/rte_eth_pcap.c             |   2 +-
 drivers/net/ring/rte_eth_ring.c             |   2 +-
 drivers/net/softnic/rte_eth_softnic.c       |   2 +-
 drivers/net/tap/rte_eth_tap.c               |   2 +-
 drivers/net/vhost/rte_eth_vhost.c           |   2 +-
 drivers/net/virtio/virtio_user_ethdev.c     |   2 +-
 lib/librte_eal/bsdapp/eal/Makefile          |   3 +-
 lib/librte_eal/common/.eal_common_dev.c.swp | Bin 0 -> 16384 bytes
 lib/librte_eal/common/Makefile              |   2 +-
 lib/librte_eal/common/eal_common_vdev.c     | 342 ---------------------------
 lib/librte_eal/common/include/rte_dev.h     |  24 +-
 lib/librte_eal/common/include/rte_vdev.h    | 131 -----------
 lib/librte_eal/linuxapp/eal/Makefile        |   3 +-
 lib/librte_eal/rte_eal_version.map          |   4 -
 lib/librte_ether/rte_ethdev_vdev.h          |   2 +-
 lib/librte_eventdev/rte_eventdev_pmd_vdev.h |   2 +-
 mk/rte.app.mk                               |   1 +
 test/test/autotest_data.pyc                 | Bin 0 -> 6122 bytes
 test/test/autotest_test_funcs.pyc           | Bin 0 -> 6812 bytes
 test/test/test_cryptodev.c                  |   1 +
 test/test/test_event_eth_rx_adapter.c       |   1 +
 test/test/test_eventdev.c                   |   1 +
 test/test/test_eventdev_octeontx.c          |   1 +
 test/test/test_eventdev_sw.c                |   1 +
 test/test/test_link_bonding_rssconf.c       |   1 +
 57 files changed, 622 insertions(+), 539 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev.h
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 lib/librte_eal/common/.eal_common_dev.c.swp
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h
 create mode 100644 test/test/autotest_data.pyc
 create mode 100644 test/test/autotest_test_funcs.pyc

diff --git a/config/common_base b/config/common_base
index 82ee754..d39e657 100644
--- a/config/common_base
+++ b/config/common_base
@@ -814,3 +814,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index bab5d73..8f76ecd 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -406,6 +406,14 @@ API Changes
 * ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
   in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
+* **Moved vdev bus APIs outside of the EAL**
+
+  Moved the following APIs from ``librte_eal`` to ``librte_bus_vdev``:
+  * ``rte_vdev_init``
+  * ``rte_vdev_register``
+  * ``rte_vdev_uninit``
+  * ``rte_vdev_unregister``
+
 ABI Changes
 -----------
 
@@ -461,6 +469,7 @@ The libraries prepended with a plus sign were incremented in this version.
 
      librte_acl.so.2
    + librte_bitratestats.so.2
+   + librte_bus_vdev.so.1
      librte_cfgfile.so.2
      librte_cmdline.so.2
    + librte_cryptodev.so.4
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index a220d27..6c7e203 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -30,12 +30,12 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-
 DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 
 DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..84bd724
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,57 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+LDLIBS += -lrte_eal
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_bus_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..6ccb789
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+};
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..04ed49b
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,344 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_bus_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index d551541..1cb4cdb 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
+core-libs += librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index 1d18217..88554c3 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -35,7 +35,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 #include <rte_byteorder.h>
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index a589557..7004389 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -36,7 +36,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index 2d2f3ff..97719f2 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -36,7 +36,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index 7c1b56b..e76821d 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -35,7 +35,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/mrvl/rte_mrvl_pmd.c b/drivers/crypto/mrvl/rte_mrvl_pmd.c
index 63895c5..1f09d7d 100644
--- a/drivers/crypto/mrvl/rte_mrvl_pmd.c
+++ b/drivers/crypto/mrvl/rte_mrvl_pmd.c
@@ -36,7 +36,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 4b9a58a..62a2802 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -33,7 +33,7 @@
 #include <rte_common.h>
 #include <rte_config.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 
 #include "null_crypto_pmd_private.h"
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 25c1154..06e1a6d 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -34,7 +34,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/scheduler/scheduler_pmd.c b/drivers/crypto/scheduler/scheduler_pmd.c
index 40ab304..acdf636 100644
--- a/drivers/crypto/scheduler/scheduler_pmd.c
+++ b/drivers/crypto/scheduler/scheduler_pmd.c
@@ -33,7 +33,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 #include <rte_reorder.h>
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index fe7bb86..2738b2c 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -35,7 +35,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index b99f6ec..1f4ca7b 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -35,7 +35,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
index 05dec1b..9c9ae82 100644
--- a/drivers/event/Makefile
+++ b/drivers/event/Makefile
@@ -31,7 +31,7 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-core-libs := librte_eal librte_ether librte_eventdev
+core-libs := librte_eal librte_ether librte_eventdev librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV) += skeleton
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw
diff --git a/drivers/event/dpaa2/dpaa2_eventdev.c b/drivers/event/dpaa2/dpaa2_eventdev.c
index 45e2ebc..c293087 100644
--- a/drivers/event/dpaa2/dpaa2_eventdev.c
+++ b/drivers/event/dpaa2/dpaa2_eventdev.c
@@ -52,7 +52,7 @@
 #include <rte_memory.h>
 #include <rte_memzone.h>
 #include <rte_pci.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_ethdev.h>
 #include <rte_event_eth_rx_adapter.h>
 
diff --git a/drivers/event/octeontx/ssovf_evdev.c b/drivers/event/octeontx/ssovf_evdev.c
index cfbd958..7606b60 100644
--- a/drivers/event/octeontx/ssovf_evdev.c
+++ b/drivers/event/octeontx/ssovf_evdev.c
@@ -43,7 +43,7 @@
 #include <rte_malloc.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "ssovf_evdev.h"
 
diff --git a/drivers/event/skeleton/skeleton_eventdev.c b/drivers/event/skeleton/skeleton_eventdev.c
index 4d1a1da..70bb186 100644
--- a/drivers/event/skeleton/skeleton_eventdev.c
+++ b/drivers/event/skeleton/skeleton_eventdev.c
@@ -47,7 +47,7 @@
 #include <rte_memory.h>
 #include <rte_memzone.h>
 #include <rte_lcore.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "skeleton_eventdev.h"
 
diff --git a/drivers/event/sw/sw_evdev.c b/drivers/event/sw/sw_evdev.c
index 178f169..0b54afa 100644
--- a/drivers/event/sw/sw_evdev.c
+++ b/drivers/event/sw/sw_evdev.c
@@ -33,7 +33,7 @@
 #include <inttypes.h>
 #include <string.h>
 
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_memzone.h>
 #include <rte_kvargs.h>
 #include <rte_ring.h>
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index cf33233..00be153 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -37,7 +37,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD),d)
 endif
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
-core-libs += librte_net librte_kvargs
+core-libs += librte_net librte_kvargs librte_bus_vdev
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DIRS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 28e6a94..fa84eb9 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -41,7 +41,7 @@
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
 #include <rte_kvargs.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include <linux/if_ether.h>
 #include <linux/if_packet.h>
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index 8c602f8..980e636 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -37,7 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_ethdev.h>
 #include <rte_tcp.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 
 #include "rte_eth_bond.h"
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index af33529..9f66dfc 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -43,7 +43,7 @@
 #include <rte_ip_frag.h>
 #include <rte_devargs.h>
 #include <rte_kvargs.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_alarm.h>
 #include <rte_cycles.h>
 
diff --git a/drivers/net/failsafe/failsafe.c b/drivers/net/failsafe/failsafe.c
index 6006bef..6bc5aba 100644
--- a/drivers/net/failsafe/failsafe.c
+++ b/drivers/net/failsafe/failsafe.c
@@ -37,7 +37,7 @@
 #include <rte_ethdev_vdev.h>
 #include <rte_devargs.h>
 #include <rte_kvargs.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "failsafe_private.h"
 
diff --git a/drivers/net/kni/rte_eth_kni.c b/drivers/net/kni/rte_eth_kni.c
index d68ff7a..36e90fd 100644
--- a/drivers/net/kni/rte_eth_kni.c
+++ b/drivers/net/kni/rte_eth_kni.c
@@ -40,7 +40,7 @@
 #include <rte_kni.h>
 #include <rte_kvargs.h>
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 /* Only single queue supported */
 #define KNI_MAX_QUEUE_PER_PORT 1
diff --git a/drivers/net/mrvl/mrvl_ethdev.c b/drivers/net/mrvl/mrvl_ethdev.c
index 03d9fec..c60ee37 100644
--- a/drivers/net/mrvl/mrvl_ethdev.c
+++ b/drivers/net/mrvl/mrvl_ethdev.c
@@ -36,7 +36,7 @@
 #include <rte_kvargs.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 /* Unluckily, container_of is defined by both DPDK and MUSDK,
  * we'll declare only one version.
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 3433c9c..032c30e 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -36,7 +36,7 @@
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
 
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 86de5d1..bd24ec3 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -44,7 +44,7 @@
 #include <rte_kvargs.h>
 #include <rte_malloc.h>
 #include <rte_prefetch.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "octeontx_ethdev.h"
 #include "octeontx_rxtx.h"
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 3205df8..f683d3a 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -44,7 +44,7 @@
 #include <rte_kvargs.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #define RTE_ETH_PCAP_SNAPSHOT_LEN 65535
 #define RTE_ETH_PCAP_SNAPLEN ETHER_MAX_JUMBO_FRAME_LEN
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index d82d207..cdc3cc1 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -38,7 +38,7 @@
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
 #include <rte_string_fns.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_errno.h>
 
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index abb617a..3e47c2f 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -38,7 +38,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_errno.h>
 #include <rte_ring.h>
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 64dd3b0..6b27679 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -39,7 +39,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_net.h>
 #include <rte_debug.h>
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index f98c980..53f61f0 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -39,7 +39,7 @@
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_vhost.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 0cfa27b..7be57ce 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -40,7 +40,7 @@
 #include <rte_malloc.h>
 #include <rte_kvargs.h>
 #include <rte_ethdev_vdev.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_alarm.h>
 
 #include "virtio_ethdev.h"
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 934c12b..5d9ace9 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -48,7 +48,7 @@ LDLIBS += -lgcc_s
 
 EXPORT_MAP := ../../rte_eal_version.map
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 # specific to bsdapp exec-env
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
@@ -67,7 +67,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/common/.eal_common_dev.c.swp b/lib/librte_eal/common/.eal_common_dev.c.swp
new file mode 100644
index 0000000000000000000000000000000000000000..86626d122c3c6ce6980bc1ff0419c99ff5647222
GIT binary patch
literal 16384
zcmeI2Ym6IL6~`wj(6~v%qX_X3;>J;ky?7sKLn|fO4PJY8cZ%0uX2!c+NM(&Z<K1cP
z8E0m^VQDC+P$(3{LwtY=Xak4>f={%i`A}6zNQjq&RKbU~Qom5~6e4L6MbMW2xp&4M
zd%f9&FH~q&`mODm>vPZjpL6frIpg}&va-l-nm8)q?{$*&#JP*B-#Bucbn5VKDKH#5
zy5nDQsrcTh8+U9b-3fz}Yj!YccFfzyH%x0|vSrr^FR*Hs(VA?y?Y8So;%!a5t)bCG
zV`tMzi$sA$fgKgNR=VN(BU9AuVEO>N?hVx)zmYUZ6i5_E6i5_E6i5_E6i5_E6i5{K
z|4|_5?3O-);p`5FbVvBQYv}c=@bl^L_3Y63@MH3lD3B<SD3B<SD3B<SD3B<SD3B<S
zD3B<SD3B=d3RJ)_C21f0dLtD8@cciz|Nr-ECF#%L58zwiF0c+P@OJQ<{gU)k@Dp$r
zyc_)KT1h$wZUu8-H#iUD9&o`s!83a$=}X{d@bWb{4;*k1JeiWD&jA_a!F#|scni1+
z{ACY(0>1@62Hyc+0B6A+pbiX>2K&K2aN%l6`WtuxoCiMu-v{@CPl0>DNiYr4-~f=o
zORtfn7s2D;G4LSxHn<a<1mj=~WWmd?hF{>j;C}E~@M%y4`@mlC!mA|d5%4hhCO8Kk
z0H=WqRzU@n!7*?(_&bU&7r_PaD{vls6r2V%a0+|?oCMc^e;|g>gXh4L;Md@b;A3C|
z1i%LtI0y~^iu-jS{+DX38y*{TjJ9<g3DNAfTJ$@N8Xd?qT*nWXXi@L_ITk;FR)Yr&
zZ_Uq2eqaQ4Bm9yieOO9)R?zhvhL__~DwV?b#%IWUmOiSwTq{-PGqS4Yn4B-=Si0!h
z8<xi!hU2&aGp)dAtg~R<!rKkIVX@31KYPka=cJU~WEq&v@;=x!gOB4gU8mFPu4T{|
z9Y`rS5P2{zmn*tfUD~GK*{;u;U8fP)uEVHnzuW1!__>OS-pE<%F4hH`o@V80sgz}y
zNQ3<-<>h?o@<v+_!))4)N&d5@>x~{Los9LE;-4A)ng;J`^!-|WlVS&rMvuPd)d<lQ
zXTxaOX4G}Zb2n_$GACj~hv~Qj(8CGBsQQ7|ZQz4&hK<1^$|l}G{M?5pm55~~);bL7
z7)2|dEd5X+eCeVHyb<tJuzlt_t<8RTxMoWQg&EM0ergns!jHV)GG4?hN{aC3NVRo0
zpuDLWrYV9<DVk&AKWy^s4wC=_XtX==X6a7DPG?D;DR%ZO8_|IL3R@sw2ePskm(-=E
zMb$CtEsF&%<GEt=vL!Y(4j=Ll_ov2{WQ>^bVgK9tw?#*m9?BaeFNEs0Ehq3<lti%{
zq7I@YBB4TIqeEgU#qxuOuw6EZbQoBqM6`xhDX}iaR-!OE=vypABFcQVh<{c1%D6I=
z&Ed*MNsZ_auaYsRVVKq_O6q8Z+;B0s#<;10Jiml1QGy-`la9M<inZ}TxbjG;$uZ{N
zZg-dv!-^&_RGUPSUurnv$pO!{43Q?BWnSi3aiy`HMyqRDEKNV_>%dtfuqM{iu`?%V
z!nNGBiS?O&bAHgY>fMot`P>`Teq-xFBn%ylnf5pR$<tk{3qRsLB8<Ui$KtJfZl6Fr
zY-h*`KQL{V8zoWM7-Ot5$Mgk7V_IcSU&*U7E?vuVnJIHDUtCr+xhPu5Y^kDY%B)gS
z^i?{fRSOHOm|x7#%M-#<MkyCc)uK|KXJvW5q|D3Zg3Kx^tLO`|x&m8SmRA*x8YpF!
zFR!wdJZx3<sEev53sd+)MdjU;l)UIO$5s|(GDP1kRLZ)VFX%a@>8euDS*#g4)GMkk
z3>EWwK1V(*sg*fJ*N)Ts*(!XHH4T<@T&$~0x>6};*+OLnLswZL4?l|V4@2i}3R5Lz
zQPFW+ujI&Dp{mM@a+&+CRcAF_(W|=5<|~z=MxAJ~x~vpr^jLy$G(uR-2~*mVTu^9(
zAm1V{E|v1?D)$ki(&YD5VH77rZ8g@HH3!dih6}&2Qdud(TXe<MP;joIYHU{KVw7Yy
zhf^eSQBh@*N-6i>6_g^nfeXS^o-O57T`5%I3tOtHh_#GZ$@s2TDCLz!xi~?(mn%Fw
zbfzujOC=<ZjLw%<Rb_r5bSkbAomMbD1*##n)I0_zb14>OwXlGXVQjh92oDbm+!juy
z^N5g^<|k<!@-0g$MGeE+YL$i;X5WxZ1KACO6ue~&zsP1+2S<PmC>3RBNTH953V(!4
zm@lm9xozy>aOw8lW^l&vEOy2Y*4-|4SsklkH?d{Ja)Hao8P5&^%V8bMYumn$y;wL?
z$PCsqOwf8aa6O;3jZId!Sl7p@hpVFHm^f-N*uaIS?FJUTn%I~4xXjSHX-58xv9g8U
zvB{)sCtv5?CR3ciYO#XrVbg~_EZ+q7TVT`CWOm?3HW)K)S}owrppX1=>^Ar{P?*8C
zWD;JvyvH_HM9(%_{mUa)f;{P)#_khWkepDgg?^}W4BoV<GoNpCsGp|WYPn~yVv#eA
zmSMLsCfkV&jWN}Vd+FmGtJ{v@ZPK2p&Dvd<_AH?j_7*T{)ZGmWeRVcHdu=_4OflLK
z|JOeCLb%l<49s`C9<G-S7Z;AuqriZtqumi6Q3kcG;F$Q-c1=nlE_V()5QLu62Z?0%
zb|Ell1l(p{wZ5dn&Y)aeW~3LX7Wzm#%$R_<C89K@oD0(#c7&;XtHrp2J_PnH59t@G
zP>8h6G_vgasUt_(jVoAYm^P8$rp44aZ?+{tC)hT<2p49xB9^s+j0IAf92=MD{y&TR
z(-htJ;{HE+zW*HV@h^f$!2{r4un1<ragYN4!ae^#!3*FK@OAK2@CnccI+zF3-~@OR
z*bRP;y1=90Vek;R53GWl!A;;OxB=_}e?`sUY48+y415oK1>6Jf1|J8ffC^568Spmn
zdhilz3@?H|0;)Uw68r*u27C}qgDLP1un(lb9&iD*h-blr;LG4{a2M!;+kg#j1v&6m
zupjINyTJ3PQ~Vx03w{Ug2VVo91P(Ak15AS~xPThPGvI0P6nGp^J);fY4_3f3V1Viw
zKSP{;1RerE1owf@0~Hj&o55Z{@!SKFzeIsVfkc5sfgKbWE=oo<Alzb8v7qKzZES+5
zz9R|>I8JYP!Sa7vzwA|tMpR<rg+!`kt@Vlly^1N7TcUwbF%uu-l@}UXR7K_WM0}=V
zA{9AN$cWWEaxqIo#iD+Rl`52%uJq1D)mBln9W1)CI=1&H{|uIUxy`V7tQxw-3EZer
z{dEVO;`XVtxHxn!*26aSR{BPiD7=D1<snh(9$gWFSFsb+$*B5PRE-QXF<!?B-Ha+r
zqB<W1HeN#&UNk++%7o*xJdc;4jtRN=DbwI-9ljr*iPt$VcV1B0j%>pVeEk@9B<P!J
z{!<uj+yP$qTyyDet=F8wbfuFjtOU~yg2>UKETM-2@QK`r5_-!+fe~(q=2Uww%FB^o
zQBLfXOCl*p%sTPl0Dcan6aP#(H$Jo7TpKFB4Nkh$R{uvn4)O6ECBrlGGQKe!aNEJ1
zOOW9?f-vpe<*<Q{fm?E(e(;_$O=Mor5Q$4d_my9i7jb~EPR5{M_=tx>xZ!PNj^vnc
zf5>v1nK4)uqk{=bIf`E22HEdfk$8O_RtBGP^(GWTLhZTE;WXH?u0+p|u3&Ma%)9KR
zjW>=hJ6jxh1uSgwM~3mm4Em95D0~|TVQiJdiKrkxcp|?1VHJokbD^>9z(b^HS)_+F
z@y5Ln#t%l}jIW7dzWEM{O-|4ZGqYtmc<y+}KX%B^9rDvTnwC5ZsFr|-ns7Syz=ke|
zI5KiQaJwy&$C~FUN<BQ+qD6{&-{xTmU#>*9#*!S4QRjF;*7lqh*W;;6y3F3i@ZbPZ
Nz%;1^3>J<{{{d!`pU?mR

literal 0
HcmV?d00001

diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 16a2f26..9effd0d 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -39,7 +39,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 4c4ac7e..8088dcc 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -170,28 +170,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -316,4 +294,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 1d3a42d..2975c25c 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -37,7 +37,7 @@ ARCH_DIR ?= $(RTE_ARCH)
 EXPORT_MAP := ../../rte_eal_version.map
 VPATH += $(RTE_SDK)/lib/librte_eal/common/arch/$(ARCH_DIR)
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 VPATH += $(RTE_SDK)/lib/librte_eal/common
 
@@ -74,7 +74,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index d2a4ff9..5966a03 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -166,10 +166,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_vdev_init;
-	rte_vdev_register;
-	rte_vdev_uninit;
-	rte_vdev_unregister;
 	vfio_get_container_fd;
 	vfio_get_group_fd;
 	vfio_get_group_no;
diff --git a/lib/librte_ether/rte_ethdev_vdev.h b/lib/librte_ether/rte_ethdev_vdev.h
index 4d2c3e2..ff92e6e 100644
--- a/lib/librte_ether/rte_ethdev_vdev.h
+++ b/lib/librte_ether/rte_ethdev_vdev.h
@@ -35,7 +35,7 @@
 #define _RTE_ETHDEV_VDEV_H_
 
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_vdev.h b/lib/librte_eventdev/rte_eventdev_pmd_vdev.h
index 135e8b8..56232de 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_vdev.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_vdev.h
@@ -48,7 +48,7 @@ extern "C" {
 
 #include <rte_debug.h>
 #include <rte_eal.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "rte_eventdev_pmd.h"
 
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 047121d..de2f557 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -101,6 +101,7 @@ _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
diff --git a/test/test/autotest_data.pyc b/test/test/autotest_data.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e2e917de5c2ffd5315f7d32c484f4fa4659a25a6
GIT binary patch
literal 6122
zcmb_f340vH5$%<PWyuG|nEP6efG~)~vc22{AsZ0Zie+UC7?Nc))4LjLE>HJLh&z}B
z5|W>iUzZ;M^}5#6J^Rh<mpHbi@$`H3s=I2ctJ|~xIkvd^@9w9*82>p=|Gq`P>Vv~V
z1oYDokr1&ESA}R`JR_opxE#!ip9q@~!JK)S72&K1?hwHt(U$Z!FK#qMa9Fg%IT0*~
zU{SP#BO*9TECI)8^iL5SXZlX2PcVIGlD>=SlQrtQnLbrR-^291HS~Q<-(N#N!1RL^
z^l)AT4^aRV?87GP;E^KWM_Kk5%gC@CaFglBnLa#8Kf&~qOjGj8>Zh3gL&chq?5CN2
zriNZ(`q>)#G}F)3(9biyTtN>hj&VL-D9WJamcffGK2ssa!dI9+TSK2?`g{%DX8NTX
z`emkHsi9wG`n3vrNCi2L>-8e8H{7`1Wbq#>#E9!HrdMm|x0zn6p)W9fv4(z!>33`B
z_n2O<pq;qh=lZ==)b9q%IxJh9tiVmCKdA7EfV)h8SVQ-i-m0N5GyPEoJ*56J{uEb=
zPf;qdk6HXlg%~UQl<BKA^k+<eUPJ$h=|9)deWt&tpq+(#oa^l(*FMXF3K^CxnI6>8
zL#B5s=pl6`$`<vht4B<C4teTp#nihjj;h4ey~nAJCuIrC(&@5nQg)qX`E;2wG8`e=
z-D4vb?@br)7vfS?e97X2>Ef@d#b2}do9W_jIa+%Je8;lyr^|krl>LQeKTen3n3Vm*
zvcFE3{jEB}pIQ9Nbn)M-#s6UOul3^L5pngXp!0rf>0flQ2!EqLOAUI{bMzQS={Ao5
zoi_Inyv@?@8vUxL>7nU|3bKKUpr3Dr_(tF+vO6PkIxT0#7LB)-;BQksO3#)$P_01j
zg}zjH*D`J;X&}wxbVwE=#4JlQ^w5|ql1Y#L5xkZ|^p;CCiu95J@lY%DXzir2Y-ulP
z4MW`uvS4?4kLGD<sWd;lkxnt{2cGs`$PV-ok|m?KuTp<kYV{0U(cOx!Qzsio8*>dG
z3n_*C2muuAH4`;OMj;OyLeGdBLY$((mRa^Dr9_D5m#})1%4=zum{^p~d&mXH0-ol-
zJ%MC0zZuAj<X0hoqM_&MIn2{h)<2_>yKXKA;g=!8G~<qp)BHf)N#nHxKa#3>GfigY
zn_et6NZ*kCf`s3-G>*L_Foy4p65lxN$t=ya!fo|(7|Y!H1Ec{JUX0ZRxjh<|tpY%0
ztBZM_q-84!sBG1ddU8fuzdNG|l-8Xl)|rXVVAk7RwAh|h=_vQ5wFFAlXVAh{-+@@E
zu#}VS6)FlL&a_QtImy-yCX7wu3n%J+!g|sRTKjpZWiz6hEDQ2|U{-L91RLql`CvdI
zLafb6Le{z;H3yOB8X^oo8yVCZpCI&#%vI>-2H+lp*780AFRpGh2O$-V*~8_fN-ydU
zCYE9B%gey(j45F29bvrZsU7PR$POWejg#oJp`c8wqhzwt?N|+fD2oe;GWqIu+SbJ6
zD~sFK1|Nn#mY*G1tMSJo%-SI<WcO8?IK=^wzA8X#3H6rF!^A0ZVAKf+vv$}VtC5$-
zc49ytpu)-t`&{?~ydcW%+PW11$o#O7aQ%4^)s8hXAsNit-Alp_wbgJr%TsF3PF>wY
zR19j&SP?SV*&Yq7YalTp)&^g>EA!>ZPje?*fYGxIY^|a1m9hn-lq)9-=glrVyP{Ch
zTUnTtw+&D=M(q@L6Z-Z6?Xffu+-`vtZ4+)_Yi>H(>iWiqHb~RSyfC_Mt&pQ}KU|K&
z$+Ga{0H8I;8rBo)O!+9&PO7m6Ix842%$<na>R~c5-4^>amom}0m-tS>qLU1$9rrC+
zcv9oa&C)co@r)}MVA*n2r*Y^z>qF&u2DFCAGL99geP_=C&Bmy;MS1pQV5bI<%b>7u
zLVd}6-1a&1al4%h&GIh71g0*s*vd_IR((^yQK)p&PboicteDXAojCC^xBMM<QGgU6
zyDS`-a*vWtcM5ZqpFgu=diKRJNHdjB6?}%9iawLp9j+b)srJ<=8W*0_zReE^$IyDf
z<zY7oO$WHNIne=#u$G9J`jYv&wBrUL?ldM*)WS?508Mi`%iXii?0QFL9b)n15FHUp
z^$?B86}o1nC&b{`TSp5-n7(e@JU}DU_bZ)XXB4*91<u|q-KP@@AFYcwn>;{<wDzX$
zz^d>0S=h%Zn9J)X1QxHZb=R9?*m^>UV^5CEx<!te-`$J*d$B@0Wrvrpbei;IeIc=~
zt@W}<4BwDULLQ_c-=Qiqf*xY6trujKHwHcqvf4vKt@MF(6t;zn%_Y-@i4z*L+`RSm
z&Gi|*MVV`C4^wG$k3bGQIw1-Ve0ijku!k9XNM8?)tA`tO?<_qu_DAOBbPUOe9rHaE
z+g8IiNt1q^fxR=Ew_E)m0Cx53aT<&w`Q{V!t}?nyoM<f0Ei5b?nr+NCj?Lm}{?6R`
z+wnQ0y)C}xi*>Nq|7V4_%ftNt9NDeT{NH5q)IvGilbY(W&Ew?Ss>e3wYJZcw<Nq+$
HXUD$-S%8l+

literal 0
HcmV?d00001

diff --git a/test/test/autotest_test_funcs.pyc b/test/test/autotest_test_funcs.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..794b45b4e9a79cc3ddbd08d5031d78e4c7a2387a
GIT binary patch
literal 6812
zcmcgxOK%)m8NF3)x4UCI?_?54GL=jc+8GBwA|$X#G?^s8fW|S^Mwub9Os8+zuDH9}
zsau^m$PtSS5<4VTgM?VkmRTT##BL<S9*Grf_yH4X7A#nXbH3YMUDfS&fEd!<*Y{QD
zKI)wB`|eHQACm`e{$}aJy6XIM@%J74%m+v`zK&`r^+RM_^${|T(gn%5N{>jUp!BF@
zMwBi}W>o1h$rP0?NoGvxvSdmGtX2*HJba0Ni**iIz;6`4Tlkp($&OMFkvi(RqZ}46
zEWQ}Cpb}R-EU0yihVLkPIL}<QgQlX|bX9y)=|if@a#_mXSNgCmk4w3x^bu9nM=^_I
z7-`XrAzcnk;@$n88Sm!5RSO$|Hb+pt)oM0tk@lii;;psXkxuwT5;lWYI|)C++(QQy
zvYccDIX)Y5S>|x3<lSHFKD-igvF2dfvTT7?LewaMuD0v-z?cdl1l1>gued90rg;$C
zHgW);pcT$CDIqaIq#I!rBt;a0?X94m$P~6R`Q`WCzjOBo%N5Q$;ajS2gbkgPS;V%j
zMzyAWJ`PN~kyKExBr#t{Zf2v^3}%vAG_xKiGkQyJUVW^C$1{A?Cbf3b5+F&|+ELwn
zb?a%uz0<*34UntdE`&A5ktk=<nQ%_wH<JE@Nn9R(!X&=E9FxGFsw{p{cH3@-Y%_W)
zVM2HFx#d2WEPLnkmHXVW{aW56uynh*m9CAOW%y#aHdzbzniaB^-y)M=i=)VU(FWMw
zQ3Yr(BB3e@Y6sdJQJV!(1ylff@_|wHu&AD6{1J5;N`3CCXJ`;XZ8|D$ib5<hM5GUN
z!GQ+wagm$_pAbp?T2W3M?4XoCRr(ktb{w010@GeJ?;_pWcxo1Ax9`th{YLHT+RBw_
zuMtEG6_!`7Oig=_!#K&en^t`@NLE9=U_1FhQQ_~HNRIYnHzAQZ<`5DJ(Yya{O?xK%
zaj>$N(nGOG^3p}jBt?cELx#$TZkO>gtzEN_soG1WIVKAA$V8tgK3U;Yt_kbHC=pFI
zYe{`WRJ<Oy+FPa~-BQ*{OB}32*3vzUbg(VPiaWDkoaP=hgJvs!nzH&GRGD)~$m*hd
zPSkp)quCRA?Q+UonDG4#yat$jP@E~)mh}kR|5OQxdQ@CPm-5yfU{@ZFsCBp?I3I8u
zI<VY!gqk0!rAKFk>m@0FLX$@9qI!tlGUjPG9Vlv3srY9ih26VgY8@!+SiTqrRS>AZ
zh)9M&6}nJXP%lM5RHPNu8AUN+w0rslM0FCIWG&cUlr~>Nx9<dvM$21^TTQRtiUY5!
zH}AZe%Qrs>lZ`O);-KD+P53zQ8jzo{kM^Fj8swW24=3&^<BzDdR;+{Ay19^y-A$sY
z(E2sj^O!xTjA&lbJWNv}-@FDfvAn^jaTkLxvRIDWL7(3I3HG4f_Bl?!!o+OA3S(zt
zpYz-=Rnd!?tuW&INOe_Z<t!5A6!DpK%J>xcaZkALiiHX1P54GCP5z=xPg!!svv4a?
zrTrZRtF*kv{v;avo2cWJ8nf=eYOF5N81x0dvns4#dUR5Jkrm3P!-Qfr_X{Ea5TQVG
z7HU%D`$q<t6r!!PYJt+A7AghR_w-39<_)az^%XM%ly5g$4{8nXNgO6tB3@G43?i=;
zdCi(hf;g`;tCvo=3u*`xPXovLruPx&)z$+qG+r|_CXCis`Xk4l4kU6MCMk&#`_;7P
zK>uf1`HZ$-At`ZisnhZq>FukO=%C^!IU%)CWu}o(Nc}RRXi_ObLS;&8q$8r7yZR*n
za`H)!E6Cui0*-F`)Wz+U?{?i8yo|(WIK=eMG<{yndZ{1L5mf09pdhH~vYc@qT~_xv
zCJsh&66$~eGXuiIPlYCA(NF}-cdE-bmzL%hydaKSvDdT&6kpM6tApKP9W>vid49ng
zXyz+h-u(!b5rD)iLn0{~kBeKN3C(cxb!@uuiNp5suHSak_BUGVtBugu^A8J6v%at7
zqvrswNo_beV=f{=Y*Y~2?UW0oAoF6yLAR32@(F9VX-7yqiI9$CVL8fmxFF}`9v6gS
zy+iV-*v%VCziAJ}mSBrYdnj8n9blOM3V@#|eLf5DbEPk&0OS7#z-LOol?C{-(idU0
zixdY_FdC_ZanFisd(?$nj=yj_Q=CwGGBXG|<Eew0y8ye)OU_b+O@jBb%lw+7FWEs4
z$u`_^^kr3jdUwDfjVcC#&&CECO17ai&~V5$l-0ecq#Vc5Us2T$c5v@;L`Hh)Q0w-F
z;xlKb%w<N?3K`T>(l4AH+>IQSQ1OL>o;X6;)-_k1#IMTs<7yMz@Y2y0RprWnZ&!NT
zWoMlAa0BwT%g5mnr6zqGV<Hj;2)rafZo7Ia1+m-nvAZK1PLP0r*#F2A9E^fV{#1}p
zb!t*%V4fDtk6nEw#k5=ex!S>G?85&bn8hw8DuMY|!Thpd7S$l;3s=7lPyV^W_Z~J2
zaGc-a0vCCf+lQL&V|p6a?kW_rXig!mCbc;6cvTa7Cc*uL@p#E#`tNx%QLTh=G*aSF
ztur1pL1Hh5p?mXUYO~D`Y9_3A#(obIqp9V+iocLX<S?tXM&m)PzUhVfdKz)papRQq
ziU>1uaeVdwV9&5LcZR;!Mi{qh5ihQ`YOx9I9aBiRYTinFGz9Scbx$&@*sWQwa!F5n
zm-N(1$OF7wxmY-9tw)J>!<(O589=$7L7D5J<N@Y93vg|A5Fk5^`5r*XBV-<BK7&Fd
zYUh`(;hI<9s7336CWv?ShO8!!fG)BS&SPp2L3Uxv%P#2}!KPOF!z{WP4*%bItsx#U
z1NOhhAHtT*3`m*X2r#Tm<`oa?l6il_x@2CE?SfehIkfdTcpGf?9oXnSdlz})+Y{EM
zoSDrR=kmq*eDNAQBm#OZ*DxRw4lEt0{W|#3?1=43BZl9j#{3EiB8E;}V9#|UdzN@Y
z#0P!KZZ@`%yHnJh#^)@ej8TNR2y$_+T67K~HzsA~i)pEhT(-4W9!GDq*hqy|h_t<h
zpP_lB<3>7oqyLIP1Ch$Ob=lUrAySz@oG=MH&;8l+`rev#c};n<zT1@qzy@yo{sZCh
z@!Yi?pOyQBK5EK6dLIq<i!lr_V;mw=!kojp<$8wKZxc>>;pSG#oE|Cbi!AsbAO2A$
zyj=2mRPcF!<X>PyXVIIZ<X-P`zXZT<He0&g2ySo$nd3yUe7IaHA1hxdUo4+3Z~O}Z
C_uuIN

literal 0
HcmV?d00001

diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 72988c5..a83b361 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_pause.h>
+#include <rte_bus_vdev.h>
 
 #include <rte_crypto.h>
 #include <rte_cryptodev.h>
diff --git a/test/test/test_event_eth_rx_adapter.c b/test/test/test_event_eth_rx_adapter.c
index 56ed1f8..90a5c64 100644
--- a/test/test/test_event_eth_rx_adapter.c
+++ b/test/test/test_event_eth_rx_adapter.c
@@ -35,6 +35,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
+#include <rte_bus_vdev.h>
 
 #include <rte_event_eth_rx_adapter.h>
 
diff --git a/test/test/test_eventdev.c b/test/test/test_eventdev.c
index 4118b75..ba39cba 100644
--- a/test/test/test_eventdev.c
+++ b/test/test/test_eventdev.c
@@ -37,6 +37,7 @@
 #include <rte_memcpy.h>
 #include <rte_eventdev.h>
 #include <rte_dev.h>
+#include <rte_bus_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_octeontx.c b/test/test/test_eventdev_octeontx.c
index b88b0d2..dbc36d9 100644
--- a/test/test/test_eventdev_octeontx.c
+++ b/test/test/test_eventdev_octeontx.c
@@ -45,6 +45,7 @@
 #include <rte_lcore.h>
 #include <rte_per_lcore.h>
 #include <rte_random.h>
+#include <rte_bus_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_sw.c b/test/test/test_eventdev_sw.c
index 5c7751b..f6a3fa3 100644
--- a/test/test/test_eventdev_sw.c
+++ b/test/test/test_eventdev_sw.c
@@ -51,6 +51,7 @@
 #include <rte_pause.h>
 #include <rte_service.h>
 #include <rte_service_component.h>
+#include <rte_bus_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_link_bonding_rssconf.c b/test/test/test_link_bonding_rssconf.c
index 7dccc6e..54cbf12 100644
--- a/test/test/test_link_bonding_rssconf.c
+++ b/test/test/test_link_bonding_rssconf.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_lcore.h>
 #include <rte_memory.h>
+#include <rte_bus_vdev.h>
 
 #include <rte_string_fns.h>
 #include <rte_errno.h>
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v11 4/4] bus/vdev: change log type
  2017-10-30  8:28   ` [PATCH v11 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-10-30  8:28     ` [PATCH v11 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-10-30  8:28     ` Jianfeng Tan
  3 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-10-30  8:28 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use specialized dynamic log type for vdev bus logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Suggested-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      | 20 ++++++++++++++++----
 drivers/bus/vdev/vdev_logs.h | 45 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 04ed49b..1f8efe2 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,9 @@
 #include <rte_errno.h>
 
 #include "rte_bus_vdev.h"
+#include "vdev_logs.h"
+
+int vdev_logtype_bus;
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +106,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +193,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -213,7 +216,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -294,7 +297,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
@@ -342,3 +345,12 @@ static struct rte_bus rte_vdev_bus = {
 };
 
 RTE_REGISTER_BUS(vdev, rte_vdev_bus);
+
+RTE_INIT(vdev_init_log);
+static void
+vdev_init_log(void)
+{
+	vdev_logtype_bus = rte_log_register("bus.vdev");
+	if (vdev_logtype_bus >= 0)
+		rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE);
+}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..43b0ab8
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,45 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#include <rte_log.h>
+
+extern int vdev_logtype_bus;
+
+#define VDEV_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, vdev_logtype_bus, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v11 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-10-30  8:28     ` [PATCH v11 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-11-07  2:43       ` Thomas Monjalon
  2017-11-07  6:21         ` Tan, Jianfeng
  0 siblings, 1 reply; 158+ messages in thread
From: Thomas Monjalon @ 2017-11-07  2:43 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit

Hi Jianfeng,

This patch needs a rebase and some changes as described below.
Would you have time to fix it quickly please?

30/10/2017 09:28, Jianfeng Tan:
>  create mode 100644 lib/librte_eal/common/.eal_common_dev.c.swp
[...]
>  create mode 100644 test/test/autotest_data.pyc
>  create mode 100644 test/test/autotest_test_funcs.pyc

These files should not be in the patch.


> --- a/config/common_base
> +++ b/config/common_base
> @@ -814,3 +814,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
>  # Compile the eventdev application
>  #
>  CONFIG_RTE_APP_EVENTDEV=y
> +
> +#
> +# Compile the vdev bus
> +#
> +CONFIG_RTE_LIBRTE_VDEV_BUS=y

Please move this option in a more logical position.


> --- a/drivers/crypto/Makefile
> +++ b/drivers/crypto/Makefile
> @@ -32,6 +32,7 @@
>  include $(RTE_SDK)/mk/rte.vars.mk
>  
>  core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
> +core-libs += librte_bus_vdev

The library dependencies have changed.
You must add the dependency to LDLIBS in each PMD Makefile.


> --- a/lib/librte_eal/linuxapp/eal/Makefile
> +++ b/lib/librte_eal/linuxapp/eal/Makefile
> -LIBABIVER := 6
> +LIBABIVER := 7

No need to bump again the EAL version in 17.11.


> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -101,6 +101,7 @@ _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev

I suggest to move by one line just before -lrte_eal.

^ permalink raw reply	[flat|nested] 158+ messages in thread

* Re: [PATCH v11 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-11-07  2:43       ` Thomas Monjalon
@ 2017-11-07  6:21         ` Tan, Jianfeng
  0 siblings, 0 replies; 158+ messages in thread
From: Tan, Jianfeng @ 2017-11-07  6:21 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, jblunck, Richardson, Bruce, Ananyev, Konstantin,
	De Lara Guarch, Pablo, yliu, maxime.coquelin, mtetsuyah, Yigit,
	Ferruh

Hi Thomas,

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Tuesday, November 7, 2017 10:43 AM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; jblunck@infradead.org; Richardson, Bruce; Ananyev,
> Konstantin; De Lara Guarch, Pablo; yliu@fridaylinux.org;
> maxime.coquelin@redhat.com; mtetsuyah@gmail.com; Yigit, Ferruh
> Subject: Re: [dpdk-dev] [PATCH v11 3/4] bus/vdev: move to vdev bus to
> drivers/bus
> 
> Hi Jianfeng,
> 
> This patch needs a rebase and some changes as described below.
> Would you have time to fix it quickly please?

Thank you for review. Will send out soon.
 
> 
> > --- a/config/common_base
> > +++ b/config/common_base
> > @@ -814,3 +814,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
> >  # Compile the eventdev application
> >  #
> >  CONFIG_RTE_APP_EVENTDEV=y
> > +
> > +#
> > +# Compile the vdev bus
> > +#
> > +CONFIG_RTE_LIBRTE_VDEV_BUS=y
> 
> Please move this option in a more logical position.

How about moving it after LIBRTE_PCI_BUS?

> 
> 
> > --- a/lib/librte_eal/linuxapp/eal/Makefile
> > +++ b/lib/librte_eal/linuxapp/eal/Makefile
> > -LIBABIVER := 6
> > +LIBABIVER := 7
> 
> No need to bump again the EAL version in 17.11.
> 
> 
> > --- a/mk/rte.app.mk
> > +++ b/mk/rte.app.mk
> > @@ -101,6 +101,7 @@ _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)
> += -lrte_mempool_ring
> >  _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
> >  _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
> >  _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
> > +_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
> 
> I suggest to move by one line just before -lrte_eal.

How about moving it to after rte_bus_pci?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v12 0/4] move vdev into drivers/bus
  2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
                     ` (13 preceding siblings ...)
  2017-10-30  8:28   ` [PATCH v11 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-11-07  6:54   ` Jianfeng Tan
  2017-11-07  6:54     ` [PATCH v12 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
                       ` (4 more replies)
  14 siblings, 5 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-11-07  6:54 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

v12: (Suggested Thomas)
  - Remove unnecessary files introduced in v11.
  - Adjust position for some macros.
  - Move LDLIBS into PMD Makefile.
  - Do not bump the LIBABIVER.
  - Rebase on latest code.

v11:
  - Rename rte_vdev.h to rte_bus_vdev.h as suggested by Thomas.

v10:
  - Rebase on 17.11-rc2.

v9:
  - Avoid bumping library version (eal, crypto) as other commits in this
    release already do that as suggested by Pablo.
  - Move vdev's dir dependency to its own folder as suggested by Gaetan.

v8: (Suggested by Pablo)
  - As we bump the library version and add new library (bus_vdev), we
    need to update those in release note.
  - Fix compiling issue in test as of missing rte_vdev.h.
  - Move vdev API symbols from eal to bus_vdev; update in release note.

v7:
  - Add notice in release note for API change, and bump library version
    of librte_cryptodev and librte_eal, as suggested by Thomas.

v6:
  - Don't introduce the static log type for bug, instead we use dynamic
    log type for vdev, suggested by Shreyansh Jain.

v4 & v5:
  - Fix issues of compiling shared library.
  - Remove extra symbols in drivers/bus/vdev/rte_bus_vdev_version.map.
  - Address checkpatch warnings.

This patch set is originated from below series:
  http://dpdk.org/ml/archives/dev/2017-September/076821.html

As per previous discussions, we move all bus drivers from EAL to
drivers/bus/. This patch set targets vdev bus.

Jianfeng Tan (4):
  cryptodev: remove crypto vdev init API
  eal: remove dependency on vdev
  bus/vdev: move to vdev bus to drivers/bus
  bus/vdev: change log type

 config/common_base                             |   5 +
 doc/guides/rel_notes/deprecation.rst           |   5 -
 doc/guides/rel_notes/release_17_11.rst         |  11 +
 drivers/bus/Makefile                           |   2 +
 drivers/bus/vdev/Makefile                      |  57 ++++
 drivers/bus/vdev/rte_bus_vdev.h                | 153 +++++++++++
 drivers/bus/vdev/rte_bus_vdev_version.map      |   8 +
 drivers/bus/vdev/vdev.c                        | 356 +++++++++++++++++++++++++
 drivers/bus/vdev/vdev_logs.h                   |  45 ++++
 drivers/crypto/aesni_gcm/Makefile              |   1 +
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c       |   2 +-
 drivers/crypto/aesni_mb/Makefile               |   1 +
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c     |   2 +-
 drivers/crypto/armv8/Makefile                  |   1 +
 drivers/crypto/armv8/rte_armv8_pmd.c           |   2 +-
 drivers/crypto/kasumi/Makefile                 |   1 +
 drivers/crypto/kasumi/rte_kasumi_pmd.c         |   2 +-
 drivers/crypto/mrvl/Makefile                   |   1 +
 drivers/crypto/mrvl/rte_mrvl_pmd.c             |   2 +-
 drivers/crypto/null/Makefile                   |   1 +
 drivers/crypto/null/null_crypto_pmd.c          |   2 +-
 drivers/crypto/openssl/Makefile                |   1 +
 drivers/crypto/openssl/rte_openssl_pmd.c       |   2 +-
 drivers/crypto/scheduler/Makefile              |   1 +
 drivers/crypto/scheduler/scheduler_pmd.c       |   2 +-
 drivers/crypto/snow3g/Makefile                 |   1 +
 drivers/crypto/snow3g/rte_snow3g_pmd.c         |   2 +-
 drivers/crypto/zuc/Makefile                    |   1 +
 drivers/crypto/zuc/rte_zuc_pmd.c               |   2 +-
 drivers/event/dpaa2/Makefile                   |   1 +
 drivers/event/dpaa2/dpaa2_eventdev.c           |   2 +-
 drivers/event/octeontx/Makefile                |   1 +
 drivers/event/octeontx/ssovf_evdev.c           |   2 +-
 drivers/event/skeleton/Makefile                |   1 +
 drivers/event/skeleton/skeleton_eventdev.c     |   2 +-
 drivers/event/sw/Makefile                      |   1 +
 drivers/event/sw/sw_evdev.c                    |   2 +-
 drivers/net/af_packet/Makefile                 |   1 +
 drivers/net/af_packet/rte_eth_af_packet.c      |   2 +-
 drivers/net/bonding/Makefile                   |   1 +
 drivers/net/bonding/rte_eth_bond_api.c         |   2 +-
 drivers/net/bonding/rte_eth_bond_pmd.c         |   2 +-
 drivers/net/failsafe/Makefile                  |   1 +
 drivers/net/failsafe/failsafe.c                |   2 +-
 drivers/net/kni/Makefile                       |   1 +
 drivers/net/kni/rte_eth_kni.c                  |   2 +-
 drivers/net/mrvl/Makefile                      |   1 +
 drivers/net/mrvl/mrvl_ethdev.c                 |   2 +-
 drivers/net/null/Makefile                      |   1 +
 drivers/net/null/rte_eth_null.c                |   2 +-
 drivers/net/octeontx/Makefile                  |   1 +
 drivers/net/octeontx/octeontx_ethdev.c         |   2 +-
 drivers/net/pcap/Makefile                      |   1 +
 drivers/net/pcap/rte_eth_pcap.c                |   2 +-
 drivers/net/ring/Makefile                      |   1 +
 drivers/net/ring/rte_eth_ring.c                |   2 +-
 drivers/net/softnic/Makefile                   |   1 +
 drivers/net/softnic/rte_eth_softnic.c          |   2 +-
 drivers/net/tap/Makefile                       |   1 +
 drivers/net/tap/rte_eth_tap.c                  |   2 +-
 drivers/net/vhost/Makefile                     |   1 +
 drivers/net/vhost/rte_eth_vhost.c              |   2 +-
 drivers/net/virtio/Makefile                    |   3 +
 drivers/net/virtio/virtio_user_ethdev.c        |   2 +-
 lib/librte_cryptodev/rte_cryptodev.c           |   6 -
 lib/librte_cryptodev/rte_cryptodev.h           |  17 --
 lib/librte_cryptodev/rte_cryptodev_version.map |   1 -
 lib/librte_eal/bsdapp/eal/Makefile             |   1 -
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_dev.c         |  22 +-
 lib/librte_eal/common/eal_common_vdev.c        | 342 ------------------------
 lib/librte_eal/common/include/rte_dev.h        |  24 +-
 lib/librte_eal/common/include/rte_vdev.h       | 131 ---------
 lib/librte_eal/linuxapp/eal/Makefile           |   1 -
 lib/librte_eal/rte_eal_version.map             |   4 -
 lib/librte_ether/rte_ethdev_vdev.h             |   2 +-
 lib/librte_eventdev/rte_eventdev_pmd_vdev.h    |   2 +-
 mk/rte.app.mk                                  |   1 +
 test/test/test_cryptodev.c                     |   1 +
 test/test/test_event_eth_rx_adapter.c          |   1 +
 test/test/test_eventdev.c                      |   1 +
 test/test/test_eventdev_octeontx.c             |   1 +
 test/test/test_eventdev_sw.c                   |   1 +
 test/test/test_link_bonding_rssconf.c          |   1 +
 84 files changed, 711 insertions(+), 578 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev.h
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/vdev.c
 create mode 100644 drivers/bus/vdev/vdev_logs.h
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 158+ messages in thread

* [PATCH v12 1/4] cryptodev: remove crypto vdev init API
  2017-11-07  6:54   ` [PATCH v12 0/4] move vdev into drivers/bus Jianfeng Tan
@ 2017-11-07  6:54     ` Jianfeng Tan
  2017-11-07  6:54     ` [PATCH v12 2/4] eal: remove dependency on vdev Jianfeng Tan
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-11-07  6:54 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Remove rte_cryptodev_create_vdev() for duplication.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  5 -----
 doc/guides/rel_notes/release_17_11.rst         |  2 ++
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 17 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  1 -
 5 files changed, 2 insertions(+), 29 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 817f192..d38ce5c 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -53,10 +53,5 @@ Deprecation Notices
   ``rte_cryptodev`` respectively to support security protocol offloaded
   operations.
 
-* cryptodev: the following function is deprecated starting from 17.08 and will
-  be removed in 17.11:
-
-  - ``rte_cryptodev_create_vdev``
-
 * librte_meter: The API will change to accommodate configuration profiles.
   Most of the API functions will have an additional opaque parameter.
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 4846448..158a9ca 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -431,6 +431,8 @@ API Changes
   the backing device supports the operation or if the operation was
   successfully performed.
 
+* ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
+  in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
 ABI Changes
 -----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index e5f2876..b40c028 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -377,12 +377,6 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 	}
 }
 
-int
-rte_cryptodev_create_vdev(const char *name, const char *args)
-{
-	return rte_vdev_init(name, args);
-}
-
 struct rte_cryptodev *
 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index a25bff9..dade554 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -435,23 +435,6 @@ struct rte_cryptodev_stats {
 /**< Max length of name of crypto PMD */
 
 /**
- * @deprecated
- *
- * Create a virtual crypto device
- *
- * @param	name	Cryptodev PMD name of device to be created.
- * @param	args	Options arguments for device.
- *
- * @return
- * - On successful creation of the cryptodev the device index is returned,
- *   which will be between 0 and rte_cryptodev_count().
- * - In the case of a failure, returns -1.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_create_vdev(const char *name, const char *args);
-
-/**
  * Get the device identifier for the named crypto device.
  *
  * @param	name	device name to select the device structure.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e82296c..eb47308 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -7,7 +7,6 @@ DPDK_16.04 {
 	rte_cryptodev_close;
 	rte_cryptodev_count;
 	rte_cryptodev_configure;
-	rte_cryptodev_create_vdev;
 	rte_cryptodev_get_dev_id;
 	rte_cryptodev_get_feature_name;
 	rte_cryptodev_info_get;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v12 2/4] eal: remove dependency on vdev
  2017-11-07  6:54   ` [PATCH v12 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-11-07  6:54     ` [PATCH v12 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
@ 2017-11-07  6:54     ` Jianfeng Tan
  2017-11-07  6:54     ` [PATCH v12 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-11-07  6:54 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

We can call bus->plug() to avoid calling rte_vdev_init() explicitly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index e251275..dda8f58 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -67,7 +67,6 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
-	int ret;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
@@ -80,22 +79,13 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 			name);
 		return -EINVAL;
 	}
-	if (strcmp(bus->name, "pci") == 0)
-		return rte_eal_hotplug_add("pci", name, devargs);
-	if (strcmp(bus->name, "vdev") != 0) {
-		RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n");
-		return -ENOTSUP;
-	}
+	if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
+		return rte_eal_hotplug_add(bus->name, name, devargs);
 
-	/*
-	 * If we haven't found a bus device the user meant to "hotplug" a
-	 * virtual device instead.
-	 */
-	ret = rte_vdev_init(name, devargs);
-	if (ret)
-		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
-			name);
-	return ret;
+	RTE_LOG(ERR, EAL,
+		"Device attach is only supported for PCI and vdev devices.\n");
+
+	return -ENOTSUP;
 }
 
 int rte_eal_dev_detach(struct rte_device *dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v12 3/4] bus/vdev: move to vdev bus to drivers/bus
  2017-11-07  6:54   ` [PATCH v12 0/4] move vdev into drivers/bus Jianfeng Tan
  2017-11-07  6:54     ` [PATCH v12 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
  2017-11-07  6:54     ` [PATCH v12 2/4] eal: remove dependency on vdev Jianfeng Tan
@ 2017-11-07  6:54     ` Jianfeng Tan
  2017-11-07  6:54     ` [PATCH v12 4/4] bus/vdev: change log type Jianfeng Tan
  2017-11-07 15:43     ` [PATCH v12 0/4] move vdev into drivers/bus Thomas Monjalon
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-11-07  6:54 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Move the vdev bus from lib/librte_eal to drivers/bus.

As the crypto vdev helper function refers to data structure
in rte_vdev.h, so we move those helper function into drivers/bus
too.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                          |   5 +
 doc/guides/rel_notes/release_17_11.rst      |   9 +
 drivers/bus/Makefile                        |   2 +
 drivers/bus/vdev/Makefile                   |  57 +++++
 drivers/bus/vdev/rte_bus_vdev.h             | 153 +++++++++++++
 drivers/bus/vdev/rte_bus_vdev_version.map   |   8 +
 drivers/bus/vdev/vdev.c                     | 344 ++++++++++++++++++++++++++++
 drivers/crypto/aesni_gcm/Makefile           |   1 +
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c    |   2 +-
 drivers/crypto/aesni_mb/Makefile            |   1 +
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c  |   2 +-
 drivers/crypto/armv8/Makefile               |   1 +
 drivers/crypto/armv8/rte_armv8_pmd.c        |   2 +-
 drivers/crypto/kasumi/Makefile              |   1 +
 drivers/crypto/kasumi/rte_kasumi_pmd.c      |   2 +-
 drivers/crypto/mrvl/Makefile                |   1 +
 drivers/crypto/mrvl/rte_mrvl_pmd.c          |   2 +-
 drivers/crypto/null/Makefile                |   1 +
 drivers/crypto/null/null_crypto_pmd.c       |   2 +-
 drivers/crypto/openssl/Makefile             |   1 +
 drivers/crypto/openssl/rte_openssl_pmd.c    |   2 +-
 drivers/crypto/scheduler/Makefile           |   1 +
 drivers/crypto/scheduler/scheduler_pmd.c    |   2 +-
 drivers/crypto/snow3g/Makefile              |   1 +
 drivers/crypto/snow3g/rte_snow3g_pmd.c      |   2 +-
 drivers/crypto/zuc/Makefile                 |   1 +
 drivers/crypto/zuc/rte_zuc_pmd.c            |   2 +-
 drivers/event/dpaa2/Makefile                |   1 +
 drivers/event/dpaa2/dpaa2_eventdev.c        |   2 +-
 drivers/event/octeontx/Makefile             |   1 +
 drivers/event/octeontx/ssovf_evdev.c        |   2 +-
 drivers/event/skeleton/Makefile             |   1 +
 drivers/event/skeleton/skeleton_eventdev.c  |   2 +-
 drivers/event/sw/Makefile                   |   1 +
 drivers/event/sw/sw_evdev.c                 |   2 +-
 drivers/net/af_packet/Makefile              |   1 +
 drivers/net/af_packet/rte_eth_af_packet.c   |   2 +-
 drivers/net/bonding/Makefile                |   1 +
 drivers/net/bonding/rte_eth_bond_api.c      |   2 +-
 drivers/net/bonding/rte_eth_bond_pmd.c      |   2 +-
 drivers/net/failsafe/Makefile               |   1 +
 drivers/net/failsafe/failsafe.c             |   2 +-
 drivers/net/kni/Makefile                    |   1 +
 drivers/net/kni/rte_eth_kni.c               |   2 +-
 drivers/net/mrvl/Makefile                   |   1 +
 drivers/net/mrvl/mrvl_ethdev.c              |   2 +-
 drivers/net/null/Makefile                   |   1 +
 drivers/net/null/rte_eth_null.c             |   2 +-
 drivers/net/octeontx/Makefile               |   1 +
 drivers/net/octeontx/octeontx_ethdev.c      |   2 +-
 drivers/net/pcap/Makefile                   |   1 +
 drivers/net/pcap/rte_eth_pcap.c             |   2 +-
 drivers/net/ring/Makefile                   |   1 +
 drivers/net/ring/rte_eth_ring.c             |   2 +-
 drivers/net/softnic/Makefile                |   1 +
 drivers/net/softnic/rte_eth_softnic.c       |   2 +-
 drivers/net/tap/Makefile                    |   1 +
 drivers/net/tap/rte_eth_tap.c               |   2 +-
 drivers/net/vhost/Makefile                  |   1 +
 drivers/net/vhost/rte_eth_vhost.c           |   2 +-
 drivers/net/virtio/Makefile                 |   3 +
 drivers/net/virtio/virtio_user_ethdev.c     |   2 +-
 lib/librte_eal/bsdapp/eal/Makefile          |   1 -
 lib/librte_eal/common/Makefile              |   2 +-
 lib/librte_eal/common/eal_common_vdev.c     | 342 ---------------------------
 lib/librte_eal/common/include/rte_dev.h     |  24 +-
 lib/librte_eal/common/include/rte_vdev.h    | 131 -----------
 lib/librte_eal/linuxapp/eal/Makefile        |   1 -
 lib/librte_eal/rte_eal_version.map          |   4 -
 lib/librte_ether/rte_ethdev_vdev.h          |   2 +-
 lib/librte_eventdev/rte_eventdev_pmd_vdev.h |   2 +-
 mk/rte.app.mk                               |   1 +
 test/test/test_cryptodev.c                  |   1 +
 test/test/test_event_eth_rx_adapter.c       |   1 +
 test/test/test_eventdev.c                   |   1 +
 test/test/test_eventdev_octeontx.c          |   1 +
 test/test/test_eventdev_sw.c                |   1 +
 test/test/test_link_bonding_rssconf.c       |   1 +
 78 files changed, 646 insertions(+), 533 deletions(-)
 create mode 100644 drivers/bus/vdev/Makefile
 create mode 100644 drivers/bus/vdev/rte_bus_vdev.h
 create mode 100644 drivers/bus/vdev/rte_bus_vdev_version.map
 create mode 100644 drivers/bus/vdev/vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/config/common_base b/config/common_base
index 82ee754..9ae5ec3 100644
--- a/config/common_base
+++ b/config/common_base
@@ -158,6 +158,11 @@ CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
 CONFIG_RTE_LIBRTE_PCI_BUS=y
 
 #
+# Compile the vdev bus
+#
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
+
+#
 # Compile burst-oriented Amazon ENA PMD driver
 #
 CONFIG_RTE_LIBRTE_ENA_PMD=y
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 158a9ca..714234a 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -434,6 +434,14 @@ API Changes
 * ``rte_cryptodev_create_vdev`` was removed to avoid the dependency on vdev
   in librte_cryptodev; instead, users can call rte_vdev_init() directly.
 
+* **Moved vdev bus APIs outside of the EAL**
+
+  Moved the following APIs from ``librte_eal`` to ``librte_bus_vdev``:
+  * ``rte_vdev_init``
+  * ``rte_vdev_register``
+  * ``rte_vdev_uninit``
+  * ``rte_vdev_unregister``
+
 ABI Changes
 -----------
 
@@ -489,6 +497,7 @@ The libraries prepended with a plus sign were incremented in this version.
 
      librte_acl.so.2
    + librte_bitratestats.so.2
+   + librte_bus_vdev.so.1
      librte_cfgfile.so.2
      librte_cmdline.so.2
    + librte_cryptodev.so.4
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index e3fbc50..d9fe4c4 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -34,4 +34,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
 
+DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
new file mode 100644
index 0000000..84bd724
--- /dev/null
+++ b/drivers/bus/vdev/Makefile
@@ -0,0 +1,57 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_vdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_vdev_version.map
+
+# library version
+LIBABIVER := 1
+
+SRCS-y += vdev.c
+
+LDLIBS += -lrte_eal
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_bus_vdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h
new file mode 100644
index 0000000..41762b8
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev.h
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+struct rte_vdev_device {
+	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
+	struct rte_device device;               /**< Inherit core device */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_vdev_device.
+ */
+#define RTE_DEV_TO_VDEV(ptr) \
+	container_of(ptr, struct rte_vdev_device, device)
+
+static inline const char *
+rte_vdev_device_name(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.name)
+		return dev->device.name;
+	return NULL;
+}
+
+static inline const char *
+rte_vdev_device_args(const struct rte_vdev_device *dev)
+{
+	if (dev && dev->device.devargs)
+		return dev->device.devargs->args;
+	return "";
+}
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Probe function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
+
+/**
+ * Remove function called for each virtual device driver once.
+ */
+typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;      /**< Inherited general driver. */
+	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
+	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vdev_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vdev_unregister(struct rte_vdev_driver *driver);
+
+#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static const char *vdrvinit_ ## nm ## _alias;\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
+	rte_vdev_register(&vdrv);\
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
+static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
+
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @param args
+ *   The pointer to arguments used by driver initialization.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ *   The pointer to a driver name to be initialized.
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vdev_uninit(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
new file mode 100644
index 0000000..6ccb789
--- /dev/null
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	rte_vdev_init;
+	rte_vdev_register;
+	rte_vdev_uninit;
+	rte_vdev_unregister;
+};
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
new file mode 100644
index 0000000..04ed49b
--- /dev/null
+++ b/drivers/bus/vdev/vdev.c
@@ -0,0 +1,344 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_memory.h>
+#include <rte_errno.h>
+
+#include "rte_bus_vdev.h"
+
+/* Forward declare to access virtual bus name */
+static struct rte_bus rte_vdev_bus;
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_device_list, rte_vdev_device);
+
+static struct vdev_device_list vdev_device_list =
+	TAILQ_HEAD_INITIALIZER(vdev_device_list);
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_vdev_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_vdev_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+static int
+vdev_parse(const char *name, void *addr)
+{
+	struct rte_vdev_driver **out = addr;
+	struct rte_vdev_driver *driver = NULL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)) == 0)
+			break;
+		if (driver->driver.alias &&
+		    strncmp(driver->driver.alias, name,
+			    strlen(driver->driver.alias)) == 0)
+			break;
+	}
+	if (driver != NULL &&
+	    addr != NULL)
+		*out = driver;
+	return driver == NULL;
+}
+
+static int
+vdev_probe_all_drivers(struct rte_vdev_device *dev)
+{
+	const char *name;
+	struct rte_vdev_driver *driver;
+	int ret;
+
+	name = rte_vdev_device_name(dev);
+
+	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+		rte_vdev_device_name(dev));
+
+	if (vdev_parse(name, &driver))
+		return -1;
+	dev->device.driver = &driver->driver;
+	ret = driver->probe(dev);
+	if (ret)
+		dev->device.driver = NULL;
+	return ret;
+}
+
+static struct rte_vdev_device *
+find_vdev(const char *name)
+{
+	struct rte_vdev_device *dev;
+
+	if (!name)
+		return NULL;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		const char *devname = rte_vdev_device_name(dev);
+
+		if (!strncmp(devname, name, strlen(name)))
+			return dev;
+	}
+
+	return NULL;
+}
+
+static struct rte_devargs *
+alloc_devargs(const char *name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = calloc(1, sizeof(*devargs));
+	if (!devargs)
+		return NULL;
+
+	devargs->bus = &rte_vdev_bus;
+	if (args)
+		devargs->args = strdup(args);
+	else
+		devargs->args = strdup("");
+
+	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
+		free(devargs->args);
+		free(devargs);
+		return NULL;
+	}
+
+	return devargs;
+}
+
+int
+rte_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (dev)
+		return -EEXIST;
+
+	devargs = alloc_devargs(name, args);
+	if (!devargs)
+		return -ENOMEM;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dev->device.devargs = devargs;
+	dev->device.numa_node = SOCKET_ID_ANY;
+	dev->device.name = devargs->name;
+
+	ret = vdev_probe_all_drivers(dev);
+	if (ret) {
+		if (ret > 0)
+			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+		goto fail;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+
+	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	return 0;
+
+fail:
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return ret;
+}
+
+static int
+vdev_remove_driver(struct rte_vdev_device *dev)
+{
+	const char *name = rte_vdev_device_name(dev);
+	const struct rte_vdev_driver *driver;
+
+	if (!dev->device.driver) {
+		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		return 1;
+	}
+
+	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
+		driver);
+	return driver->remove(dev);
+}
+
+int
+rte_vdev_uninit(const char *name)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	dev = find_vdev(name);
+	if (!dev)
+		return -ENOENT;
+
+	devargs = dev->device.devargs;
+
+	ret = vdev_remove_driver(dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&vdev_device_list, dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(dev);
+	return 0;
+}
+
+static int
+vdev_scan(void)
+{
+	struct rte_vdev_device *dev;
+	struct rte_devargs *devargs;
+
+	/* for virtual devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->bus != &rte_vdev_bus)
+			continue;
+
+		dev = find_vdev(devargs->name);
+		if (dev)
+			continue;
+
+		dev = calloc(1, sizeof(*dev));
+		if (!dev)
+			return -1;
+
+		dev->device.devargs = devargs;
+		dev->device.numa_node = SOCKET_ID_ANY;
+		dev->device.name = devargs->name;
+
+		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+static int
+vdev_probe(void)
+{
+	struct rte_vdev_device *dev;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+
+		if (dev->device.driver)
+			continue;
+
+		if (vdev_probe_all_drivers(dev)) {
+			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+				rte_vdev_device_name(dev));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static struct rte_device *
+vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		 const void *data)
+{
+	struct rte_vdev_device *dev;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		if (start && &dev->device == start) {
+			start = NULL;
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+	return NULL;
+}
+
+static int
+vdev_plug(struct rte_device *dev)
+{
+	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
+}
+
+static int
+vdev_unplug(struct rte_device *dev)
+{
+	return rte_vdev_uninit(dev->name);
+}
+
+static struct rte_bus rte_vdev_bus = {
+	.scan = vdev_scan,
+	.probe = vdev_probe,
+	.find_device = vdev_find_device,
+	.plug = vdev_plug,
+	.unplug = vdev_unplug,
+	.parse = vdev_parse,
+};
+
+RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/crypto/aesni_gcm/Makefile b/drivers/crypto/aesni_gcm/Makefile
index 44979a4..ddfec4c 100644
--- a/drivers/crypto/aesni_gcm/Makefile
+++ b/drivers/crypto/aesni_gcm/Makefile
@@ -55,6 +55,7 @@ CFLAGS += -I$(AESNI_MULTI_BUFFER_LIB_PATH)/include
 LDLIBS += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm_pmd.c
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index 444cfa2..08dcacc 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -34,7 +34,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 #include <rte_byteorder.h>
diff --git a/drivers/crypto/aesni_mb/Makefile b/drivers/crypto/aesni_mb/Makefile
index 7c7e970..a49f06f 100644
--- a/drivers/crypto/aesni_mb/Makefile
+++ b/drivers/crypto/aesni_mb/Makefile
@@ -55,6 +55,7 @@ CFLAGS += -I$(AESNI_MULTI_BUFFER_LIB_PATH)/include
 LDLIBS += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += rte_aesni_mb_pmd.c
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index a589557..7004389 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -36,7 +36,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/armv8/Makefile b/drivers/crypto/armv8/Makefile
index 8bf60e2..79c260f 100644
--- a/drivers/crypto/armv8/Makefile
+++ b/drivers/crypto/armv8/Makefile
@@ -59,6 +59,7 @@ CFLAGS += -I$(ARMV8_CRYPTO_LIB_PATH)/asm/include
 LDLIBS += -L$(ARMV8_CRYPTO_LIB_PATH) -larmv8_crypto
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += rte_armv8_pmd.c
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index 2d2f3ff..97719f2 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -36,7 +36,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/kasumi/Makefile b/drivers/crypto/kasumi/Makefile
index b9daf45..cf56b7a 100644
--- a/drivers/crypto/kasumi/Makefile
+++ b/drivers/crypto/kasumi/Makefile
@@ -56,6 +56,7 @@ CFLAGS += -I$(LIBSSO_KASUMI_PATH)/build
 LDLIBS += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += rte_kasumi_pmd.c
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index b677e54..f5db5e3 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -34,7 +34,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/mrvl/Makefile b/drivers/crypto/mrvl/Makefile
index abf4035..3532f7c 100644
--- a/drivers/crypto/mrvl/Makefile
+++ b/drivers/crypto/mrvl/Makefile
@@ -57,6 +57,7 @@ EXPORT_MAP := rte_mrvl_pmd_version.map
 
 # external library dependencies
 LDLIBS += -L$(LIBMUSDK_PATH)/lib -lmusdk
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO) += rte_mrvl_pmd.c
diff --git a/drivers/crypto/mrvl/rte_mrvl_pmd.c b/drivers/crypto/mrvl/rte_mrvl_pmd.c
index f778a80..31f3fe5 100644
--- a/drivers/crypto/mrvl/rte_mrvl_pmd.c
+++ b/drivers/crypto/mrvl/rte_mrvl_pmd.c
@@ -36,7 +36,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/null/Makefile b/drivers/crypto/null/Makefile
index b368161..49ada09 100644
--- a/drivers/crypto/null/Makefile
+++ b/drivers/crypto/null/Makefile
@@ -39,6 +39,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_vdev
 
 # library version
 LIBABIVER := 1
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 3f2a90d..f031d3b 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -32,7 +32,7 @@
 
 #include <rte_common.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 
 #include "null_crypto_pmd_private.h"
diff --git a/drivers/crypto/openssl/Makefile b/drivers/crypto/openssl/Makefile
index 85e5d87..1a00643 100644
--- a/drivers/crypto/openssl/Makefile
+++ b/drivers/crypto/openssl/Makefile
@@ -47,6 +47,7 @@ EXPORT_MAP := rte_pmd_openssl_version.map
 LDLIBS += -lcrypto
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL) += rte_openssl_pmd.c
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 25c1154..06e1a6d 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -34,7 +34,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/scheduler/Makefile b/drivers/crypto/scheduler/Makefile
index b1a468e..123b0f6 100644
--- a/drivers/crypto/scheduler/Makefile
+++ b/drivers/crypto/scheduler/Makefile
@@ -38,6 +38,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev -lrte_kvargs -lrte_reorder
+LDLIBS += -lrte_bus_vdev
 
 # library version
 LIBABIVER := 1
diff --git a/drivers/crypto/scheduler/scheduler_pmd.c b/drivers/crypto/scheduler/scheduler_pmd.c
index 40ab304..acdf636 100644
--- a/drivers/crypto/scheduler/scheduler_pmd.c
+++ b/drivers/crypto/scheduler/scheduler_pmd.c
@@ -33,7 +33,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 #include <rte_reorder.h>
diff --git a/drivers/crypto/snow3g/Makefile b/drivers/crypto/snow3g/Makefile
index 1fb0571..183c6ce 100644
--- a/drivers/crypto/snow3g/Makefile
+++ b/drivers/crypto/snow3g/Makefile
@@ -56,6 +56,7 @@ CFLAGS += -I$(LIBSSO_SNOW3G_PATH)/build
 LDLIBS += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += rte_snow3g_pmd.c
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index 094ddc4..4cc9a94 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -34,7 +34,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/crypto/zuc/Makefile b/drivers/crypto/zuc/Makefile
index 9d03cf0..af77bc8 100644
--- a/drivers/crypto/zuc/Makefile
+++ b/drivers/crypto/zuc/Makefile
@@ -56,6 +56,7 @@ CFLAGS += -I$(LIBSSO_ZUC_PATH)/build
 LDLIBS += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += rte_zuc_pmd.c
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index 5c1f71f..590224b 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -34,7 +34,7 @@
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
 
diff --git a/drivers/event/dpaa2/Makefile b/drivers/event/dpaa2/Makefile
index d268e33..f34eebf 100644
--- a/drivers/event/dpaa2/Makefile
+++ b/drivers/event/dpaa2/Makefile
@@ -46,6 +46,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa2
 CFLAGS += -I$(RTE_SDK)/drivers/event/dpaa2
 CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_bus_fslmc -lrte_pmd_dpaa2
+LDLIBS += -lrte_bus_vdev
 CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
 CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc
 
diff --git a/drivers/event/dpaa2/dpaa2_eventdev.c b/drivers/event/dpaa2/dpaa2_eventdev.c
index a23c734..eeeb231 100644
--- a/drivers/event/dpaa2/dpaa2_eventdev.c
+++ b/drivers/event/dpaa2/dpaa2_eventdev.c
@@ -51,7 +51,7 @@
 #include <rte_memcpy.h>
 #include <rte_memory.h>
 #include <rte_pci.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_ethdev.h>
 #include <rte_event_eth_rx_adapter.h>
 
diff --git a/drivers/event/octeontx/Makefile b/drivers/event/octeontx/Makefile
index ae901a3..fdf1b73 100644
--- a/drivers/event/octeontx/Makefile
+++ b/drivers/event/octeontx/Makefile
@@ -43,6 +43,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/net/octeontx/
 
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_mempool_octeontx
 LDLIBS += -lrte_bus_pci
+LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_octeontx_ssovf_version.map
 
diff --git a/drivers/event/octeontx/ssovf_evdev.c b/drivers/event/octeontx/ssovf_evdev.c
index ca866ea..117b145 100644
--- a/drivers/event/octeontx/ssovf_evdev.c
+++ b/drivers/event/octeontx/ssovf_evdev.c
@@ -42,7 +42,7 @@
 #include <rte_log.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "ssovf_evdev.h"
 
diff --git a/drivers/event/skeleton/Makefile b/drivers/event/skeleton/Makefile
index 65e1641..a24738b 100644
--- a/drivers/event/skeleton/Makefile
+++ b/drivers/event/skeleton/Makefile
@@ -40,6 +40,7 @@ LIB = librte_pmd_skeleton_event.a
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_eventdev
 LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_skeleton_event_version.map
 
diff --git a/drivers/event/skeleton/skeleton_eventdev.c b/drivers/event/skeleton/skeleton_eventdev.c
index a014dcf..bb554c3 100644
--- a/drivers/event/skeleton/skeleton_eventdev.c
+++ b/drivers/event/skeleton/skeleton_eventdev.c
@@ -46,7 +46,7 @@
 #include <rte_malloc.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "skeleton_eventdev.h"
 
diff --git a/drivers/event/sw/Makefile b/drivers/event/sw/Makefile
index 61a108c..2f2b67b 100644
--- a/drivers/event/sw/Makefile
+++ b/drivers/event/sw/Makefile
@@ -44,6 +44,7 @@ CFLAGS += -Wno-missing-field-initializers
 endif
 endif
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_kvargs -lrte_ring
+LDLIBS += -lrte_bus_vdev
 
 # library version
 LIBABIVER := 1
diff --git a/drivers/event/sw/sw_evdev.c b/drivers/event/sw/sw_evdev.c
index 1ba0fb6..fd11079 100644
--- a/drivers/event/sw/sw_evdev.c
+++ b/drivers/event/sw/sw_evdev.c
@@ -33,7 +33,7 @@
 #include <inttypes.h>
 #include <string.h>
 
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_ring.h>
 #include <rte_errno.h>
diff --git a/drivers/net/af_packet/Makefile b/drivers/net/af_packet/Makefile
index b97c2a6..bb37d67 100644
--- a/drivers/net/af_packet/Makefile
+++ b/drivers/net/af_packet/Makefile
@@ -46,6 +46,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_vdev
 
 #
 # all source are stored in SRCS-y
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 28e6a94..fa84eb9 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -41,7 +41,7 @@
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
 #include <rte_kvargs.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include <linux/if_ether.h>
 #include <linux/if_packet.h>
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index b86b240..dea1bd5 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -41,6 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
 LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_bond_version.map
 
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index 8c602f8..980e636 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -37,7 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_ethdev.h>
 #include <rte_tcp.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 
 #include "rte_eth_bond.h"
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 53d8e98..fe23289 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -43,7 +43,7 @@
 #include <rte_ip_frag.h>
 #include <rte_devargs.h>
 #include <rte_kvargs.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_alarm.h>
 #include <rte_cycles.h>
 
diff --git a/drivers/net/failsafe/Makefile b/drivers/net/failsafe/Makefile
index e533d54..ea2a8fe 100644
--- a/drivers/net/failsafe/Makefile
+++ b/drivers/net/failsafe/Makefile
@@ -60,5 +60,6 @@ CFLAGS += -Wno-strict-prototypes
 CFLAGS += -pedantic
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_vdev
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/failsafe/failsafe.c b/drivers/net/failsafe/failsafe.c
index 6006bef..6bc5aba 100644
--- a/drivers/net/failsafe/failsafe.c
+++ b/drivers/net/failsafe/failsafe.c
@@ -37,7 +37,7 @@
 #include <rte_ethdev_vdev.h>
 #include <rte_devargs.h>
 #include <rte_kvargs.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "failsafe_private.h"
 
diff --git a/drivers/net/kni/Makefile b/drivers/net/kni/Makefile
index 00d099f..a3f51f9 100644
--- a/drivers/net/kni/Makefile
+++ b/drivers/net/kni/Makefile
@@ -40,6 +40,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lpthread
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_kni
+LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_kni_version.map
 
diff --git a/drivers/net/kni/rte_eth_kni.c b/drivers/net/kni/rte_eth_kni.c
index d68ff7a..36e90fd 100644
--- a/drivers/net/kni/rte_eth_kni.c
+++ b/drivers/net/kni/rte_eth_kni.c
@@ -40,7 +40,7 @@
 #include <rte_kni.h>
 #include <rte_kvargs.h>
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 /* Only single queue supported */
 #define KNI_MAX_QUEUE_PER_PORT 1
diff --git a/drivers/net/mrvl/Makefile b/drivers/net/mrvl/Makefile
index a313055..815c3ba 100644
--- a/drivers/net/mrvl/Makefile
+++ b/drivers/net/mrvl/Makefile
@@ -59,6 +59,7 @@ LDLIBS += -L$(LIBMUSDK_PATH)/lib
 LDLIBS += -lmusdk
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cfgfile
+LDLIBS += -lrte_bus_vdev
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_MRVL_PMD) += mrvl_ethdev.c
diff --git a/drivers/net/mrvl/mrvl_ethdev.c b/drivers/net/mrvl/mrvl_ethdev.c
index a897ba0..2936165 100644
--- a/drivers/net/mrvl/mrvl_ethdev.c
+++ b/drivers/net/mrvl/mrvl_ethdev.c
@@ -36,7 +36,7 @@
 #include <rte_kvargs.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 /* Unluckily, container_of is defined by both DPDK and MUSDK,
  * we'll declare only one version.
diff --git a/drivers/net/null/Makefile b/drivers/net/null/Makefile
index c2404f4..9331cca 100644
--- a/drivers/net/null/Makefile
+++ b/drivers/net/null/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_null_version.map
 
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 3433c9c..032c30e 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -36,7 +36,7 @@
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
 
diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile
index 078fcd4..9c27fdf 100644
--- a/drivers/net/octeontx/Makefile
+++ b/drivers/net/octeontx/Makefile
@@ -74,5 +74,6 @@ LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_mempool_octeontx
 LDLIBS += -lrte_eventdev
 LDLIBS += -lrte_bus_pci
+LDLIBS += -lrte_bus_vdev
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 86de5d1..bd24ec3 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -44,7 +44,7 @@
 #include <rte_kvargs.h>
 #include <rte_malloc.h>
 #include <rte_prefetch.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "octeontx_ethdev.h"
 #include "octeontx_rxtx.h"
diff --git a/drivers/net/pcap/Makefile b/drivers/net/pcap/Makefile
index 9ea9670..b6487d4 100644
--- a/drivers/net/pcap/Makefile
+++ b/drivers/net/pcap/Makefile
@@ -42,6 +42,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lpcap
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_pcap_version.map
 
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 3205df8..f683d3a 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -44,7 +44,7 @@
 #include <rte_kvargs.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #define RTE_ETH_PCAP_SNAPSHOT_LEN 65535
 #define RTE_ETH_PCAP_SNAPLEN ETHER_MAX_JUMBO_FRAME_LEN
diff --git a/drivers/net/ring/Makefile b/drivers/net/ring/Makefile
index 9edd7d5..085ffa5 100644
--- a/drivers/net/ring/Makefile
+++ b/drivers/net/ring/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_ring_version.map
 
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 76355a1..a73c631 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -37,7 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_string_fns.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_errno.h>
 
diff --git a/drivers/net/softnic/Makefile b/drivers/net/softnic/Makefile
index 4b15f00..09ed62e 100644
--- a/drivers/net/softnic/Makefile
+++ b/drivers/net/softnic/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_sched
+LDLIBS += -lrte_bus_vdev
 
 EXPORT_MAP := rte_pmd_eth_softnic_version.map
 
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index abb617a..3e47c2f 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -38,7 +38,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_errno.h>
 #include <rte_ring.h>
diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index b5c5a35..405b49e 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -45,6 +45,7 @@ CFLAGS += -I.
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_vdev
 
 #
 # all source are stored in SRCS-y
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 64dd3b0..6b27679 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -39,7 +39,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_net.h>
 #include <rte_debug.h>
diff --git a/drivers/net/vhost/Makefile b/drivers/net/vhost/Makefile
index 1085a52..c411745 100644
--- a/drivers/net/vhost/Makefile
+++ b/drivers/net/vhost/Makefile
@@ -39,6 +39,7 @@ LIB = librte_pmd_vhost.a
 LDLIBS += -lpthread
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_vhost
+LDLIBS += -lrte_bus_vdev
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index f98c980..53f61f0 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -39,7 +39,7 @@
 #include <rte_ethdev_vdev.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_vhost.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile
index 32e99da..f2b5d1c 100644
--- a/drivers/net/virtio/Makefile
+++ b/drivers/net/virtio/Makefile
@@ -41,6 +41,9 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_pci
+ifeq ($(CONFIG_RTE_VIRTIO_USER),y)
+LDLIBS += -lrte_bus_vdev
+endif
 
 EXPORT_MAP := rte_pmd_virtio_version.map
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 0cfa27b..7be57ce 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -40,7 +40,7 @@
 #include <rte_malloc.h>
 #include <rte_kvargs.h>
 #include <rte_ethdev_vdev.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_alarm.h>
 
 #include "virtio_ethdev.h"
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index eb94f3e..afa117d 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -67,7 +67,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 16a2f26..9effd0d 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -39,7 +39,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
deleted file mode 100644
index f7e547a..0000000
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/queue.h>
-
-#include <rte_eal.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-#include <rte_vdev.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-/* Forward declare to access virtual bus name */
-static struct rte_bus rte_vdev_bus;
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_device_list, rte_vdev_device);
-
-static struct vdev_device_list vdev_device_list =
-	TAILQ_HEAD_INITIALIZER(vdev_device_list);
-struct vdev_driver_list vdev_driver_list =
-	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
-
-/* register a driver */
-void
-rte_vdev_register(struct rte_vdev_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
-}
-
-/* unregister a driver */
-void
-rte_vdev_unregister(struct rte_vdev_driver *driver)
-{
-	TAILQ_REMOVE(&vdev_driver_list, driver, next);
-}
-
-static int
-vdev_parse(const char *name, void *addr)
-{
-	struct rte_vdev_driver **out = addr;
-	struct rte_vdev_driver *driver = NULL;
-
-	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
-		if (strncmp(driver->driver.name, name,
-			    strlen(driver->driver.name)) == 0)
-			break;
-		if (driver->driver.alias &&
-		    strncmp(driver->driver.alias, name,
-			    strlen(driver->driver.alias)) == 0)
-			break;
-	}
-	if (driver != NULL &&
-	    addr != NULL)
-		*out = driver;
-	return driver == NULL;
-}
-
-static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
-{
-	const char *name;
-	struct rte_vdev_driver *driver;
-	int ret;
-
-	name = rte_vdev_device_name(dev);
-
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
-		rte_vdev_device_name(dev));
-
-	if (vdev_parse(name, &driver))
-		return -1;
-	dev->device.driver = &driver->driver;
-	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
-	return ret;
-}
-
-static struct rte_vdev_device *
-find_vdev(const char *name)
-{
-	struct rte_vdev_device *dev;
-
-	if (!name)
-		return NULL;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		const char *devname = rte_vdev_device_name(dev);
-		if (!strncmp(devname, name, strlen(name)))
-			return dev;
-	}
-
-	return NULL;
-}
-
-static struct rte_devargs *
-alloc_devargs(const char *name, const char *args)
-{
-	struct rte_devargs *devargs;
-	int ret;
-
-	devargs = calloc(1, sizeof(*devargs));
-	if (!devargs)
-		return NULL;
-
-	devargs->bus = &rte_vdev_bus;
-	if (args)
-		devargs->args = strdup(args);
-	else
-		devargs->args = strdup("");
-
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
-		free(devargs->args);
-		free(devargs);
-		return NULL;
-	}
-
-	return devargs;
-}
-
-int
-rte_vdev_init(const char *name, const char *args)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (dev)
-		return -EEXIST;
-
-	devargs = alloc_devargs(name, args);
-	if (!devargs)
-		return -ENOMEM;
-
-	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	dev->device.devargs = devargs;
-	dev->device.numa_node = SOCKET_ID_ANY;
-	dev->device.name = devargs->name;
-
-	ret = vdev_probe_all_drivers(dev);
-	if (ret) {
-		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-		goto fail;
-	}
-
-	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
-
-	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	return 0;
-
-fail:
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return ret;
-}
-
-static int
-vdev_remove_driver(struct rte_vdev_device *dev)
-{
-	const char *name = rte_vdev_device_name(dev);
-	const struct rte_vdev_driver *driver;
-
-	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
-		return 1;
-	}
-
-	driver = container_of(dev->device.driver, const struct rte_vdev_driver,
-		driver);
-	return driver->remove(dev);
-}
-
-int
-rte_vdev_uninit(const char *name)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-	int ret;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	dev = find_vdev(name);
-	if (!dev)
-		return -ENOENT;
-
-	devargs = dev->device.devargs;
-
-	ret = vdev_remove_driver(dev);
-	if (ret)
-		return ret;
-
-	TAILQ_REMOVE(&vdev_device_list, dev, next);
-
-	TAILQ_REMOVE(&devargs_list, devargs, next);
-
-	free(devargs->args);
-	free(devargs);
-	free(dev);
-	return 0;
-}
-
-static int
-vdev_scan(void)
-{
-	struct rte_vdev_device *dev;
-	struct rte_devargs *devargs;
-
-	/* for virtual devices we scan the devargs_list populated via cmdline */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->bus != &rte_vdev_bus)
-			continue;
-
-		dev = find_vdev(devargs->name);
-		if (dev)
-			continue;
-
-		dev = calloc(1, sizeof(*dev));
-		if (!dev)
-			return -1;
-
-		dev->device.devargs = devargs;
-		dev->device.numa_node = SOCKET_ID_ANY;
-		dev->device.name = devargs->name;
-
-		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
-	}
-
-	return 0;
-}
-
-static int
-vdev_probe(void)
-{
-	struct rte_vdev_device *dev;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-
-		if (dev->device.driver)
-			continue;
-
-		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
-				rte_vdev_device_name(dev));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		 const void *data)
-{
-	struct rte_vdev_device *dev;
-
-	TAILQ_FOREACH(dev, &vdev_device_list, next) {
-		if (start && &dev->device == start) {
-			start = NULL;
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-	return NULL;
-}
-
-static int
-vdev_plug(struct rte_device *dev)
-{
-	return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev));
-}
-
-static int
-vdev_unplug(struct rte_device *dev)
-{
-	return rte_vdev_uninit(dev->name);
-}
-
-static struct rte_bus rte_vdev_bus = {
-	.scan = vdev_scan,
-	.probe = vdev_probe,
-	.find_device = vdev_find_device,
-	.plug = vdev_plug,
-	.unplug = vdev_unplug,
-	.parse = vdev_parse,
-};
-
-RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index c3f7246..9342e0c 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -169,28 +169,6 @@ struct rte_device {
 };
 
 /**
- * Initialize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @param args
- *   The pointer to arguments used by driver initialization.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_init(const char *name, const char *args);
-
-/**
- * Uninitalize a driver specified by name.
- *
- * @param name
- *   The pointer to a driver name to be initialized.
- * @return
- *  0 on success, negative on error
- */
-int rte_vdev_uninit(const char *name);
-
-/**
  * Attach a device to a registered driver.
  *
  * @param name
@@ -315,4 +293,4 @@ __attribute__((used)) = str
 }
 #endif
 
-#endif /* _RTE_VDEV_H_ */
+#endif /* _RTE_DEV_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
deleted file mode 100644
index 29f5a52..0000000
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 RehiveTech. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of RehiveTech nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTE_VDEV_H
-#define RTE_VDEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/queue.h>
-#include <rte_dev.h>
-#include <rte_devargs.h>
-
-struct rte_vdev_device {
-	TAILQ_ENTRY(rte_vdev_device) next;      /**< Next attached vdev */
-	struct rte_device device;               /**< Inherit core device */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_vdev_device.
- */
-#define RTE_DEV_TO_VDEV(ptr) \
-	container_of(ptr, struct rte_vdev_device, device)
-
-static inline const char *
-rte_vdev_device_name(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.name)
-		return dev->device.name;
-	return NULL;
-}
-
-static inline const char *
-rte_vdev_device_args(const struct rte_vdev_device *dev)
-{
-	if (dev && dev->device.devargs)
-		return dev->device.devargs->args;
-	return "";
-}
-
-/** Double linked list of virtual device drivers. */
-TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
-
-/**
- * Probe function called for each virtual device driver once.
- */
-typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev);
-
-/**
- * Remove function called for each virtual device driver once.
- */
-typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev);
-
-/**
- * A virtual device driver abstraction.
- */
-struct rte_vdev_driver {
-	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
-	struct rte_driver driver;      /**< Inherited general driver. */
-	rte_vdev_probe_t *probe;       /**< Virtual device probe function. */
-	rte_vdev_remove_t *remove;     /**< Virtual device remove function. */
-};
-
-/**
- * Register a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be registered.
- */
-void rte_vdev_register(struct rte_vdev_driver *driver);
-
-/**
- * Unregister a virtual device driver.
- *
- * @param driver
- *   A pointer to a rte_vdev_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_vdev_unregister(struct rte_vdev_driver *driver);
-
-#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\
-RTE_INIT(vdrvinitfn_ ##vdrv);\
-static const char *vdrvinit_ ## nm ## _alias;\
-static void vdrvinitfn_ ##vdrv(void)\
-{\
-	(vdrv).driver.name = RTE_STR(nm);\
-	(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
-	rte_vdev_register(&vdrv);\
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
-static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 919d371..5a7b8b2 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -74,7 +74,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 5521d01..f4f46c1 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -163,10 +163,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_vdev_init;
-	rte_vdev_register;
-	rte_vdev_uninit;
-	rte_vdev_unregister;
 	vfio_get_container_fd;
 	vfio_get_group_fd;
 	vfio_get_group_no;
diff --git a/lib/librte_ether/rte_ethdev_vdev.h b/lib/librte_ether/rte_ethdev_vdev.h
index 4d2c3e2..ff92e6e 100644
--- a/lib/librte_ether/rte_ethdev_vdev.h
+++ b/lib/librte_ether/rte_ethdev_vdev.h
@@ -35,7 +35,7 @@
 #define _RTE_ETHDEV_VDEV_H_
 
 #include <rte_malloc.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_vdev.h b/lib/librte_eventdev/rte_eventdev_pmd_vdev.h
index 135e8b8..56232de 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_vdev.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_vdev.h
@@ -48,7 +48,7 @@ extern "C" {
 
 #include <rte_debug.h>
 #include <rte_eal.h>
-#include <rte_vdev.h>
+#include <rte_bus_vdev.h>
 
 #include "rte_eventdev_pmd.h"
 
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 047121d..6a6a745 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -110,6 +110,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS)       += -lrte_bus_vdev
 
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 060b498..1bed65d 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_pause.h>
+#include <rte_bus_vdev.h>
 
 #include <rte_crypto.h>
 #include <rte_cryptodev.h>
diff --git a/test/test/test_event_eth_rx_adapter.c b/test/test/test_event_eth_rx_adapter.c
index 56ed1f8..90a5c64 100644
--- a/test/test/test_event_eth_rx_adapter.c
+++ b/test/test/test_event_eth_rx_adapter.c
@@ -35,6 +35,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
+#include <rte_bus_vdev.h>
 
 #include <rte_event_eth_rx_adapter.h>
 
diff --git a/test/test/test_eventdev.c b/test/test/test_eventdev.c
index 4118b75..ba39cba 100644
--- a/test/test/test_eventdev.c
+++ b/test/test/test_eventdev.c
@@ -37,6 +37,7 @@
 #include <rte_memcpy.h>
 #include <rte_eventdev.h>
 #include <rte_dev.h>
+#include <rte_bus_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_octeontx.c b/test/test/test_eventdev_octeontx.c
index b88b0d2..dbc36d9 100644
--- a/test/test/test_eventdev_octeontx.c
+++ b/test/test/test_eventdev_octeontx.c
@@ -45,6 +45,7 @@
 #include <rte_lcore.h>
 #include <rte_per_lcore.h>
 #include <rte_random.h>
+#include <rte_bus_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_eventdev_sw.c b/test/test/test_eventdev_sw.c
index 01aa4d9..f524b6f 100644
--- a/test/test/test_eventdev_sw.c
+++ b/test/test/test_eventdev_sw.c
@@ -50,6 +50,7 @@
 #include <rte_pause.h>
 #include <rte_service.h>
 #include <rte_service_component.h>
+#include <rte_bus_vdev.h>
 
 #include "test.h"
 
diff --git a/test/test/test_link_bonding_rssconf.c b/test/test/test_link_bonding_rssconf.c
index 7dccc6e..54cbf12 100644
--- a/test/test/test_link_bonding_rssconf.c
+++ b/test/test/test_link_bonding_rssconf.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_lcore.h>
 #include <rte_memory.h>
+#include <rte_bus_vdev.h>
 
 #include <rte_string_fns.h>
 #include <rte_errno.h>
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* [PATCH v12 4/4] bus/vdev: change log type
  2017-11-07  6:54   ` [PATCH v12 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (2 preceding siblings ...)
  2017-11-07  6:54     ` [PATCH v12 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
@ 2017-11-07  6:54     ` Jianfeng Tan
  2017-11-07 15:43     ` [PATCH v12 0/4] move vdev into drivers/bus Thomas Monjalon
  4 siblings, 0 replies; 158+ messages in thread
From: Jianfeng Tan @ 2017-11-07  6:54 UTC (permalink / raw)
  To: dev
  Cc: jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, thomas, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit, Jianfeng Tan

Use specialized dynamic log type for vdev bus logging.

Suggested-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Suggested-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/bus/vdev/vdev.c      | 20 ++++++++++++++++----
 drivers/bus/vdev/vdev_logs.h | 45 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 drivers/bus/vdev/vdev_logs.h

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 04ed49b..1f8efe2 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -47,6 +47,9 @@
 #include <rte_errno.h>
 
 #include "rte_bus_vdev.h"
+#include "vdev_logs.h"
+
+int vdev_logtype_bus;
 
 /* Forward declare to access virtual bus name */
 static struct rte_bus rte_vdev_bus;
@@ -103,7 +106,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	name = rte_vdev_device_name(dev);
 
-	RTE_LOG(DEBUG, EAL, "Search driver %s to probe device %s\n", name,
+	VDEV_LOG(DEBUG, "Search driver %s to probe device %s\n", name,
 		rte_vdev_device_name(dev));
 
 	if (vdev_parse(name, &driver))
@@ -190,7 +193,7 @@ rte_vdev_init(const char *name, const char *args)
 	ret = vdev_probe_all_drivers(dev);
 	if (ret) {
 		if (ret > 0)
-			RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+			VDEV_LOG(ERR, "no driver found for %s\n", name);
 		goto fail;
 	}
 
@@ -213,7 +216,7 @@ vdev_remove_driver(struct rte_vdev_device *dev)
 	const struct rte_vdev_driver *driver;
 
 	if (!dev->device.driver) {
-		RTE_LOG(DEBUG, EAL, "no driver attach to device %s\n", name);
+		VDEV_LOG(DEBUG, "no driver attach to device %s\n", name);
 		return 1;
 	}
 
@@ -294,7 +297,7 @@ vdev_probe(void)
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
-			RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+			VDEV_LOG(ERR, "failed to initialize %s device\n",
 				rte_vdev_device_name(dev));
 			return -1;
 		}
@@ -342,3 +345,12 @@ static struct rte_bus rte_vdev_bus = {
 };
 
 RTE_REGISTER_BUS(vdev, rte_vdev_bus);
+
+RTE_INIT(vdev_init_log);
+static void
+vdev_init_log(void)
+{
+	vdev_logtype_bus = rte_log_register("bus.vdev");
+	if (vdev_logtype_bus >= 0)
+		rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE);
+}
diff --git a/drivers/bus/vdev/vdev_logs.h b/drivers/bus/vdev/vdev_logs.h
new file mode 100644
index 0000000..43b0ab8
--- /dev/null
+++ b/drivers/bus/vdev/vdev_logs.h
@@ -0,0 +1,45 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VDEV_LOGS_H_
+#define _VDEV_LOGS_H_
+
+#include <rte_log.h>
+
+extern int vdev_logtype_bus;
+
+#define VDEV_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, vdev_logtype_bus, "%s(): " fmt "\n", \
+		__func__, ##args)
+
+#endif /* _VDEV_LOGS_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 158+ messages in thread

* Re: [PATCH v12 0/4] move vdev into drivers/bus
  2017-11-07  6:54   ` [PATCH v12 0/4] move vdev into drivers/bus Jianfeng Tan
                       ` (3 preceding siblings ...)
  2017-11-07  6:54     ` [PATCH v12 4/4] bus/vdev: change log type Jianfeng Tan
@ 2017-11-07 15:43     ` Thomas Monjalon
  4 siblings, 0 replies; 158+ messages in thread
From: Thomas Monjalon @ 2017-11-07 15:43 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, jblunck, bruce.richardson, konstantin.ananyev,
	pablo.de.lara.guarch, yliu, maxime.coquelin, mtetsuyah,
	ferruh.yigit

> Jianfeng Tan (4):
>   cryptodev: remove crypto vdev init API
>   eal: remove dependency on vdev
>   bus/vdev: move to vdev bus to drivers/bus
>   bus/vdev: change log type

Applied with few small nitpick changes, thanks

^ permalink raw reply	[flat|nested] 158+ messages in thread

end of thread, other threads:[~2017-11-07 15:43 UTC | newest]

Thread overview: 158+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-25  9:40 [PATCH 00/12] support to run vdev in the secondary process Jianfeng Tan
2017-08-25  9:40 ` [PATCH 01/12] cryptodev: remove crypto vdev init Jianfeng Tan
2017-09-18 11:48   ` De Lara Guarch, Pablo
2017-08-25  9:40 ` [PATCH 02/12] eal: avoid calling rte_vdev_init() Jianfeng Tan
2017-08-29 12:50   ` Gaëtan Rivet
2017-08-29 22:25     ` Tan, Jianfeng
2017-08-25  9:40 ` [PATCH 03/12] crypto: move vdev helper functions into dedicated file Jianfeng Tan
2017-09-18 11:51   ` De Lara Guarch, Pablo
2017-08-25  9:40 ` [PATCH 04/12] vdev: move to drivers/bus Jianfeng Tan
2017-08-29 13:04   ` Gaëtan Rivet
2017-08-29 22:47     ` Tan, Jianfeng
2017-09-18 11:47       ` De Lara Guarch, Pablo
2017-09-19  6:01         ` Tan, Jianfeng
2017-08-25  9:40 ` [PATCH 05/12] bus/vdev: change log type from EAL to PMD Jianfeng Tan
2017-08-29 12:54   ` Gaëtan Rivet
2017-08-29 22:27     ` Tan, Jianfeng
2017-08-25  9:40 ` [PATCH 06/12] eal: add channel for primary/secondary communication Jianfeng Tan
2017-09-18 13:49   ` Jiayu Hu
2017-09-21  6:11     ` Tan, Jianfeng
2017-09-20  3:00   ` Jiayu Hu
2017-09-21  6:53     ` Tan, Jianfeng
2017-09-27 12:19   ` Yuanhan Liu
2017-09-28 13:50     ` Tan, Jianfeng
2017-09-29  1:24       ` Yuanhan Liu
2017-09-29 10:09         ` Burakov, Anatoly
2017-09-29 10:25           ` Yuanhan Liu
2017-08-25  9:40 ` [PATCH 07/12] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
2017-08-25  9:40 ` [PATCH 08/12] ethdev: support attach vdev in secondary process Jianfeng Tan
2017-08-25  9:40 ` [PATCH 09/12] vhost: allocate virtio_net in memzone Jianfeng Tan
2017-08-25  9:40 ` [PATCH 10/12] vhost: support to kick in secondary process Jianfeng Tan
2017-09-21  3:33   ` Yuanhan Liu
2017-09-21  7:04     ` Tan, Jianfeng
2017-09-21  9:17       ` Yuanhan Liu
2017-09-22  2:30         ` Tan, Jianfeng
2017-09-27  9:36           ` Yuanhan Liu
2017-09-28  5:10             ` Tan, Jianfeng
2017-09-28  8:09             ` Tan, Jianfeng
2017-09-30  8:18               ` Yuanhan Liu
2017-09-30 10:50                 ` Tan, Jianfeng
2017-08-25  9:40 ` [PATCH 11/12] net/vhost: support to run in the " Jianfeng Tan
2017-09-21  4:29   ` Yuanhan Liu
2017-08-25  9:40 ` [PATCH 12/12] examples/helloworld: do not exit automatically Jianfeng Tan
2017-09-18 11:44   ` De Lara Guarch, Pablo
2017-09-19  5:07     ` Tan, Jianfeng
2017-09-28 13:55 ` [PATCH v2 00/12] support to run vdev in the secondary process Jianfeng Tan
2017-09-28 13:55   ` [PATCH v2 01/12] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-09-28 13:55   ` [PATCH v2 02/12] eal: avoid calling rte_vdev_init() Jianfeng Tan
2017-09-28 13:55   ` [PATCH v2 03/12] cryptodev: avoid dependency on rte_vdev.h Jianfeng Tan
2017-10-05 13:13     ` Jan Blunck
2017-10-09  1:04       ` Tan, Jianfeng
2017-09-28 13:55   ` [PATCH v2 04/12] bus/fslmc: introduce RTE_LOGTYPE_BUS for bus drivers Jianfeng Tan
2017-09-28 13:55   ` [PATCH v2 05/12] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-09-28 13:55   ` [PATCH v2 06/12] bus/vdev: normalize log type Jianfeng Tan
2017-09-28 13:55   ` [PATCH v2 07/12] eal: add channel for primary/secondary communication Jianfeng Tan
2017-09-28 15:01     ` Ananyev, Konstantin
2017-09-28 15:29       ` Burakov, Anatoly
2017-09-29  1:03         ` Tan, Jianfeng
2017-09-29 10:00           ` Burakov, Anatoly
2017-09-30  4:07             ` Tan, Jianfeng
2017-10-02 10:08               ` Burakov, Anatoly
2017-10-05 12:01     ` Jan Blunck
2017-10-09  1:27       ` Tan, Jianfeng
2017-09-28 13:55   ` [PATCH v2 08/12] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
2017-10-05 13:04     ` Jan Blunck
2017-10-09  1:08       ` Tan, Jianfeng
2017-09-28 13:55   ` [PATCH v2 09/12] ethdev: support attach vdev in secondary process Jianfeng Tan
2017-10-05 14:26     ` Jan Blunck
2017-10-09  0:56       ` Tan, Jianfeng
2017-09-28 13:55   ` [PATCH v2 10/12] vhost: allocate virtio_net in memzone Jianfeng Tan
2017-09-28 13:55   ` [PATCH v2 11/12] vhost: support to kick in secondary process Jianfeng Tan
2017-09-28 13:55   ` [PATCH v2 12/12] net/vhost: support to run in the " Jianfeng Tan
2017-09-29  8:28     ` Yuanhan Liu
2017-09-30  4:03       ` Tan, Jianfeng
2017-09-30  8:16         ` Yuanhan Liu
2017-09-30 10:06           ` Tan, Jianfeng
2017-09-30 11:49           ` Yuanhan Liu
2017-10-01 23:48             ` Tan, Jianfeng
2017-09-30  8:23     ` Yuanhan Liu
2017-09-30 10:53       ` Tan, Jianfeng
2017-09-30 11:34       ` Yuanhan Liu
2017-10-01 23:46         ` Tan, Jianfeng
2017-10-09  3:20 ` [PATCH v3 0/5] move vdev into drivers/bus Jianfeng Tan
2017-10-09  3:20   ` [PATCH v3 1/5] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-10-09  3:20   ` [PATCH v3 2/5] eal: avoid calling rte_vdev_init() Jianfeng Tan
2017-10-09  3:20   ` [PATCH v3 3/5] bus: introduce RTE_LOGTYPE_BUS for bus drivers Jianfeng Tan
2017-10-09  3:20   ` [PATCH v3 4/5] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-10-09  3:20   ` [PATCH v3 5/5] bus/vdev: normalize log type Jianfeng Tan
2017-10-09 10:55   ` [PATCH v4 0/5] move vdev into drivers/bus Jianfeng Tan
2017-10-09 10:55     ` [PATCH v4 1/5] bus/vdev: scan and probe vdev in secondary processes Jianfeng Tan
2017-10-09 10:55     ` [PATCH v4 2/5] ethdev: support attach vdev in secondary process Jianfeng Tan
2017-10-09 10:55     ` [PATCH v4 3/5] vhost: allocate virtio_net in memzone Jianfeng Tan
2017-10-09 10:55     ` [PATCH v4 4/5] vhost: support to kick in secondary process Jianfeng Tan
2017-10-09 10:55     ` [PATCH v4 5/5] net/vhost: support to run in the " Jianfeng Tan
2017-10-09 11:08     ` [PATCH v4 0/5] move vdev into drivers/bus Tan, Jianfeng
2017-10-09 11:27   ` [PATCH v5 " Jianfeng Tan
2017-10-09 11:27     ` [PATCH v5 1/5] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-10-09 11:27     ` [PATCH v5 2/5] eal: remove dependency on vdev Jianfeng Tan
2017-10-09 11:27     ` [PATCH v5 3/5] bus: introduce new log type for bus drivers Jianfeng Tan
2017-10-11  6:54       ` Shreyansh Jain
2017-10-11 10:42         ` Tan, Jianfeng
2017-10-11 11:20           ` Shreyansh Jain
2017-10-12  2:14             ` Tan, Jianfeng
2017-10-09 11:27     ` [PATCH v5 4/5] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-10-09 11:27     ` [PATCH v5 5/5] bus/vdev: normalize log type Jianfeng Tan
2017-10-12  8:46   ` [PATCH v6 0/4] move vdev into drivers/bus Jianfeng Tan
2017-10-12  8:46     ` [PATCH v6 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-10-12 10:06       ` Thomas Monjalon
2017-10-12  8:46     ` [PATCH v6 2/4] eal: remove dependency on vdev Jianfeng Tan
2017-10-12  8:46     ` [PATCH v6 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-10-12  8:46     ` [PATCH v6 4/4] bus/vdev: change log type Jianfeng Tan
2017-10-13  2:04   ` [PATCH v7 0/4] move vdev into drivers/bus Jianfeng Tan
2017-10-13  2:04     ` [PATCH v7 1/4] ethdev: support attach vdev in secondary process Jianfeng Tan
2017-10-13  2:04     ` [PATCH v7 2/4] vhost: allocate virtio_net in memzone Jianfeng Tan
2017-10-13  2:04     ` [PATCH v7 3/4] vhost: support to kick in secondary process Jianfeng Tan
2017-10-13  2:04     ` [PATCH v7 4/4] net/vhost: support to run in the " Jianfeng Tan
2017-10-13  8:26     ` [PATCH v7 0/4] move vdev into drivers/bus Thomas Monjalon
2017-10-13 11:49       ` Tan, Jianfeng
2017-10-13 11:51   ` Jianfeng Tan
2017-10-13 11:51     ` [PATCH v7 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-10-23 10:06       ` De Lara Guarch, Pablo
2017-10-13 11:51     ` [PATCH v7 2/4] eal: remove dependency on vdev Jianfeng Tan
2017-10-13 11:52     ` [PATCH v7 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-10-23 14:34       ` De Lara Guarch, Pablo
2017-10-13 11:52     ` [PATCH v7 4/4] bus/vdev: change log type Jianfeng Tan
2017-10-25 17:10   ` [PATCH v8 0/4] move vdev into drivers/bus Jianfeng Tan
2017-10-25 17:10     ` [PATCH v8 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-10-25 17:10     ` [PATCH v8 2/4] eal: remove dependency on vdev Jianfeng Tan
2017-10-25 17:10     ` [PATCH v8 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-10-25 21:32       ` De Lara Guarch, Pablo
2017-10-25 23:03       ` Gaëtan Rivet
2017-10-25 17:10     ` [PATCH v8 4/4] bus/vdev: change log type Jianfeng Tan
2017-10-27  1:06   ` [PATCH v0 0/4] move vdev into drivers/bus Jianfeng Tan
2017-10-27  1:06     ` [PATCH v9 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-10-27  1:06     ` [PATCH v9 2/4] eal: remove dependency on vdev Jianfeng Tan
2017-10-27  1:06     ` [PATCH v9 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-10-27  7:56       ` Thomas Monjalon
2017-10-27  8:19         ` Tan, Jianfeng
2017-10-27  8:53           ` Thomas Monjalon
2017-10-27 16:57             ` Gaëtan Rivet
2017-10-27  1:06     ` [PATCH v9 4/4] bus/vdev: change log type Jianfeng Tan
2017-10-27  3:23   ` [PATCH v10 0/4] move vdev into drivers/bus Jianfeng Tan
2017-10-27  3:23     ` [PATCH v10 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-10-27  3:23     ` [PATCH v10 2/4] eal: remove dependency on vdev Jianfeng Tan
2017-10-27  3:23     ` [PATCH v10 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-10-27  3:23     ` [PATCH v10 4/4] bus/vdev: change log type Jianfeng Tan
2017-10-30  8:28   ` [PATCH v11 0/4] move vdev into drivers/bus Jianfeng Tan
2017-10-30  8:28     ` [PATCH v11 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-10-30  8:28     ` [PATCH v11 2/4] eal: remove dependency on vdev Jianfeng Tan
2017-10-30  8:28     ` [PATCH v11 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-11-07  2:43       ` Thomas Monjalon
2017-11-07  6:21         ` Tan, Jianfeng
2017-10-30  8:28     ` [PATCH v11 4/4] bus/vdev: change log type Jianfeng Tan
2017-11-07  6:54   ` [PATCH v12 0/4] move vdev into drivers/bus Jianfeng Tan
2017-11-07  6:54     ` [PATCH v12 1/4] cryptodev: remove crypto vdev init API Jianfeng Tan
2017-11-07  6:54     ` [PATCH v12 2/4] eal: remove dependency on vdev Jianfeng Tan
2017-11-07  6:54     ` [PATCH v12 3/4] bus/vdev: move to vdev bus to drivers/bus Jianfeng Tan
2017-11-07  6:54     ` [PATCH v12 4/4] bus/vdev: change log type Jianfeng Tan
2017-11-07 15:43     ` [PATCH v12 0/4] move vdev into drivers/bus Thomas Monjalon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.