aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bus/vdev
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bus/vdev')
-rw-r--r--drivers/bus/vdev/Makefile5
-rw-r--r--drivers/bus/vdev/meson.build7
-rw-r--r--drivers/bus/vdev/vdev.c50
-rw-r--r--drivers/bus/vdev/vdev_params.c66
-rw-r--r--drivers/bus/vdev/vdev_private.h26
5 files changed, 132 insertions, 22 deletions
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
index bd0bb895..803b8ea7 100644
--- a/drivers/bus/vdev/Makefile
+++ b/drivers/bus/vdev/Makefile
@@ -16,11 +16,12 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
EXPORT_MAP := rte_bus_vdev_version.map
# library version
-LIBABIVER := 1
+LIBABIVER := 2
SRCS-y += vdev.c
+SRCS-y += vdev_params.c
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_eal -lrte_kvargs
#
# Export include files
diff --git a/drivers/bus/vdev/meson.build b/drivers/bus/vdev/meson.build
index 2ee648b4..803785f1 100644
--- a/drivers/bus/vdev/meson.build
+++ b/drivers/bus/vdev/meson.build
@@ -1,7 +1,12 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-sources = files('vdev.c')
+version = 2
+
+sources = files('vdev.c',
+ 'vdev_params.c')
install_headers('rte_bus_vdev.h')
allow_experimental_apis = true
+
+deps += ['kvargs']
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 6139dd55..9c66bdc7 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -23,6 +23,7 @@
#include "rte_bus_vdev.h"
#include "vdev_logs.h"
+#include "vdev_private.h"
#define VDEV_MP_KEY "bus_vdev_mp"
@@ -40,7 +41,7 @@ static struct vdev_device_list vdev_device_list =
static rte_spinlock_recursive_t vdev_device_list_lock =
RTE_SPINLOCK_RECURSIVE_INITIALIZER;
-struct vdev_driver_list vdev_driver_list =
+static struct vdev_driver_list vdev_driver_list =
TAILQ_HEAD_INITIALIZER(vdev_driver_list);
struct vdev_custom_scan {
@@ -149,10 +150,9 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
if (vdev_parse(name, &driver))
return -1;
- dev->device.driver = &driver->driver;
ret = driver->probe(dev);
- if (ret)
- dev->device.driver = NULL;
+ if (ret == 0)
+ dev->device.driver = &driver->driver;
return ret;
}
@@ -202,7 +202,9 @@ alloc_devargs(const char *name, const char *args)
}
static int
-insert_vdev(const char *name, const char *args, struct rte_vdev_device **p_dev)
+insert_vdev(const char *name, const char *args,
+ struct rte_vdev_device **p_dev,
+ bool init)
{
struct rte_vdev_device *dev;
struct rte_devargs *devargs;
@@ -221,17 +223,24 @@ insert_vdev(const char *name, const char *args, struct rte_vdev_device **p_dev)
goto fail;
}
+ dev->device.bus = &rte_vdev_bus;
dev->device.devargs = devargs;
dev->device.numa_node = SOCKET_ID_ANY;
dev->device.name = devargs->name;
if (find_vdev(name)) {
+ /*
+ * A vdev is expected to have only one port.
+ * So there is no reason to try probing again,
+ * even with new arguments.
+ */
ret = -EEXIST;
goto fail;
}
TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
- rte_devargs_insert(devargs);
+ if (init)
+ rte_devargs_insert(devargs);
if (p_dev)
*p_dev = dev;
@@ -248,20 +257,18 @@ int
rte_vdev_init(const char *name, const char *args)
{
struct rte_vdev_device *dev;
- struct rte_devargs *devargs;
int ret;
rte_spinlock_recursive_lock(&vdev_device_list_lock);
- ret = insert_vdev(name, args, &dev);
+ ret = insert_vdev(name, args, &dev, true);
if (ret == 0) {
ret = vdev_probe_all_drivers(dev);
if (ret) {
if (ret > 0)
VDEV_LOG(ERR, "no driver found for %s", name);
/* If fails, remove it from vdev list */
- devargs = dev->device.devargs;
TAILQ_REMOVE(&vdev_device_list, dev, next);
- rte_devargs_remove(devargs->bus->name, devargs->name);
+ rte_devargs_remove(dev->device.devargs);
free(dev);
}
}
@@ -289,7 +296,6 @@ int
rte_vdev_uninit(const char *name)
{
struct rte_vdev_device *dev;
- struct rte_devargs *devargs;
int ret;
if (name == NULL)
@@ -308,8 +314,7 @@ rte_vdev_uninit(const char *name)
goto unlock;
TAILQ_REMOVE(&vdev_device_list, dev, next);
- devargs = dev->device.devargs;
- rte_devargs_remove(devargs->bus->name, devargs->name);
+ rte_devargs_remove(dev->device.devargs);
free(dev);
unlock:
@@ -346,6 +351,7 @@ vdev_action(const struct rte_mp_msg *mp_msg, const void *peer)
const struct vdev_param *in = (const struct vdev_param *)mp_msg->param;
const char *devname;
int num;
+ int ret;
strlcpy(mp_resp.name, VDEV_MP_KEY, sizeof(mp_resp.name));
mp_resp.len_param = sizeof(*ou);
@@ -380,7 +386,10 @@ vdev_action(const struct rte_mp_msg *mp_msg, const void *peer)
break;
case VDEV_SCAN_ONE:
VDEV_LOG(INFO, "receive vdev, %s", in->name);
- if (insert_vdev(in->name, NULL, NULL) < 0)
+ ret = insert_vdev(in->name, NULL, NULL, false);
+ if (ret == -EEXIST)
+ VDEV_LOG(DEBUG, "device already exist, %s", in->name);
+ else if (ret < 0)
VDEV_LOG(ERR, "failed to add vdev, %s", in->name);
break;
default:
@@ -419,6 +428,7 @@ vdev_scan(void)
mp_rep = &mp_reply.msgs[0];
resp = (struct vdev_param *)mp_rep->param;
VDEV_LOG(INFO, "Received %d vdevs", resp->num);
+ free(mp_reply.msgs);
} else
VDEV_LOG(ERR, "Failed to request vdev from primary");
@@ -455,6 +465,7 @@ vdev_scan(void)
continue;
}
+ dev->device.bus = &rte_vdev_bus;
dev->device.devargs = devargs;
dev->device.numa_node = SOCKET_ID_ANY;
dev->device.name = devargs->name;
@@ -480,7 +491,7 @@ vdev_probe(void)
* we call each driver probe.
*/
- if (dev->device.driver)
+ if (rte_dev_is_probed(&dev->device))
continue;
if (vdev_probe_all_drivers(dev)) {
@@ -493,9 +504,9 @@ vdev_probe(void)
return ret;
}
-static struct rte_device *
-vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
- const void *data)
+struct rte_device *
+rte_vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+ const void *data)
{
const struct rte_vdev_device *vstart;
struct rte_vdev_device *dev;
@@ -532,10 +543,11 @@ vdev_unplug(struct rte_device *dev)
static struct rte_bus rte_vdev_bus = {
.scan = vdev_scan,
.probe = vdev_probe,
- .find_device = vdev_find_device,
+ .find_device = rte_vdev_find_device,
.plug = vdev_plug,
.unplug = vdev_unplug,
.parse = vdev_parse,
+ .dev_iterate = rte_vdev_dev_iterate,
};
RTE_REGISTER_BUS(vdev, rte_vdev_bus);
diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c
new file mode 100644
index 00000000..6f74704d
--- /dev/null
+++ b/drivers/bus/vdev/vdev_params.c
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Gaëtan Rivet
+ */
+
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_kvargs.h>
+#include <rte_errno.h>
+
+#include "vdev_logs.h"
+#include "vdev_private.h"
+
+enum vdev_params {
+ RTE_VDEV_PARAM_NAME,
+ RTE_VDEV_PARAM_MAX,
+};
+
+static const char * const vdev_params_keys[] = {
+ [RTE_VDEV_PARAM_NAME] = "name",
+ [RTE_VDEV_PARAM_MAX] = NULL,
+};
+
+static int
+vdev_dev_match(const struct rte_device *dev,
+ const void *_kvlist)
+{
+ int ret;
+ const struct rte_kvargs *kvlist = _kvlist;
+ char *name;
+
+ /* cannot pass const dev->name to rte_kvargs_process() */
+ name = strdup(dev->name);
+ if (name == NULL)
+ return -1;
+ ret = rte_kvargs_process(kvlist,
+ vdev_params_keys[RTE_VDEV_PARAM_NAME],
+ rte_kvargs_strcmp, name);
+ free(name);
+ if (ret != 0)
+ return -1;
+
+ return 0;
+}
+
+void *
+rte_vdev_dev_iterate(const void *start,
+ const char *str,
+ const struct rte_dev_iterator *it __rte_unused)
+{
+ struct rte_kvargs *kvargs = NULL;
+ struct rte_device *dev;
+
+ if (str != NULL) {
+ kvargs = rte_kvargs_parse(str, vdev_params_keys);
+ if (kvargs == NULL) {
+ VDEV_LOG(ERR, "cannot parse argument list\n");
+ rte_errno = EINVAL;
+ return NULL;
+ }
+ }
+ dev = rte_vdev_find_device(start, vdev_dev_match, kvargs);
+ rte_kvargs_free(kvargs);
+ return dev;
+}
diff --git a/drivers/bus/vdev/vdev_private.h b/drivers/bus/vdev/vdev_private.h
new file mode 100644
index 00000000..ba6dc48f
--- /dev/null
+++ b/drivers/bus/vdev/vdev_private.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Gaëtan Rivet
+ */
+
+#ifndef _VDEV_PRIVATE_H_
+#define _VDEV_PRIVATE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rte_device *
+rte_vdev_find_device(const struct rte_device *start,
+ rte_dev_cmp_t cmp,
+ const void *data);
+
+void *
+rte_vdev_dev_iterate(const void *start,
+ const char *str,
+ const struct rte_dev_iterator *it);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VDEV_PRIVATE_H_ */