* [dpdk-dev] [PATCH v1 01/13] bus/pci: implement device iteration and comparison
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
@ 2018-08-30 13:41 ` Gaetan Rivet
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 02/13] bus/pci: add device matching field id Gaetan Rivet
` (13 subsequent siblings)
14 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:41 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/pci/Makefile | 3 +-
drivers/bus/pci/meson.build | 6 +++-
drivers/bus/pci/pci_common.c | 3 +-
drivers/bus/pci/pci_params.c | 53 ++++++++++++++++++++++++++++++++++++
drivers/bus/pci/private.h | 25 +++++++++++++++++
5 files changed, 86 insertions(+), 4 deletions(-)
create mode 100644 drivers/bus/pci/pci_params.c
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
index cf373068a..4de953f8f 100644
--- a/drivers/bus/pci/Makefile
+++ b/drivers/bus/pci/Makefile
@@ -26,10 +26,11 @@ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
CFLAGS += -DALLOW_EXPERIMENTAL_API
LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
-LDLIBS += -lrte_ethdev -lrte_pci
+LDLIBS += -lrte_ethdev -lrte_pci -lrte_kvargs
include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_params.c
SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common.c
SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common_uio.c
diff --git a/drivers/bus/pci/meson.build b/drivers/bus/pci/meson.build
index 72939e598..23d6a5fec 100644
--- a/drivers/bus/pci/meson.build
+++ b/drivers/bus/pci/meson.build
@@ -3,7 +3,9 @@
deps += ['pci']
install_headers('rte_bus_pci.h')
-sources = files('pci_common.c', 'pci_common_uio.c')
+sources = files('pci_common.c',
+ 'pci_common_uio.c',
+ 'pci_params.c')
if host_machine.system() == 'linux'
sources += files('linux/pci.c',
'linux/pci_uio.c',
@@ -17,3 +19,5 @@ endif
# memseg walk is not part of stable API yet
allow_experimental_apis = true
+
+deps += ['kvargs']
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 7736b3f9c..c7695d108 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -27,8 +27,6 @@
#include "private.h"
-extern struct rte_pci_bus rte_pci_bus;
-
#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
const char *rte_pci_get_sysfs_path(void)
@@ -435,6 +433,7 @@ struct rte_pci_bus rte_pci_bus = {
.unplug = pci_unplug,
.parse = pci_parse,
.get_iommu_class = rte_pci_get_iommu_class,
+ .dev_iterate = rte_pci_dev_iterate,
},
.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
new file mode 100644
index 000000000..0fde75803
--- /dev/null
+++ b/drivers/bus/pci/pci_params.c
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Gaëtan Rivet
+ */
+
+#include <rte_bus.h>
+#include <rte_dev.h>
+#include <rte_errno.h>
+#include <rte_kvargs.h>
+#include <rte_pci.h>
+
+#include "private.h"
+
+enum pci_params {
+ RTE_PCI_PARAMS_MAX,
+};
+
+static const char * const pci_params_keys[] = {
+ [RTE_PCI_PARAMS_MAX] = NULL,
+};
+
+static int
+pci_dev_match(const struct rte_device *dev,
+ const void *_kvlist)
+{
+ const struct rte_kvargs *kvlist = _kvlist;
+
+ (void) dev;
+ (void) kvlist;
+ return 0;
+}
+
+void *
+rte_pci_dev_iterate(const void *start,
+ const char *str,
+ const struct rte_dev_iterator *it __rte_unused)
+{
+ rte_bus_find_device_t find_device;
+ struct rte_kvargs *kvargs = NULL;
+ struct rte_device *dev;
+
+ if (str != NULL) {
+ kvargs = rte_kvargs_parse(str, pci_params_keys);
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "cannot parse argument list\n");
+ rte_errno = EINVAL;
+ return NULL;
+ }
+ }
+ find_device = rte_pci_bus.bus.find_device;
+ dev = find_device(start, pci_dev_match, kvargs);
+ rte_kvargs_free(kvargs);
+ return dev;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 8ddd03e16..0e689fa74 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -10,6 +10,8 @@
#include <rte_pci.h>
#include <rte_bus_pci.h>
+extern struct rte_pci_bus rte_pci_bus;
+
struct rte_pci_driver;
struct rte_pci_device;
@@ -166,4 +168,27 @@ rte_pci_match(const struct rte_pci_driver *pci_drv,
enum rte_iova_mode
rte_pci_get_iommu_class(void);
+/*
+ * Iterate over internal devices,
+ * matching any device against the provided
+ * string.
+ *
+ * @param start
+ * Iteration starting point.
+ *
+ * @param str
+ * Device string to match against.
+ *
+ * @param it
+ * (unused) iterator structure.
+ *
+ * @return
+ * A pointer to the next matching device if any.
+ * NULL otherwise.
+ */
+void *
+rte_pci_dev_iterate(const void *start,
+ const char *str,
+ const struct rte_dev_iterator *it);
+
#endif /* _PCI_PRIVATE_H_ */
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 02/13] bus/pci: add device matching field id
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 01/13] bus/pci: implement device iteration and comparison Gaetan Rivet
@ 2018-08-30 13:41 ` Gaetan Rivet
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 03/13] bus/vdev: implement device iteration Gaetan Rivet
` (12 subsequent siblings)
14 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:41 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The PCI bus can now parse a matching field "id" as follows:
"bus=pci,id=0000:00:00.0"
or
"bus=pci,id=00:00.0"
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/pci/pci_params.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
index 0fde75803..7630d4845 100644
--- a/drivers/bus/pci/pci_params.c
+++ b/drivers/bus/pci/pci_params.c
@@ -3,6 +3,7 @@
*/
#include <rte_bus.h>
+#include <rte_bus_pci.h>
#include <rte_dev.h>
#include <rte_errno.h>
#include <rte_kvargs.h>
@@ -11,21 +12,45 @@
#include "private.h"
enum pci_params {
+ RTE_PCI_PARAMS_ID,
RTE_PCI_PARAMS_MAX,
};
static const char * const pci_params_keys[] = {
+ [RTE_PCI_PARAMS_ID] = "id",
[RTE_PCI_PARAMS_MAX] = NULL,
};
+static int
+pci_addr_kv_cmp(const char *key __rte_unused,
+ const char *value,
+ void *_addr2)
+{
+ struct rte_pci_addr _addr1;
+ struct rte_pci_addr *addr1 = &_addr1;
+ struct rte_pci_addr *addr2 = _addr2;
+
+ if (rte_pci_addr_parse(value, addr1))
+ return -1;
+ return -abs(rte_pci_addr_cmp(addr1, addr2));
+}
+
static int
pci_dev_match(const struct rte_device *dev,
const void *_kvlist)
{
const struct rte_kvargs *kvlist = _kvlist;
+ const struct rte_pci_device *pdev;
- (void) dev;
- (void) kvlist;
+ if (kvlist == NULL)
+ /* Empty string matches everything. */
+ return 0;
+ pdev = RTE_DEV_TO_PCI_CONST(dev);
+ /* if any field does not match. */
+ if (rte_kvargs_process(kvlist, "id",
+ &pci_addr_kv_cmp,
+ (void *)(intptr_t)&pdev->addr))
+ return 1;
return 0;
}
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 03/13] bus/vdev: implement device iteration
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 01/13] bus/pci: implement device iteration and comparison Gaetan Rivet
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 02/13] bus/pci: add device matching field id Gaetan Rivet
@ 2018-08-30 13:41 ` Gaetan Rivet
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 04/13] bus/vdev: add device matching field driver Gaetan Rivet
` (11 subsequent siblings)
14 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:41 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/vdev/Makefile | 3 +-
drivers/bus/vdev/meson.build | 5 +++-
drivers/bus/vdev/vdev.c | 10 ++++---
drivers/bus/vdev/vdev_params.c | 51 +++++++++++++++++++++++++++++++++
drivers/bus/vdev/vdev_private.h | 26 +++++++++++++++++
5 files changed, 89 insertions(+), 6 deletions(-)
create mode 100644 drivers/bus/vdev/vdev_params.c
create mode 100644 drivers/bus/vdev/vdev_private.h
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
index bd0bb8955..1f9cd7ebe 100644
--- a/drivers/bus/vdev/Makefile
+++ b/drivers/bus/vdev/Makefile
@@ -19,8 +19,9 @@ EXPORT_MAP := rte_bus_vdev_version.map
LIBABIVER := 1
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 2ee648b49..12605e5c7 100644
--- a/drivers/bus/vdev/meson.build
+++ b/drivers/bus/vdev/meson.build
@@ -1,7 +1,10 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-sources = files('vdev.c')
+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 6139dd551..e8518833d 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"
@@ -493,9 +494,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 +533,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 000000000..842a4684e
--- /dev/null
+++ b/drivers/bus/vdev/vdev_params.c
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Gaëtan Rivet
+ */
+
+#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_PARAMS_MAX,
+};
+
+static const char * const vdev_params_keys[] = {
+ [RTE_VDEV_PARAMS_MAX] = NULL,
+};
+
+static int
+vdev_dev_match(const struct rte_device *dev,
+ const void *_kvlist)
+{
+ const struct rte_kvargs *kvlist = _kvlist;
+
+ (void) kvlist;
+ (void) dev;
+ 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 000000000..ba6dc48ff
--- /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_ */
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 04/13] bus/vdev: add device matching field driver
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (2 preceding siblings ...)
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 03/13] bus/vdev: implement device iteration Gaetan Rivet
@ 2018-08-30 13:41 ` Gaetan Rivet
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 05/13] ethdev: add private generic device iterator Gaetan Rivet
` (10 subsequent siblings)
14 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:41 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The vdev bus parses a field "driver", matching
a vdev driver name with one passed as follows:
"bus=vdev,driver=xxxx"
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/vdev/vdev_params.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c
index 842a4684e..2f55f451f 100644
--- a/drivers/bus/vdev/vdev_params.c
+++ b/drivers/bus/vdev/vdev_params.c
@@ -4,6 +4,7 @@
#include <rte_dev.h>
#include <rte_bus.h>
+#include <rte_bus_vdev.h>
#include <rte_kvargs.h>
#include <rte_errno.h>
@@ -11,10 +12,12 @@
#include "vdev_private.h"
enum vdev_params {
+ RTE_VDEV_PARAMS_DRIVER,
RTE_VDEV_PARAMS_MAX,
};
static const char * const vdev_params_keys[] = {
+ [RTE_VDEV_PARAMS_DRIVER] = "driver",
[RTE_VDEV_PARAMS_MAX] = NULL,
};
@@ -23,9 +26,17 @@ vdev_dev_match(const struct rte_device *dev,
const void *_kvlist)
{
const struct rte_kvargs *kvlist = _kvlist;
+ const struct rte_vdev_device *vdev;
- (void) kvlist;
- (void) dev;
+ if (kvlist == NULL)
+ /* Empty string matches everything. */
+ return 0;
+ vdev = RTE_DEV_TO_VDEV_CONST(dev);
+ /* if any field does not match. */
+ if (rte_kvargs_process(kvlist, "driver",
+ rte_kvargs_strcmp,
+ (void *)(intptr_t)vdev->device.driver->name))
+ return -1;
return 0;
}
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 05/13] ethdev: add private generic device iterator
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (3 preceding siblings ...)
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 04/13] bus/vdev: add device matching field driver Gaetan Rivet
@ 2018-08-30 13:41 ` Gaetan Rivet
2018-08-31 10:09 ` Andrew Rybchenko
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 06/13] ethdev: register ether layer as a class Gaetan Rivet
` (9 subsequent siblings)
14 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:41 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
This iterator can be customized with a comparison function that will
trigger a stopping condition.
It can be leveraged to write several different iterators that have
similar but non-identical purposes.
It is private to librte_ethdev.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_ethdev/Makefile | 1 +
lib/librte_ethdev/eth_private.c | 31 +++++++++++++++++++++++++++++++
lib/librte_ethdev/eth_private.h | 26 ++++++++++++++++++++++++++
lib/librte_ethdev/meson.build | 3 ++-
4 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_ethdev/eth_private.c
create mode 100644 lib/librte_ethdev/eth_private.h
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 0935a275e..3c1c92cb9 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -18,6 +18,7 @@ EXPORT_MAP := rte_ethdev_version.map
LIBABIVER := 10
+SRCS-y += eth_private.c
SRCS-y += rte_ethdev.c
SRCS-y += rte_flow.c
SRCS-y += rte_tm.c
diff --git a/lib/librte_ethdev/eth_private.c b/lib/librte_ethdev/eth_private.c
new file mode 100644
index 000000000..d565568a0
--- /dev/null
+++ b/lib/librte_ethdev/eth_private.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Gaëtan Rivet
+ */
+
+#include "rte_ethdev.h"
+#include "eth_private.h"
+
+struct rte_eth_dev *
+eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp,
+ const void *data)
+{
+ struct rte_eth_dev *edev;
+ ptrdiff_t idx;
+
+ /* Avoid Undefined Behaviour */
+ if (start != NULL &&
+ (start < &rte_eth_devices[0] ||
+ start > &rte_eth_devices[RTE_MAX_ETHPORTS]))
+ return NULL;
+ if (start != NULL)
+ idx = start - &rte_eth_devices[0] + 1;
+ else
+ idx = 0;
+ for (; idx < RTE_MAX_ETHPORTS; idx++) {
+ edev = &rte_eth_devices[idx];
+ if (cmp(edev, data) == 0)
+ return edev;
+ }
+ return NULL;
+}
+
diff --git a/lib/librte_ethdev/eth_private.h b/lib/librte_ethdev/eth_private.h
new file mode 100644
index 000000000..0f5c6d5c4
--- /dev/null
+++ b/lib/librte_ethdev/eth_private.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Gaëtan Rivet
+ */
+
+#ifndef _RTE_ETH_PRIVATE_H_
+#define _RTE_ETH_PRIVATE_H_
+
+#include "rte_ethdev.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Generic rte_eth_dev comparison function. */
+typedef int (*rte_eth_cmp_t)(const struct rte_eth_dev *, const void *);
+
+/* Generic rte_eth_dev iterator. */
+struct rte_eth_dev *
+eth_find_device(const struct rte_eth_dev *_start, rte_eth_cmp_t cmp,
+ const void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ETH_PRIVATE_H_ */
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 596cd0f39..372d3ca06 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -4,7 +4,8 @@
name = 'ethdev'
version = 10
allow_experimental_apis = true
-sources = files('ethdev_profile.c',
+sources = files('eth_private.c',
+ 'ethdev_profile.c',
'rte_ethdev.c',
'rte_flow.c',
'rte_mtr.c',
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v1 05/13] ethdev: add private generic device iterator
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 05/13] ethdev: add private generic device iterator Gaetan Rivet
@ 2018-08-31 10:09 ` Andrew Rybchenko
2018-08-31 10:22 ` Gaëtan Rivet
0 siblings, 1 reply; 47+ messages in thread
From: Andrew Rybchenko @ 2018-08-31 10:09 UTC (permalink / raw)
To: Gaetan Rivet, dev
On 08/30/2018 04:41 PM, Gaetan Rivet wrote:
> This iterator can be customized with a comparison function that will
> trigger a stopping condition.
>
> It can be leveraged to write several different iterators that have
> similar but non-identical purposes.
>
> It is private to librte_ethdev.
>
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---
> lib/librte_ethdev/Makefile | 1 +
> lib/librte_ethdev/eth_private.c | 31 +++++++++++++++++++++++++++++++
> lib/librte_ethdev/eth_private.h | 26 ++++++++++++++++++++++++++
> lib/librte_ethdev/meson.build | 3 ++-
> 4 files changed, 60 insertions(+), 1 deletion(-)
> create mode 100644 lib/librte_ethdev/eth_private.c
> create mode 100644 lib/librte_ethdev/eth_private.h
>
> diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
> index 0935a275e..3c1c92cb9 100644
> --- a/lib/librte_ethdev/Makefile
> +++ b/lib/librte_ethdev/Makefile
> @@ -18,6 +18,7 @@ EXPORT_MAP := rte_ethdev_version.map
>
> LIBABIVER := 10
>
> +SRCS-y += eth_private.c
> SRCS-y += rte_ethdev.c
> SRCS-y += rte_flow.c
> SRCS-y += rte_tm.c
> diff --git a/lib/librte_ethdev/eth_private.c b/lib/librte_ethdev/eth_private.c
> new file mode 100644
> index 000000000..d565568a0
> --- /dev/null
> +++ b/lib/librte_ethdev/eth_private.c
Just a nit
I think it is better to name it ethdev_private.c since we already
have ethdev_profile.[ch] and it is about ethdev, not Ethernet.
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2018 Gaëtan Rivet
> + */
> +
> +#include "rte_ethdev.h"
> +#include "eth_private.h"
> +
> +struct rte_eth_dev *
> +eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp,
> + const void *data)
> +{
> + struct rte_eth_dev *edev;
> + ptrdiff_t idx;
> +
> + /* Avoid Undefined Behaviour */
> + if (start != NULL &&
> + (start < &rte_eth_devices[0] ||
> + start > &rte_eth_devices[RTE_MAX_ETHPORTS]))
> + return NULL;
> + if (start != NULL)
> + idx = start - &rte_eth_devices[0] + 1;
> + else
> + idx = 0;
> + for (; idx < RTE_MAX_ETHPORTS; idx++) {
> + edev = &rte_eth_devices[idx];
Shouldn't we limit it to valid ports only?
If no, I think it would be useful to highlight it in the function
description that it iterates over all devices including unused.
> + if (cmp(edev, data) == 0)
> + return edev;
> + }
> + return NULL;
> +}
> +
> diff --git a/lib/librte_ethdev/eth_private.h b/lib/librte_ethdev/eth_private.h
> new file mode 100644
> index 000000000..0f5c6d5c4
> --- /dev/null
> +++ b/lib/librte_ethdev/eth_private.h
ethdev_private.h
<...>
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v1 05/13] ethdev: add private generic device iterator
2018-08-31 10:09 ` Andrew Rybchenko
@ 2018-08-31 10:22 ` Gaëtan Rivet
0 siblings, 0 replies; 47+ messages in thread
From: Gaëtan Rivet @ 2018-08-31 10:22 UTC (permalink / raw)
To: Andrew Rybchenko; +Cc: dev
On Fri, Aug 31, 2018 at 01:09:34PM +0300, Andrew Rybchenko wrote:
> On 08/30/2018 04:41 PM, Gaetan Rivet wrote:
> > This iterator can be customized with a comparison function that will
> > trigger a stopping condition.
> >
> > It can be leveraged to write several different iterators that have
> > similar but non-identical purposes.
> >
> > It is private to librte_ethdev.
> >
> > Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> > ---
> > lib/librte_ethdev/Makefile | 1 +
> > lib/librte_ethdev/eth_private.c | 31 +++++++++++++++++++++++++++++++
> > lib/librte_ethdev/eth_private.h | 26 ++++++++++++++++++++++++++
> > lib/librte_ethdev/meson.build | 3 ++-
> > 4 files changed, 60 insertions(+), 1 deletion(-)
> > create mode 100644 lib/librte_ethdev/eth_private.c
> > create mode 100644 lib/librte_ethdev/eth_private.h
> >
> > diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
> > index 0935a275e..3c1c92cb9 100644
> > --- a/lib/librte_ethdev/Makefile
> > +++ b/lib/librte_ethdev/Makefile
> > @@ -18,6 +18,7 @@ EXPORT_MAP := rte_ethdev_version.map
> > LIBABIVER := 10
> > +SRCS-y += eth_private.c
> > SRCS-y += rte_ethdev.c
> > SRCS-y += rte_flow.c
> > SRCS-y += rte_tm.c
> > diff --git a/lib/librte_ethdev/eth_private.c b/lib/librte_ethdev/eth_private.c
> > new file mode 100644
> > index 000000000..d565568a0
> > --- /dev/null
> > +++ b/lib/librte_ethdev/eth_private.c
>
> Just a nit
> I think it is better to name it ethdev_private.c since we already
> have ethdev_profile.[ch] and it is about ethdev, not Ethernet.
>
Agreed.
> > @@ -0,0 +1,31 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(c) 2018 Gaëtan Rivet
> > + */
> > +
> > +#include "rte_ethdev.h"
> > +#include "eth_private.h"
> > +
> > +struct rte_eth_dev *
> > +eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp,
> > + const void *data)
> > +{
> > + struct rte_eth_dev *edev;
> > + ptrdiff_t idx;
> > +
> > + /* Avoid Undefined Behaviour */
> > + if (start != NULL &&
> > + (start < &rte_eth_devices[0] ||
> > + start > &rte_eth_devices[RTE_MAX_ETHPORTS]))
> > + return NULL;
> > + if (start != NULL)
> > + idx = start - &rte_eth_devices[0] + 1;
> > + else
> > + idx = 0;
> > + for (; idx < RTE_MAX_ETHPORTS; idx++) {
> > + edev = &rte_eth_devices[idx];
>
> Shouldn't we limit it to valid ports only?
> If no, I think it would be useful to highlight it in the function
> description that it iterates over all devices including unused.
>
I'm undecided about it, I wanted eth_find_device to be and internal
operator in the most generic way, allowing ethdev layer to move from
manually iterating to using this, to introduce the probable future
evolution of not using an array of rte_eth_devices.
So I thought of this operator as something stateless, only looking at
currently available memory and letting the comparison select what is
useful. Maybe for example this operator would be used to find the next
unused device, etc.
My doubts is that this is kind of future-proofing the design, something
that I don't think is good practice.
So, if you prefer something that takes care of state, as far as devargs
parsing is concerned, I'm ok with that. Otherwise it can stay that way,
UNUSED devices are taken care of afterward.
> > + if (cmp(edev, data) == 0)
> > + return edev;
> > + }
> > + return NULL;
> > +}
> > +
> > diff --git a/lib/librte_ethdev/eth_private.h b/lib/librte_ethdev/eth_private.h
> > new file mode 100644
> > index 000000000..0f5c6d5c4
> > --- /dev/null
> > +++ b/lib/librte_ethdev/eth_private.h
>
> ethdev_private.h
sure.
>
> <...>
--
Gaëtan Rivet
6WIND
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 06/13] ethdev: register ether layer as a class
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (4 preceding siblings ...)
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 05/13] ethdev: add private generic device iterator Gaetan Rivet
@ 2018-08-30 13:41 ` Gaetan Rivet
2018-08-31 10:09 ` Andrew Rybchenko
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 07/13] ethdev: add device matching field name Gaetan Rivet
` (8 subsequent siblings)
14 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:41 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_ethdev/Makefile | 3 +-
lib/librte_ethdev/meson.build | 1 +
lib/librte_ethdev/rte_class_eth.c | 79 +++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_ethdev/rte_class_eth.c
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 3c1c92cb9..91899b083 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf
+LDLIBS += -lrte_mbuf -lrte_kvargs
EXPORT_MAP := rte_ethdev_version.map
@@ -20,6 +20,7 @@ LIBABIVER := 10
SRCS-y += eth_private.c
SRCS-y += rte_ethdev.c
+SRCS-y += rte_class_eth.c
SRCS-y += rte_flow.c
SRCS-y += rte_tm.c
SRCS-y += rte_mtr.c
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 372d3ca06..8d2e2bf4e 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -6,6 +6,7 @@ version = 10
allow_experimental_apis = true
sources = files('eth_private.c',
'ethdev_profile.c',
+ 'rte_class_eth.c',
'rte_ethdev.c',
'rte_flow.c',
'rte_mtr.c',
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
new file mode 100644
index 000000000..32c736d32
--- /dev/null
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Gaëtan Rivet
+ */
+
+#include <string.h>
+
+#include <rte_class.h>
+#include <rte_compat.h>
+#include <rte_errno.h>
+#include <rte_kvargs.h>
+#include <rte_log.h>
+
+#include "rte_ethdev.h"
+#include "rte_ethdev_core.h"
+#include "eth_private.h"
+
+enum eth_params {
+ RTE_ETH_PARAMS_MAX,
+};
+
+static const char * const eth_params_keys[] = {
+ [RTE_ETH_PARAMS_MAX] = NULL,
+};
+
+struct eth_dev_match_arg {
+ struct rte_device *device;
+ struct rte_kvargs *kvlist;
+};
+
+#define eth_dev_match_arg(d, k) \
+ (&(const struct eth_dev_match_arg) { \
+ .device = (d), \
+ .kvlist = (k), \
+ })
+
+static int
+eth_dev_match(const struct rte_eth_dev *edev,
+ const void *_arg)
+{
+ const struct eth_dev_match_arg *arg = _arg;
+ const struct rte_kvargs *kvlist = arg->kvlist;
+
+ if (edev->state == RTE_ETH_DEV_UNUSED)
+ return -1;
+ if (edev->device != arg->device)
+ return -1;
+ if (kvlist == NULL)
+ /* Empty string matches everything. */
+ return 0;
+ return 0;
+}
+
+static void *
+eth_dev_iterate(const void *start,
+ const char *str,
+ const struct rte_dev_iterator *it)
+{
+ struct rte_kvargs *kvargs = NULL;
+ struct rte_eth_dev *edev = NULL;
+
+ if (str != NULL) {
+ kvargs = rte_kvargs_parse(str, eth_params_keys);
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "cannot parse argument list\n");
+ rte_errno = EINVAL;
+ return NULL;
+ }
+ }
+ edev = eth_find_device(start, eth_dev_match,
+ eth_dev_match_arg(it->device, kvargs));
+ rte_kvargs_free(kvargs);
+ return edev;
+}
+
+struct rte_class rte_class_eth = {
+ .dev_iterate = eth_dev_iterate,
+};
+
+RTE_REGISTER_CLASS(eth, rte_class_eth);
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 07/13] ethdev: add device matching field name
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (5 preceding siblings ...)
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 06/13] ethdev: register ether layer as a class Gaetan Rivet
@ 2018-08-30 13:41 ` Gaetan Rivet
2018-08-31 10:10 ` Andrew Rybchenko
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 08/13] app/testpmd: add show device command Gaetan Rivet
` (7 subsequent siblings)
14 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:41 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The eth device class can now parse a field name,
matching the eth_dev name with one passed as
"class=eth,name=xxxxxx"
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_ethdev/rte_class_eth.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 32c736d32..d8d8e8845 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -15,10 +15,12 @@
#include "eth_private.h"
enum eth_params {
+ RTE_ETH_PARAMS_NAME,
RTE_ETH_PARAMS_MAX,
};
static const char * const eth_params_keys[] = {
+ [RTE_ETH_PARAMS_NAME] = "name",
[RTE_ETH_PARAMS_MAX] = NULL,
};
@@ -39,6 +41,7 @@ eth_dev_match(const struct rte_eth_dev *edev,
{
const struct eth_dev_match_arg *arg = _arg;
const struct rte_kvargs *kvlist = arg->kvlist;
+ struct rte_eth_dev_data *data;
if (edev->state == RTE_ETH_DEV_UNUSED)
return -1;
@@ -47,6 +50,10 @@ eth_dev_match(const struct rte_eth_dev *edev,
if (kvlist == NULL)
/* Empty string matches everything. */
return 0;
+ data = edev->data;
+ if (rte_kvargs_process(kvlist, "name",
+ rte_kvargs_strcmp, data->name))
+ return -1;
return 0;
}
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 08/13] app/testpmd: add show device command
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (6 preceding siblings ...)
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 07/13] ethdev: add device matching field name Gaetan Rivet
@ 2018-08-30 13:41 ` Gaetan Rivet
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 09/13] bus/pci: pre-process declarative PCI devargs Gaetan Rivet
` (6 subsequent siblings)
14 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:41 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
A new interactive command is offered:
show device <device description>
This commands lists all rte_device element matching the device
description. e.g.:
show device bus=pci
show device bus=vdev
show device bus=vdev/class=eth
show device bus=vdev,driver=net_ring/class=eth
show device bus=vdev/class=eth,name=net_ring0
These devices may not be otherwise useful, some buses will spawn devices
to keep track of their assets without having a driver to use them.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
app/test-pmd/cmdline.c | 54 +++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 24 +++++++++
2 files changed, 78 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 589121d69..a7c0e622a 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -228,6 +228,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"show port tm node stats (port_id) (node_id) (clear)\n"
" Display the port TM node stats.\n\n"
+ "show device (device_string)\n"
+ " Display devices matching the device string.\n\n"
+
);
}
@@ -7117,6 +7120,56 @@ cmdline_parse_inst_t cmd_showportall = {
},
};
+/* *** SHOW DEVICE INFO *** */
+struct cmd_showdevice_result {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t device;
+ cmdline_fixed_string_t filter;
+};
+
+static void
+cmd_showdevice_dump_device(const struct rte_device *dev)
+{
+ const struct rte_driver *drv = dev->driver;
+
+ printf("0x%p: %s:%s\n", (const void *)dev, dev->name,
+ drv ? drv->name : "<nil>");
+}
+
+static void cmd_showdevice_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_showdevice_result *res = parsed_result;
+ struct rte_dev_iterator it;
+ const struct rte_device *dev;
+
+ RTE_DEV_FOREACH(dev, res->filter, &it)
+ cmd_showdevice_dump_device(dev);
+}
+
+cmdline_parse_token_string_t cmd_showdevice_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result,
+ show, "show");
+cmdline_parse_token_string_t cmd_showdevice_device =
+ TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result,
+ device, "device");
+cmdline_parse_token_string_t cmd_showdevice_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result,
+ filter, NULL);
+
+cmdline_parse_inst_t cmd_showdevice = {
+ .f = cmd_showdevice_parsed,
+ .data = NULL,
+ .help_str = "show device <device string>",
+ .tokens = {
+ (void *)&cmd_showdevice_show,
+ (void *)&cmd_showdevice_device,
+ (void *)&cmd_showdevice_filter,
+ NULL,
+ },
+};
+
/* *** SHOW PORT INFO *** */
struct cmd_showport_result {
cmdline_fixed_string_t show;
@@ -17610,6 +17663,7 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_help_long,
(cmdline_parse_inst_t *)&cmd_quit,
(cmdline_parse_inst_t *)&cmd_load_from_file,
+ (cmdline_parse_inst_t *)&cmd_showdevice,
(cmdline_parse_inst_t *)&cmd_showport,
(cmdline_parse_inst_t *)&cmd_showqueue,
(cmdline_parse_inst_t *)&cmd_showportall,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index dde205a2b..417072cce 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2663,6 +2663,30 @@ set the traffic management default hierarchy on the port::
testpmd> set port tm hierarchy default (port_id)
+Device functions
+----------------
+
+Show devices
+~~~~~~~~~~~~
+
+Display any registered devices::
+
+ testpmd> show device <device_string>
+
+where:
+
+* ``device_string``: Device description string, of the format
+
+ layer[/layer[/layer]]
+
+ where one layer is in the form
+
+ layer_key=layer_name[,key1=value1[,...]]
+
+ Valid layer keys are ``bus`` and ``class``.
+ Their respective values is defined by registered ``bus`` and ``class``
+ drivers.
+
Filter Functions
----------------
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 09/13] bus/pci: pre-process declarative PCI devargs
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (7 preceding siblings ...)
2018-08-30 13:41 ` [dpdk-dev] [PATCH v1 08/13] app/testpmd: add show device command Gaetan Rivet
@ 2018-08-30 13:42 ` Gaetan Rivet
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 10/13] bus/vdev: pre-process declarative vdev devargs Gaetan Rivet
` (5 subsequent siblings)
14 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:42 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The new devargs format does not recognize a particular device name.
Each bus uses its specific format.
Instead of introducing a new bus API, process those devargs privately
for the moment. Prepare them for matching during scan against the
bus devices.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/pci/bsd/pci.c | 5 ++++
drivers/bus/pci/linux/pci.c | 5 ++++
drivers/bus/pci/pci_params.c | 51 ++++++++++++++++++++++++++++++++++++
drivers/bus/pci/private.h | 16 +++++++++++
4 files changed, 77 insertions(+)
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
index 655b34b7e..046cd11d5 100644
--- a/drivers/bus/pci/bsd/pci.c
+++ b/drivers/bus/pci/bsd/pci.c
@@ -327,6 +327,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
int
rte_pci_scan(void)
{
+ struct rte_devargs *devargs;
int fd;
unsigned dev_count = 0;
struct pci_conf matches[16];
@@ -342,6 +343,10 @@ rte_pci_scan(void)
if (!rte_eal_has_pci())
return 0;
+ RTE_EAL_DEVARGS_FOREACH("pci", devargs)
+ if (rte_pci_devargs_prepare(devargs))
+ continue;
+
fd = open("/dev/pci", O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
index 04648ac93..12f246089 100644
--- a/drivers/bus/pci/linux/pci.c
+++ b/drivers/bus/pci/linux/pci.c
@@ -429,6 +429,7 @@ parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
int
rte_pci_scan(void)
{
+ struct rte_devargs *devargs;
struct dirent *e;
DIR *dir;
char dirname[PATH_MAX];
@@ -438,6 +439,10 @@ rte_pci_scan(void)
if (!rte_eal_has_pci())
return 0;
+ RTE_EAL_DEVARGS_FOREACH("pci", devargs)
+ if (rte_pci_devargs_prepare(devargs))
+ continue;
+
#ifdef VFIO_PRESENT
if (!pci_vfio_is_enabled())
RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
index 7630d4845..a09af3b1c 100644
--- a/drivers/bus/pci/pci_params.c
+++ b/drivers/bus/pci/pci_params.c
@@ -2,9 +2,12 @@
* Copyright 2018 Gaëtan Rivet
*/
+#include <string.h>
+
#include <rte_bus.h>
#include <rte_bus_pci.h>
#include <rte_dev.h>
+#include <rte_devargs.h>
#include <rte_errno.h>
#include <rte_kvargs.h>
#include <rte_pci.h>
@@ -76,3 +79,51 @@ rte_pci_dev_iterate(const void *start,
rte_kvargs_free(kvargs);
return dev;
}
+
+static int
+pci_addr_kv_parse(const char *key __rte_unused,
+ const char *value,
+ void *_devargs)
+{
+ struct rte_devargs *devargs = _devargs;
+ struct rte_pci_addr addr;
+
+ /* Verify address is valid. */
+ if (rte_pci_addr_parse(value, &addr)) {
+ rte_errno = ENODEV;
+ return -1;
+ }
+ /* Write down the address as the devargs name. */
+ rte_pci_device_name(&addr, devargs->name, sizeof(devargs->name));
+ return 0;
+}
+
+int
+rte_pci_devargs_prepare(struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvargs = NULL;
+ char *args;
+ int ret;
+
+ if (devargs->bus_str == NULL)
+ return 0;
+
+ args = strchr(devargs->bus_str, ',');
+ if (args == NULL)
+ return 0;
+ args++;
+
+ kvargs = rte_kvargs_parse(args, pci_params_keys);
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "unable to parse parameter list: %s\n",
+ devargs->bus_str);
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ ret = rte_kvargs_process(kvargs, "id",
+ &pci_addr_kv_parse, devargs);
+
+ rte_kvargs_free(kvargs);
+ return ret;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 0e689fa74..9beb24c6a 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -191,4 +191,20 @@ rte_pci_dev_iterate(const void *start,
const char *str,
const struct rte_dev_iterator *it);
+/*
+ * Prepare a devargs meant for this bus.
+ * This function is only used for a transitory period,
+ * to translate the new devargs format in one
+ * compatible with the old form.
+ *
+ * @param da
+ * Devargs to process.
+ *
+ * @return
+ * 0 on success.
+ * <0 on error.
+ */
+int
+rte_pci_devargs_prepare(struct rte_devargs *da);
+
#endif /* _PCI_PRIVATE_H_ */
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 10/13] bus/vdev: pre-process declarative vdev devargs
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (8 preceding siblings ...)
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 09/13] bus/pci: pre-process declarative PCI devargs Gaetan Rivet
@ 2018-08-30 13:42 ` Gaetan Rivet
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 11/13] bus/pci: process declarative PCI devargs Gaetan Rivet
` (4 subsequent siblings)
14 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:42 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The new devargs format does not recognize a particular device name.
Each bus uses its specific format.
Process each devargs privately prior to attempting a bus scan.
Prepare them if they are using the new devargs format.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/vdev/vdev.c | 10 ++++---
drivers/bus/vdev/vdev_params.c | 50 +++++++++++++++++++++++++++++++++
drivers/bus/vdev/vdev_private.h | 6 ++++
3 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index e8518833d..f2dace245 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -115,8 +115,8 @@ rte_vdev_remove_custom_scan(rte_vdev_scan_callback callback, void *user_arg)
return 0;
}
-static int
-vdev_parse(const char *name, void *addr)
+int
+rte_vdev_parse(const char *name, void *addr)
{
struct rte_vdev_driver **out = addr;
struct rte_vdev_driver *driver = NULL;
@@ -148,7 +148,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
VDEV_LOG(DEBUG, "Search driver %s to probe device %s", name,
rte_vdev_device_name(dev));
- if (vdev_parse(name, &driver))
+ if (rte_vdev_parse(name, &driver))
return -1;
dev->device.driver = &driver->driver;
ret = driver->probe(dev);
@@ -443,6 +443,8 @@ vdev_scan(void)
/* for virtual devices we scan the devargs_list populated via cmdline */
RTE_EAL_DEVARGS_FOREACH("vdev", devargs) {
+ if (rte_vdev_devargs_prepare(devargs))
+ continue;
dev = calloc(1, sizeof(*dev));
if (!dev)
@@ -536,7 +538,7 @@ static struct rte_bus rte_vdev_bus = {
.find_device = rte_vdev_find_device,
.plug = vdev_plug,
.unplug = vdev_unplug,
- .parse = vdev_parse,
+ .parse = rte_vdev_parse,
.dev_iterate = rte_vdev_dev_iterate,
};
diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c
index 2f55f451f..aafaf3330 100644
--- a/drivers/bus/vdev/vdev_params.c
+++ b/drivers/bus/vdev/vdev_params.c
@@ -2,11 +2,14 @@
* Copyright 2018 Gaëtan Rivet
*/
+#include <string.h>
+
#include <rte_dev.h>
#include <rte_bus.h>
#include <rte_bus_vdev.h>
#include <rte_kvargs.h>
#include <rte_errno.h>
+#include <rte_devargs.h>
#include "vdev_logs.h"
#include "vdev_private.h"
@@ -60,3 +63,50 @@ rte_vdev_dev_iterate(const void *start,
rte_kvargs_free(kvargs);
return dev;
}
+
+static int
+vdev_driver_kv_parse(const char *key __rte_unused,
+ const char *value,
+ void *_devargs)
+{
+ struct rte_devargs *devargs = _devargs;
+ struct rte_vdev_driver *driver;
+
+ /* Verify that the driver matches. */
+ if (rte_vdev_parse(value, &driver))
+ return -1;
+
+ /* Copy the driver name as-is. */
+ snprintf(devargs->name, sizeof(devargs->name), "%s", value);
+ return 0;
+}
+
+int
+rte_vdev_devargs_prepare(struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvargs = NULL;
+ char *args;
+ int ret;
+
+ if (devargs->bus_str == NULL)
+ return 0;
+
+ args = strchr(devargs->bus_str, ',');
+ if (args == NULL)
+ return 0;
+ args++;
+
+ kvargs = rte_kvargs_parse(args, vdev_params_keys);
+ if (kvargs == NULL) {
+ VDEV_LOG(ERR, "unable to parse parameter list: %s\n",
+ devargs->bus_str);
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ ret = rte_kvargs_process(kvargs, "driver",
+ vdev_driver_kv_parse, devargs);
+
+ rte_kvargs_free(kvargs);
+ return ret;
+}
diff --git a/drivers/bus/vdev/vdev_private.h b/drivers/bus/vdev/vdev_private.h
index ba6dc48ff..da57b84dd 100644
--- a/drivers/bus/vdev/vdev_private.h
+++ b/drivers/bus/vdev/vdev_private.h
@@ -19,6 +19,12 @@ rte_vdev_dev_iterate(const void *start,
const char *str,
const struct rte_dev_iterator *it);
+int
+rte_vdev_parse(const char *name, void *addr);
+
+int
+rte_vdev_devargs_prepare(struct rte_devargs *da);
+
#ifdef __cplusplus
}
#endif
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 11/13] bus/pci: process declarative PCI devargs
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (9 preceding siblings ...)
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 10/13] bus/vdev: pre-process declarative vdev devargs Gaetan Rivet
@ 2018-08-30 13:42 ` Gaetan Rivet
2018-08-30 16:15 ` Stephen Hemminger
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 12/13] ethdev: process declarative eth devargs Gaetan Rivet
` (3 subsequent siblings)
14 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:42 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Introduce the facility to process future PCI parameters.
Once the matching between PCI devices and devargs has been done, it is
possible to process each devargs. New parameters would have the PCI
device handle to work with when parsing the device (bus specific)
parameters.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/pci/pci_common.c | 3 +++
drivers/bus/pci/pci_params.c | 10 ++++++++++
drivers/bus/pci/private.h | 13 +++++++++++++
3 files changed, 26 insertions(+)
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index c7695d108..900cd9090 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -247,6 +247,9 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
if (dev->driver != NULL)
return 0;
+ if (rte_pci_devargs_process(dev) < 0)
+ return -1;
+
FOREACH_DRIVER_ON_PCIBUS(dr) {
rc = rte_pci_probe_one_driver(dr, dev);
if (rc < 0)
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
index a09af3b1c..f34bf3da9 100644
--- a/drivers/bus/pci/pci_params.c
+++ b/drivers/bus/pci/pci_params.c
@@ -127,3 +127,13 @@ rte_pci_devargs_prepare(struct rte_devargs *devargs)
rte_kvargs_free(kvargs);
return ret;
}
+
+int
+rte_pci_devargs_process(struct rte_pci_device *pdev)
+{
+ /* For the moment, no PCI param
+ * needs to be processed.
+ */
+ (void) pdev;
+ return 0;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 9beb24c6a..06dc85e85 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -207,4 +207,17 @@ rte_pci_dev_iterate(const void *start,
int
rte_pci_devargs_prepare(struct rte_devargs *da);
+/*
+ * Process the device devargs, if any.
+ *
+ * @param pdev
+ * PCI device
+ *
+ * @return
+ * 0 on success.
+ * <0 on error.
+ */
+int
+rte_pci_devargs_process(struct rte_pci_device *pdev);
+
#endif /* _PCI_PRIVATE_H_ */
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v1 11/13] bus/pci: process declarative PCI devargs
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 11/13] bus/pci: process declarative PCI devargs Gaetan Rivet
@ 2018-08-30 16:15 ` Stephen Hemminger
2018-08-30 16:37 ` Gaëtan Rivet
0 siblings, 1 reply; 47+ messages in thread
From: Stephen Hemminger @ 2018-08-30 16:15 UTC (permalink / raw)
To: Gaetan Rivet; +Cc: dev
On Thu, 30 Aug 2018 15:42:02 +0200
Gaetan Rivet <gaetan.rivet@6wind.com> wrote:
> +int
> +rte_pci_devargs_process(struct rte_pci_device *pdev)
> +{
> + /* For the moment, no PCI param
> + * needs to be processed.
> + */
> + (void) pdev;
> + return 0;
> +}
Use __rte_unused rather than the (void) cast?
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v1 11/13] bus/pci: process declarative PCI devargs
2018-08-30 16:15 ` Stephen Hemminger
@ 2018-08-30 16:37 ` Gaëtan Rivet
0 siblings, 0 replies; 47+ messages in thread
From: Gaëtan Rivet @ 2018-08-30 16:37 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On Thu, Aug 30, 2018 at 09:15:18AM -0700, Stephen Hemminger wrote:
> On Thu, 30 Aug 2018 15:42:02 +0200
> Gaetan Rivet <gaetan.rivet@6wind.com> wrote:
>
> > +int
> > +rte_pci_devargs_process(struct rte_pci_device *pdev)
> > +{
> > + /* For the moment, no PCI param
> > + * needs to be processed.
> > + */
> > + (void) pdev;
> > + return 0;
> > +}
>
> Use __rte_unused rather than the (void) cast?
Ok.
I was wondering whether we should keep this patch.
Its only use is to mark the proper place where this function,
once it has become needed, would need to be called.
PCI bus does not have any parameters configuring devices, this function
will only be needed once some have been added.
--
Gaëtan Rivet
6WIND
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 12/13] ethdev: process declarative eth devargs
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (10 preceding siblings ...)
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 11/13] bus/pci: process declarative PCI devargs Gaetan Rivet
@ 2018-08-30 13:42 ` Gaetan Rivet
2018-08-31 10:10 ` Andrew Rybchenko
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 13/13] eal: add generic dev parameter Gaetan Rivet
` (2 subsequent siblings)
14 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:42 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Process the class-specific arguments in a devargs.
This processing takes the form of setting the proper eth_dev fields when
relevant.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_ethdev/eth_private.h | 5 +++
lib/librte_ethdev/rte_class_eth.c | 62 +++++++++++++++++++++++++++++++
lib/librte_ethdev/rte_ethdev.c | 7 ++++
3 files changed, 74 insertions(+)
diff --git a/lib/librte_ethdev/eth_private.h b/lib/librte_ethdev/eth_private.h
index 0f5c6d5c4..c0c065165 100644
--- a/lib/librte_ethdev/eth_private.h
+++ b/lib/librte_ethdev/eth_private.h
@@ -19,6 +19,11 @@ struct rte_eth_dev *
eth_find_device(const struct rte_eth_dev *_start, rte_eth_cmp_t cmp,
const void *data);
+/* Generic rte_eth_dev parameters processor. */
+int
+rte_eth_dev_args_parse(struct rte_eth_dev *eth_dev,
+ struct rte_devargs *da);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index d8d8e8845..18fdef605 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -6,6 +6,7 @@
#include <rte_class.h>
#include <rte_compat.h>
+#include <rte_devargs.h>
#include <rte_errno.h>
#include <rte_kvargs.h>
#include <rte_log.h>
@@ -35,6 +36,19 @@ struct eth_dev_match_arg {
.kvlist = (k), \
})
+typedef int (*eth_dev_set_t)(struct rte_eth_dev *edev, const char *value);
+
+static enum eth_params
+ethdev_param_id(const char *key)
+{
+ int i;
+
+ for (i = 0; i < RTE_ETH_PARAMS_MAX; i++)
+ if (strcmp(key, eth_params_keys[i]) == 0)
+ return i;
+ return RTE_ETH_PARAMS_MAX;
+}
+
static int
eth_dev_match(const struct rte_eth_dev *edev,
const void *_arg)
@@ -79,6 +93,54 @@ eth_dev_iterate(const void *start,
return edev;
}
+static int
+eth_dev_set_name(struct rte_eth_dev *edev,
+ const char *value)
+{
+ snprintf(edev->data->name,
+ sizeof(edev->data->name),
+ "%s", value);
+ return 0;
+}
+
+static int
+ethdev_args_process(const char *key,
+ const char *value,
+ void *_edev)
+{
+ static eth_dev_set_t eth_dev_set[] = {
+ [RTE_ETH_PARAMS_NAME] = eth_dev_set_name,
+ [RTE_ETH_PARAMS_MAX] = NULL,
+ };
+ struct rte_eth_dev *edev = _edev;
+ int param;
+
+ param = ethdev_param_id(key);
+ if (eth_dev_set[param])
+ return eth_dev_set[param](edev, value);
+ return 0;
+}
+
+int
+rte_eth_dev_args_parse(struct rte_eth_dev *edev,
+ struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvargs = NULL;
+
+ if (devargs == NULL || devargs->cls_str == NULL)
+ return 0;
+
+ kvargs = rte_kvargs_parse_delim(devargs->cls_str, eth_params_keys, "/");
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "cannot parse argument list\n");
+ return -EINVAL;
+ }
+ if (rte_kvargs_process(kvargs, NULL, ethdev_args_process, edev))
+ return -1;
+ rte_kvargs_free(kvargs);
+ return 0;
+}
+
struct rte_class rte_class_eth = {
.dev_iterate = eth_dev_iterate,
};
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 4c3202505..633c7ee82 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -41,6 +41,7 @@
#include "rte_ethdev.h"
#include "rte_ethdev_driver.h"
#include "ethdev_profile.h"
+#include "eth_private.h"
int rte_eth_dev_logtype;
@@ -3496,6 +3497,12 @@ rte_eth_dev_create(struct rte_device *device, const char *name,
}
}
+ retval = rte_eth_dev_args_parse(ethdev, device->devargs);
+ if (retval) {
+ RTE_LOG(ERR, EAL, "ethdev parsing failed");
+ goto probe_failed;
+ }
+
retval = ethdev_init(ethdev, init_params);
if (retval) {
RTE_LOG(ERR, EAL, "ethdev initialisation failed");
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v1 12/13] ethdev: process declarative eth devargs
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 12/13] ethdev: process declarative eth devargs Gaetan Rivet
@ 2018-08-31 10:10 ` Andrew Rybchenko
2018-08-31 12:16 ` Gaëtan Rivet
0 siblings, 1 reply; 47+ messages in thread
From: Andrew Rybchenko @ 2018-08-31 10:10 UTC (permalink / raw)
To: Gaetan Rivet, dev
On 08/30/2018 04:42 PM, Gaetan Rivet wrote:
> Process the class-specific arguments in a devargs.
> This processing takes the form of setting the proper eth_dev fields when
> relevant.
>
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---
> lib/librte_ethdev/eth_private.h | 5 +++
> lib/librte_ethdev/rte_class_eth.c | 62 +++++++++++++++++++++++++++++++
> lib/librte_ethdev/rte_ethdev.c | 7 ++++
> 3 files changed, 74 insertions(+)
>
> diff --git a/lib/librte_ethdev/eth_private.h b/lib/librte_ethdev/eth_private.h
> index 0f5c6d5c4..c0c065165 100644
> --- a/lib/librte_ethdev/eth_private.h
> +++ b/lib/librte_ethdev/eth_private.h
> @@ -19,6 +19,11 @@ struct rte_eth_dev *
> eth_find_device(const struct rte_eth_dev *_start, rte_eth_cmp_t cmp,
> const void *data);
>
> +/* Generic rte_eth_dev parameters processor. */
> +int
> +rte_eth_dev_args_parse(struct rte_eth_dev *eth_dev,
> + struct rte_devargs *da);
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
> index d8d8e8845..18fdef605 100644
> --- a/lib/librte_ethdev/rte_class_eth.c
> +++ b/lib/librte_ethdev/rte_class_eth.c
<...>
> @@ -79,6 +93,54 @@ eth_dev_iterate(const void *start,
> return edev;
> }
>
> +static int
> +eth_dev_set_name(struct rte_eth_dev *edev,
> + const char *value)
> +{
> + snprintf(edev->data->name,
> + sizeof(edev->data->name),
> + "%s", value);
strlcpy()?
Shouldn't we return error if name does fit in name buffer?
> + return 0;
> +}
> +
> +static int
> +ethdev_args_process(const char *key,
> + const char *value,
> + void *_edev)
> +{
> + static eth_dev_set_t eth_dev_set[] = {
> + [RTE_ETH_PARAMS_NAME] = eth_dev_set_name,
> + [RTE_ETH_PARAMS_MAX] = NULL,
> + };
> + struct rte_eth_dev *edev = _edev;
> + int param;
> +
> + param = ethdev_param_id(key);
> + if (eth_dev_set[param])
> + return eth_dev_set[param](edev, value);
> + return 0;
> +}
> +
> +int
> +rte_eth_dev_args_parse(struct rte_eth_dev *edev,
> + struct rte_devargs *devargs)
> +{
> + struct rte_kvargs *kvargs = NULL;
> +
> + if (devargs == NULL || devargs->cls_str == NULL)
> + return 0;
> +
> + kvargs = rte_kvargs_parse_delim(devargs->cls_str, eth_params_keys, "/");
> + if (kvargs == NULL) {
> + RTE_LOG(ERR, EAL, "cannot parse argument list\n");
> + return -EINVAL;
> + }
> + if (rte_kvargs_process(kvargs, NULL, ethdev_args_process, edev))
Shouldn't we free kvargs here as well?
> + return -1;
> + rte_kvargs_free(kvargs);
> + return 0;
> +}
> +
> struct rte_class rte_class_eth = {
> .dev_iterate = eth_dev_iterate,
> };
<...>
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v1 12/13] ethdev: process declarative eth devargs
2018-08-31 10:10 ` Andrew Rybchenko
@ 2018-08-31 12:16 ` Gaëtan Rivet
0 siblings, 0 replies; 47+ messages in thread
From: Gaëtan Rivet @ 2018-08-31 12:16 UTC (permalink / raw)
To: Andrew Rybchenko; +Cc: dev
On Fri, Aug 31, 2018 at 01:10:48PM +0300, Andrew Rybchenko wrote:
> On 08/30/2018 04:42 PM, Gaetan Rivet wrote:
> > Process the class-specific arguments in a devargs.
> > This processing takes the form of setting the proper eth_dev fields when
> > relevant.
> >
> > Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> > ---
> > lib/librte_ethdev/eth_private.h | 5 +++
> > lib/librte_ethdev/rte_class_eth.c | 62 +++++++++++++++++++++++++++++++
> > lib/librte_ethdev/rte_ethdev.c | 7 ++++
> > 3 files changed, 74 insertions(+)
> >
> > diff --git a/lib/librte_ethdev/eth_private.h b/lib/librte_ethdev/eth_private.h
> > index 0f5c6d5c4..c0c065165 100644
> > --- a/lib/librte_ethdev/eth_private.h
> > +++ b/lib/librte_ethdev/eth_private.h
> > @@ -19,6 +19,11 @@ struct rte_eth_dev *
> > eth_find_device(const struct rte_eth_dev *_start, rte_eth_cmp_t cmp,
> > const void *data);
> > +/* Generic rte_eth_dev parameters processor. */
> > +int
> > +rte_eth_dev_args_parse(struct rte_eth_dev *eth_dev,
> > + struct rte_devargs *da);
> > +
> > #ifdef __cplusplus
> > }
> > #endif
> > diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
> > index d8d8e8845..18fdef605 100644
> > --- a/lib/librte_ethdev/rte_class_eth.c
> > +++ b/lib/librte_ethdev/rte_class_eth.c
>
> <...>
>
> > @@ -79,6 +93,54 @@ eth_dev_iterate(const void *start,
> > return edev;
> > }
> > +static int
> > +eth_dev_set_name(struct rte_eth_dev *edev,
> > + const char *value)
> > +{
> > + snprintf(edev->data->name,
> > + sizeof(edev->data->name),
> > + "%s", value);
>
> strlcpy()?
Ok.
> Shouldn't we return error if name does fit in name buffer?
Good idea.
>
> > + return 0;
> > +}
> > +
> > +static int
> > +ethdev_args_process(const char *key,
> > + const char *value,
> > + void *_edev)
> > +{
> > + static eth_dev_set_t eth_dev_set[] = {
> > + [RTE_ETH_PARAMS_NAME] = eth_dev_set_name,
> > + [RTE_ETH_PARAMS_MAX] = NULL,
> > + };
> > + struct rte_eth_dev *edev = _edev;
> > + int param;
> > +
> > + param = ethdev_param_id(key);
> > + if (eth_dev_set[param])
> > + return eth_dev_set[param](edev, value);
> > + return 0;
> > +}
> > +
> > +int
> > +rte_eth_dev_args_parse(struct rte_eth_dev *edev,
> > + struct rte_devargs *devargs)
> > +{
> > + struct rte_kvargs *kvargs = NULL;
> > +
> > + if (devargs == NULL || devargs->cls_str == NULL)
> > + return 0;
> > +
> > + kvargs = rte_kvargs_parse_delim(devargs->cls_str, eth_params_keys, "/");
> > + if (kvargs == NULL) {
> > + RTE_LOG(ERR, EAL, "cannot parse argument list\n");
> > + return -EINVAL;
> > + }
> > + if (rte_kvargs_process(kvargs, NULL, ethdev_args_process, edev))
>
> Shouldn't we free kvargs here as well?
>
Indeed, silly mistake.
Thanks
> > + return -1;
> > + rte_kvargs_free(kvargs);
> > + return 0;
> > +}
> > +
> > struct rte_class rte_class_eth = {
> > .dev_iterate = eth_dev_iterate,
> > };
>
> <...>
--
Gaëtan Rivet
6WIND
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v1 13/13] eal: add generic dev parameter
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (11 preceding siblings ...)
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 12/13] ethdev: process declarative eth devargs Gaetan Rivet
@ 2018-08-30 13:42 ` Gaetan Rivet
2018-08-30 15:42 ` [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Stephen Hemminger
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
14 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-08-30 13:42 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Add the --dev parameter to the EAL.
This new parameter takes a generic device declaration as argument.
It uses the new devargs parsing API.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_eal/common/eal_common_devargs.c | 4 +++
lib/librte_eal/common/eal_common_options.c | 36 +++++++++++++++++++---
lib/librte_eal/common/eal_options.h | 2 ++
3 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index dac2402a4..f1f4628db 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -219,6 +219,10 @@ rte_devargs_parse(struct rte_devargs *da, const char *dev)
if (da == NULL)
return -EINVAL;
+ if (strncmp(dev, "bus=", 4) == 0 ||
+ strncmp(dev, "class=", 6) == 0)
+ return rte_devargs_layers_parse(da, dev);
+
/* Retrieve eventual bus info */
do {
devname = dev;
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index dd5f97402..4a8b87676 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -54,6 +54,7 @@ const struct option
eal_long_options[] = {
{OPT_BASE_VIRTADDR, 1, NULL, OPT_BASE_VIRTADDR_NUM },
{OPT_CREATE_UIO_DEV, 0, NULL, OPT_CREATE_UIO_DEV_NUM },
+ {OPT_DEV, 1, NULL, OPT_DEV_NUM },
{OPT_FILE_PREFIX, 1, NULL, OPT_FILE_PREFIX_NUM },
{OPT_HELP, 0, NULL, OPT_HELP_NUM },
{OPT_HUGE_DIR, 1, NULL, OPT_HUGE_DIR_NUM },
@@ -111,6 +112,7 @@ TAILQ_HEAD(device_option_list, device_option);
struct device_option {
TAILQ_ENTRY(device_option) next;
+ int new;
enum rte_devtype type;
char arg[];
};
@@ -123,7 +125,8 @@ static int mem_parsed;
static int core_parsed;
static int
-eal_option_device_add(enum rte_devtype type, const char *optarg)
+eal_option_device_add(enum rte_devtype type, const char *optarg,
+ int new)
{
struct device_option *devopt;
size_t optlen;
@@ -137,6 +140,7 @@ eal_option_device_add(enum rte_devtype type, const char *optarg)
}
devopt->type = type;
+ devopt->new = new;
ret = snprintf(devopt->arg, optlen, "%s", optarg);
if (ret < 0) {
RTE_LOG(ERR, EAL, "Unable to copy device option\n");
@@ -156,7 +160,22 @@ eal_option_device_parse(void)
TAILQ_FOREACH_SAFE(devopt, &devopt_list, next, tmp) {
if (ret == 0) {
- ret = rte_devargs_add(devopt->type, devopt->arg);
+ if (devopt->new) {
+ struct rte_devargs *da;
+
+ da = calloc(1, sizeof(*da));
+ ret = rte_devargs_parse(da, devopt->arg);
+ if (ret) {
+ free(da);
+ } else {
+ ret = rte_devargs_insert(da);
+ if (ret)
+ free(da);
+ }
+ } else {
+ ret = rte_devargs_add(devopt->type,
+ devopt->arg);
+ }
if (ret)
RTE_LOG(ERR, EAL, "Unable to parse device '%s'\n",
devopt->arg);
@@ -1088,7 +1107,7 @@ eal_parse_common_option(int opt, const char *optarg,
if (w_used)
goto bw_used;
if (eal_option_device_add(RTE_DEVTYPE_BLACKLISTED_PCI,
- optarg) < 0) {
+ optarg, 0) < 0) {
return -1;
}
b_used = 1;
@@ -1098,7 +1117,7 @@ eal_parse_common_option(int opt, const char *optarg,
if (b_used)
goto bw_used;
if (eal_option_device_add(RTE_DEVTYPE_WHITELISTED_PCI,
- optarg) < 0) {
+ optarg, 0) < 0) {
return -1;
}
w_used = 1;
@@ -1234,9 +1253,16 @@ eal_parse_common_option(int opt, const char *optarg,
}
break;
+ case OPT_DEV_NUM:
+ if (eal_option_device_add(RTE_DEVTYPE_VIRTUAL,
+ optarg, 1) < 0) {
+ return -1;
+ }
+ break;
+
case OPT_VDEV_NUM:
if (eal_option_device_add(RTE_DEVTYPE_VIRTUAL,
- optarg) < 0) {
+ optarg, 0) < 0) {
return -1;
}
break;
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index 96e166787..8a17eb22c 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -21,6 +21,8 @@ enum {
OPT_BASE_VIRTADDR_NUM,
#define OPT_CREATE_UIO_DEV "create-uio-dev"
OPT_CREATE_UIO_DEV_NUM,
+#define OPT_DEV "dev"
+ OPT_DEV_NUM,
#define OPT_FILE_PREFIX "file-prefix"
OPT_FILE_PREFIX_NUM,
#define OPT_HUGE_DIR "huge-dir"
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (12 preceding siblings ...)
2018-08-30 13:42 ` [dpdk-dev] [PATCH v1 13/13] eal: add generic dev parameter Gaetan Rivet
@ 2018-08-30 15:42 ` Stephen Hemminger
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
14 siblings, 0 replies; 47+ messages in thread
From: Stephen Hemminger @ 2018-08-30 15:42 UTC (permalink / raw)
To: Gaetan Rivet; +Cc: dev, Shreyansh Jain
On Thu, 30 Aug 2018 15:41:51 +0200
Gaetan Rivet <gaetan.rivet@6wind.com> wrote:
> Last release saw the introduction of the new devargs system.
> To this end, the "class" abstraction was described as well
> as a common API for querying and declaring devices.
>
> This patchset implements the "eth" device class and the
> query/declaration part of the framework for PCI and vdev buses,
> enabling a minimal support for the new system.
>
> A new testpmd command is added to test device querying.
>
> Devargs parsing is extended in the relevant buses to test
> device declaration. This part uses the new "rte_eth_dev_create" API,
> introduced last release and used by only two PMDs, for now.
>
> The new devargs format is also made available through the new --dev parameter.
>
> Next work is to generalize use of new API for eth_dev creation,
> compatibility layer for -w, -b and --vdev with --dev, and devargs unit test.
>
> Gaetan Rivet (13):
> bus/pci: implement device iteration and comparison
> bus/pci: add device matching field id
> bus/vdev: implement device iteration
> bus/vdev: add device matching field driver
> ethdev: add private generic device iterator
> ethdev: register ether layer as a class
> ethdev: add device matching field name
> app/testpmd: add show device command
> bus/pci: pre-process declarative PCI devargs
> bus/vdev: pre-process declarative vdev devargs
> bus/pci: process declarative PCI devargs
> ethdev: process declarative eth devargs
> eal: add generic dev parameter
>
> app/test-pmd/cmdline.c | 54 +++++++
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 24 ++++
> drivers/bus/pci/Makefile | 3 +-
> drivers/bus/pci/bsd/pci.c | 5 +
> drivers/bus/pci/linux/pci.c | 5 +
> drivers/bus/pci/meson.build | 6 +-
> drivers/bus/pci/pci_common.c | 6 +-
> drivers/bus/pci/pci_params.c | 139 ++++++++++++++++++
> drivers/bus/pci/private.h | 54 +++++++
> drivers/bus/vdev/Makefile | 3 +-
> drivers/bus/vdev/meson.build | 5 +-
> drivers/bus/vdev/vdev.c | 20 +--
> drivers/bus/vdev/vdev_params.c | 112 +++++++++++++++
> drivers/bus/vdev/vdev_private.h | 32 +++++
> lib/librte_eal/common/eal_common_devargs.c | 4 +
> lib/librte_eal/common/eal_common_options.c | 36 ++++-
> lib/librte_eal/common/eal_options.h | 2 +
> lib/librte_ethdev/Makefile | 4 +-
> lib/librte_ethdev/eth_private.c | 31 ++++
> lib/librte_ethdev/eth_private.h | 31 ++++
> lib/librte_ethdev/meson.build | 4 +-
> lib/librte_ethdev/rte_class_eth.c | 148 ++++++++++++++++++++
> lib/librte_ethdev/rte_ethdev.c | 7 +
> 23 files changed, 714 insertions(+), 21 deletions(-)
> create mode 100644 drivers/bus/pci/pci_params.c
> create mode 100644 drivers/bus/vdev/vdev_params.c
> create mode 100644 drivers/bus/vdev/vdev_private.h
> create mode 100644 lib/librte_ethdev/eth_private.c
> create mode 100644 lib/librte_ethdev/eth_private.h
> create mode 100644 lib/librte_ethdev/rte_class_eth.c
>
> --
> 2.18.0
>
I have devargs for vmbus queued.
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 00/13] Implement new devargs framework
2018-08-30 13:41 [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Gaetan Rivet
` (13 preceding siblings ...)
2018-08-30 15:42 ` [dpdk-dev] [PATCH v1 00/13] Implement new devargs framework Stephen Hemminger
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 01/13] bus/pci: implement device iteration and comparison Gaetan Rivet
` (13 more replies)
14 siblings, 14 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet, Shreyansh Jain, Andrew Rybchenko
Last release saw the introduction of the new devargs system.
To this end, the "class" abstraction was described as well
as a common API for querying and declaring devices.
This patchset implements the "eth" device class and the
query/declaration part of the framework for PCI and vdev buses,
enabling a minimal support for the new system.
A new testpmd command is added to test device querying.
Devargs parsing is extended in the relevant buses to test
device declaration. This part uses the new "rte_eth_dev_create" API,
introduced last release and used by only two PMDs, for now.
The new devargs format is also made available through the new --dev parameter.
Next work is to generalize use of new API for eth_dev creation,
compatibility layer for -w, -b and --vdev with --dev, and devargs unit test.
--
v2: fixed Andrew's and Stephen's remarks,
added acks.
Gaetan Rivet (13):
bus/pci: implement device iteration and comparison
bus/pci: add device matching field id
bus/vdev: implement device iteration
bus/vdev: add device matching field driver
ethdev: add private generic device iterator
ethdev: register ether layer as a class
ethdev: add device matching field name
app/testpmd: add show device command
bus/pci: pre-process declarative PCI devargs
bus/vdev: pre-process declarative vdev devargs
bus/pci: process declarative PCI devargs
ethdev: process declarative eth devargs
eal: add generic dev parameter
app/test-pmd/cmdline.c | 54 +++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 24 +++
drivers/bus/pci/Makefile | 3 +-
drivers/bus/pci/bsd/pci.c | 5 +
drivers/bus/pci/linux/pci.c | 5 +
drivers/bus/pci/meson.build | 6 +-
drivers/bus/pci/pci_common.c | 6 +-
drivers/bus/pci/pci_params.c | 136 +++++++++++++++++
drivers/bus/pci/private.h | 54 +++++++
drivers/bus/vdev/Makefile | 3 +-
drivers/bus/vdev/meson.build | 5 +-
drivers/bus/vdev/vdev.c | 20 ++-
drivers/bus/vdev/vdev_params.c | 112 ++++++++++++++
drivers/bus/vdev/vdev_private.h | 32 ++++
lib/librte_eal/common/eal_common_devargs.c | 4 +
lib/librte_eal/common/eal_common_options.c | 36 ++++-
lib/librte_eal/common/eal_options.h | 2 +
lib/librte_ethdev/Makefile | 4 +-
lib/librte_ethdev/ethdev_private.c | 31 ++++
lib/librte_ethdev/ethdev_private.h | 31 ++++
lib/librte_ethdev/meson.build | 4 +-
lib/librte_ethdev/rte_class_eth.c | 158 ++++++++++++++++++++
lib/librte_ethdev/rte_ethdev.c | 7 +
23 files changed, 721 insertions(+), 21 deletions(-)
create mode 100644 drivers/bus/pci/pci_params.c
create mode 100644 drivers/bus/vdev/vdev_params.c
create mode 100644 drivers/bus/vdev/vdev_private.h
create mode 100644 lib/librte_ethdev/ethdev_private.c
create mode 100644 lib/librte_ethdev/ethdev_private.h
create mode 100644 lib/librte_ethdev/rte_class_eth.c
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 01/13] bus/pci: implement device iteration and comparison
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 02/13] bus/pci: add device matching field id Gaetan Rivet
` (12 subsequent siblings)
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/pci/Makefile | 3 +-
drivers/bus/pci/meson.build | 6 +++-
drivers/bus/pci/pci_common.c | 3 +-
drivers/bus/pci/pci_params.c | 53 ++++++++++++++++++++++++++++++++++++
drivers/bus/pci/private.h | 25 +++++++++++++++++
5 files changed, 86 insertions(+), 4 deletions(-)
create mode 100644 drivers/bus/pci/pci_params.c
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
index cf373068a..4de953f8f 100644
--- a/drivers/bus/pci/Makefile
+++ b/drivers/bus/pci/Makefile
@@ -26,10 +26,11 @@ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
CFLAGS += -DALLOW_EXPERIMENTAL_API
LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
-LDLIBS += -lrte_ethdev -lrte_pci
+LDLIBS += -lrte_ethdev -lrte_pci -lrte_kvargs
include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_params.c
SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common.c
SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common_uio.c
diff --git a/drivers/bus/pci/meson.build b/drivers/bus/pci/meson.build
index 72939e598..23d6a5fec 100644
--- a/drivers/bus/pci/meson.build
+++ b/drivers/bus/pci/meson.build
@@ -3,7 +3,9 @@
deps += ['pci']
install_headers('rte_bus_pci.h')
-sources = files('pci_common.c', 'pci_common_uio.c')
+sources = files('pci_common.c',
+ 'pci_common_uio.c',
+ 'pci_params.c')
if host_machine.system() == 'linux'
sources += files('linux/pci.c',
'linux/pci_uio.c',
@@ -17,3 +19,5 @@ endif
# memseg walk is not part of stable API yet
allow_experimental_apis = true
+
+deps += ['kvargs']
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 7736b3f9c..c7695d108 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -27,8 +27,6 @@
#include "private.h"
-extern struct rte_pci_bus rte_pci_bus;
-
#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
const char *rte_pci_get_sysfs_path(void)
@@ -435,6 +433,7 @@ struct rte_pci_bus rte_pci_bus = {
.unplug = pci_unplug,
.parse = pci_parse,
.get_iommu_class = rte_pci_get_iommu_class,
+ .dev_iterate = rte_pci_dev_iterate,
},
.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
new file mode 100644
index 000000000..0fde75803
--- /dev/null
+++ b/drivers/bus/pci/pci_params.c
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Gaëtan Rivet
+ */
+
+#include <rte_bus.h>
+#include <rte_dev.h>
+#include <rte_errno.h>
+#include <rte_kvargs.h>
+#include <rte_pci.h>
+
+#include "private.h"
+
+enum pci_params {
+ RTE_PCI_PARAMS_MAX,
+};
+
+static const char * const pci_params_keys[] = {
+ [RTE_PCI_PARAMS_MAX] = NULL,
+};
+
+static int
+pci_dev_match(const struct rte_device *dev,
+ const void *_kvlist)
+{
+ const struct rte_kvargs *kvlist = _kvlist;
+
+ (void) dev;
+ (void) kvlist;
+ return 0;
+}
+
+void *
+rte_pci_dev_iterate(const void *start,
+ const char *str,
+ const struct rte_dev_iterator *it __rte_unused)
+{
+ rte_bus_find_device_t find_device;
+ struct rte_kvargs *kvargs = NULL;
+ struct rte_device *dev;
+
+ if (str != NULL) {
+ kvargs = rte_kvargs_parse(str, pci_params_keys);
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "cannot parse argument list\n");
+ rte_errno = EINVAL;
+ return NULL;
+ }
+ }
+ find_device = rte_pci_bus.bus.find_device;
+ dev = find_device(start, pci_dev_match, kvargs);
+ rte_kvargs_free(kvargs);
+ return dev;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 8ddd03e16..0e689fa74 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -10,6 +10,8 @@
#include <rte_pci.h>
#include <rte_bus_pci.h>
+extern struct rte_pci_bus rte_pci_bus;
+
struct rte_pci_driver;
struct rte_pci_device;
@@ -166,4 +168,27 @@ rte_pci_match(const struct rte_pci_driver *pci_drv,
enum rte_iova_mode
rte_pci_get_iommu_class(void);
+/*
+ * Iterate over internal devices,
+ * matching any device against the provided
+ * string.
+ *
+ * @param start
+ * Iteration starting point.
+ *
+ * @param str
+ * Device string to match against.
+ *
+ * @param it
+ * (unused) iterator structure.
+ *
+ * @return
+ * A pointer to the next matching device if any.
+ * NULL otherwise.
+ */
+void *
+rte_pci_dev_iterate(const void *start,
+ const char *str,
+ const struct rte_dev_iterator *it);
+
#endif /* _PCI_PRIVATE_H_ */
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 02/13] bus/pci: add device matching field id
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 01/13] bus/pci: implement device iteration and comparison Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 03/13] bus/vdev: implement device iteration Gaetan Rivet
` (11 subsequent siblings)
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The PCI bus can now parse a matching field "id" as follows:
"bus=pci,id=0000:00:00.0"
or
"bus=pci,id=00:00.0"
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/pci/pci_params.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
index 0fde75803..7630d4845 100644
--- a/drivers/bus/pci/pci_params.c
+++ b/drivers/bus/pci/pci_params.c
@@ -3,6 +3,7 @@
*/
#include <rte_bus.h>
+#include <rte_bus_pci.h>
#include <rte_dev.h>
#include <rte_errno.h>
#include <rte_kvargs.h>
@@ -11,21 +12,45 @@
#include "private.h"
enum pci_params {
+ RTE_PCI_PARAMS_ID,
RTE_PCI_PARAMS_MAX,
};
static const char * const pci_params_keys[] = {
+ [RTE_PCI_PARAMS_ID] = "id",
[RTE_PCI_PARAMS_MAX] = NULL,
};
+static int
+pci_addr_kv_cmp(const char *key __rte_unused,
+ const char *value,
+ void *_addr2)
+{
+ struct rte_pci_addr _addr1;
+ struct rte_pci_addr *addr1 = &_addr1;
+ struct rte_pci_addr *addr2 = _addr2;
+
+ if (rte_pci_addr_parse(value, addr1))
+ return -1;
+ return -abs(rte_pci_addr_cmp(addr1, addr2));
+}
+
static int
pci_dev_match(const struct rte_device *dev,
const void *_kvlist)
{
const struct rte_kvargs *kvlist = _kvlist;
+ const struct rte_pci_device *pdev;
- (void) dev;
- (void) kvlist;
+ if (kvlist == NULL)
+ /* Empty string matches everything. */
+ return 0;
+ pdev = RTE_DEV_TO_PCI_CONST(dev);
+ /* if any field does not match. */
+ if (rte_kvargs_process(kvlist, "id",
+ &pci_addr_kv_cmp,
+ (void *)(intptr_t)&pdev->addr))
+ return 1;
return 0;
}
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 03/13] bus/vdev: implement device iteration
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 01/13] bus/pci: implement device iteration and comparison Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 02/13] bus/pci: add device matching field id Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 04/13] bus/vdev: add device matching field driver Gaetan Rivet
` (10 subsequent siblings)
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/vdev/Makefile | 3 +-
drivers/bus/vdev/meson.build | 5 +++-
drivers/bus/vdev/vdev.c | 10 ++++---
drivers/bus/vdev/vdev_params.c | 51 +++++++++++++++++++++++++++++++++
drivers/bus/vdev/vdev_private.h | 26 +++++++++++++++++
5 files changed, 89 insertions(+), 6 deletions(-)
create mode 100644 drivers/bus/vdev/vdev_params.c
create mode 100644 drivers/bus/vdev/vdev_private.h
diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile
index bd0bb8955..1f9cd7ebe 100644
--- a/drivers/bus/vdev/Makefile
+++ b/drivers/bus/vdev/Makefile
@@ -19,8 +19,9 @@ EXPORT_MAP := rte_bus_vdev_version.map
LIBABIVER := 1
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 2ee648b49..12605e5c7 100644
--- a/drivers/bus/vdev/meson.build
+++ b/drivers/bus/vdev/meson.build
@@ -1,7 +1,10 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-sources = files('vdev.c')
+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 69dee89a8..ef3ad6d99 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"
@@ -497,9 +498,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;
@@ -536,10 +537,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 000000000..842a4684e
--- /dev/null
+++ b/drivers/bus/vdev/vdev_params.c
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Gaëtan Rivet
+ */
+
+#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_PARAMS_MAX,
+};
+
+static const char * const vdev_params_keys[] = {
+ [RTE_VDEV_PARAMS_MAX] = NULL,
+};
+
+static int
+vdev_dev_match(const struct rte_device *dev,
+ const void *_kvlist)
+{
+ const struct rte_kvargs *kvlist = _kvlist;
+
+ (void) kvlist;
+ (void) dev;
+ 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 000000000..ba6dc48ff
--- /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_ */
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 04/13] bus/vdev: add device matching field driver
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (2 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 03/13] bus/vdev: implement device iteration Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-20 16:11 ` Thomas Monjalon
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 05/13] ethdev: add private generic device iterator Gaetan Rivet
` (9 subsequent siblings)
13 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The vdev bus parses a field "driver", matching
a vdev driver name with one passed as follows:
"bus=vdev,driver=xxxx"
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/vdev/vdev_params.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c
index 842a4684e..2f55f451f 100644
--- a/drivers/bus/vdev/vdev_params.c
+++ b/drivers/bus/vdev/vdev_params.c
@@ -4,6 +4,7 @@
#include <rte_dev.h>
#include <rte_bus.h>
+#include <rte_bus_vdev.h>
#include <rte_kvargs.h>
#include <rte_errno.h>
@@ -11,10 +12,12 @@
#include "vdev_private.h"
enum vdev_params {
+ RTE_VDEV_PARAMS_DRIVER,
RTE_VDEV_PARAMS_MAX,
};
static const char * const vdev_params_keys[] = {
+ [RTE_VDEV_PARAMS_DRIVER] = "driver",
[RTE_VDEV_PARAMS_MAX] = NULL,
};
@@ -23,9 +26,17 @@ vdev_dev_match(const struct rte_device *dev,
const void *_kvlist)
{
const struct rte_kvargs *kvlist = _kvlist;
+ const struct rte_vdev_device *vdev;
- (void) kvlist;
- (void) dev;
+ if (kvlist == NULL)
+ /* Empty string matches everything. */
+ return 0;
+ vdev = RTE_DEV_TO_VDEV_CONST(dev);
+ /* if any field does not match. */
+ if (rte_kvargs_process(kvlist, "driver",
+ rte_kvargs_strcmp,
+ (void *)(intptr_t)vdev->device.driver->name))
+ return -1;
return 0;
}
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v2 04/13] bus/vdev: add device matching field driver
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 04/13] bus/vdev: add device matching field driver Gaetan Rivet
@ 2018-09-20 16:11 ` Thomas Monjalon
2018-09-21 11:53 ` Gaëtan Rivet
0 siblings, 1 reply; 47+ messages in thread
From: Thomas Monjalon @ 2018-09-20 16:11 UTC (permalink / raw)
To: Gaetan Rivet; +Cc: dev
19/09/2018 18:03, Gaetan Rivet:
> The vdev bus parses a field "driver", matching
> a vdev driver name with one passed as follows:
>
> "bus=vdev,driver=xxxx"
I think the property should be "name".
We already have a "driver" category.
So it may be "bus=vdev,name=mytap/driver=tap"
Until now we were using the name of the driver as a prefix for
the device name because it was the only way of knowing the driver to use.
With a richer syntax like above, this restriction can be removed.
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v2 04/13] bus/vdev: add device matching field driver
2018-09-20 16:11 ` Thomas Monjalon
@ 2018-09-21 11:53 ` Gaëtan Rivet
2018-09-21 12:55 ` Thomas Monjalon
0 siblings, 1 reply; 47+ messages in thread
From: Gaëtan Rivet @ 2018-09-21 11:53 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On Thu, Sep 20, 2018 at 06:11:44PM +0200, Thomas Monjalon wrote:
> 19/09/2018 18:03, Gaetan Rivet:
> > The vdev bus parses a field "driver", matching
> > a vdev driver name with one passed as follows:
> >
> > "bus=vdev,driver=xxxx"
>
> I think the property should be "name".
> We already have a "driver" category.
> So it may be "bus=vdev,name=mytap/driver=tap"
>
> Until now we were using the name of the driver as a prefix for
> the device name because it was the only way of knowing the driver to use.
> With a richer syntax like above, this restriction can be removed.
Do you want all buses to read the driver= key and use it to know which
driver to probe, or is it an exception of the vdev bus?
--
Gaëtan Rivet
6WIND
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v2 04/13] bus/vdev: add device matching field driver
2018-09-21 11:53 ` Gaëtan Rivet
@ 2018-09-21 12:55 ` Thomas Monjalon
0 siblings, 0 replies; 47+ messages in thread
From: Thomas Monjalon @ 2018-09-21 12:55 UTC (permalink / raw)
To: Gaëtan Rivet; +Cc: dev
21/09/2018 13:53, Gaëtan Rivet:
> On Thu, Sep 20, 2018 at 06:11:44PM +0200, Thomas Monjalon wrote:
> > 19/09/2018 18:03, Gaetan Rivet:
> > > The vdev bus parses a field "driver", matching
> > > a vdev driver name with one passed as follows:
> > >
> > > "bus=vdev,driver=xxxx"
> >
> > I think the property should be "name".
> > We already have a "driver" category.
> > So it may be "bus=vdev,name=mytap/driver=tap"
> >
> > Until now we were using the name of the driver as a prefix for
> > the device name because it was the only way of knowing the driver to use.
> > With a richer syntax like above, this restriction can be removed.
>
> Do you want all buses to read the driver= key and use it to know which
> driver to probe, or is it an exception of the vdev bus?
Good point. Yes, if the driver= key is provided, the bus should respect it.
It may allow to have 2 different drivers supporting the same PCI ids,
and let the user override the default driver to use.
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 05/13] ethdev: add private generic device iterator
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (3 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 04/13] bus/vdev: add device matching field driver Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-20 10:02 ` Andrew Rybchenko
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 06/13] ethdev: register ether layer as a class Gaetan Rivet
` (8 subsequent siblings)
13 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
This iterator can be customized with a comparison function that will
trigger a stopping condition.
It can be leveraged to write several different iterators that have
similar but non-identical purposes.
It is private to librte_ethdev.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_ethdev/Makefile | 1 +
lib/librte_ethdev/ethdev_private.c | 31 ++++++++++++++++++++++++++++++
lib/librte_ethdev/ethdev_private.h | 26 +++++++++++++++++++++++++
lib/librte_ethdev/meson.build | 3 ++-
4 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_ethdev/ethdev_private.c
create mode 100644 lib/librte_ethdev/ethdev_private.h
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 0935a275e..4b0eeaac7 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -18,6 +18,7 @@ EXPORT_MAP := rte_ethdev_version.map
LIBABIVER := 10
+SRCS-y += ethdev_private.c
SRCS-y += rte_ethdev.c
SRCS-y += rte_flow.c
SRCS-y += rte_tm.c
diff --git a/lib/librte_ethdev/ethdev_private.c b/lib/librte_ethdev/ethdev_private.c
new file mode 100644
index 000000000..768c8b2ed
--- /dev/null
+++ b/lib/librte_ethdev/ethdev_private.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Gaëtan Rivet
+ */
+
+#include "rte_ethdev.h"
+#include "ethdev_private.h"
+
+struct rte_eth_dev *
+eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp,
+ const void *data)
+{
+ struct rte_eth_dev *edev;
+ ptrdiff_t idx;
+
+ /* Avoid Undefined Behaviour */
+ if (start != NULL &&
+ (start < &rte_eth_devices[0] ||
+ start > &rte_eth_devices[RTE_MAX_ETHPORTS]))
+ return NULL;
+ if (start != NULL)
+ idx = start - &rte_eth_devices[0] + 1;
+ else
+ idx = 0;
+ for (; idx < RTE_MAX_ETHPORTS; idx++) {
+ edev = &rte_eth_devices[idx];
+ if (cmp(edev, data) == 0)
+ return edev;
+ }
+ return NULL;
+}
+
diff --git a/lib/librte_ethdev/ethdev_private.h b/lib/librte_ethdev/ethdev_private.h
new file mode 100644
index 000000000..0f5c6d5c4
--- /dev/null
+++ b/lib/librte_ethdev/ethdev_private.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Gaëtan Rivet
+ */
+
+#ifndef _RTE_ETH_PRIVATE_H_
+#define _RTE_ETH_PRIVATE_H_
+
+#include "rte_ethdev.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Generic rte_eth_dev comparison function. */
+typedef int (*rte_eth_cmp_t)(const struct rte_eth_dev *, const void *);
+
+/* Generic rte_eth_dev iterator. */
+struct rte_eth_dev *
+eth_find_device(const struct rte_eth_dev *_start, rte_eth_cmp_t cmp,
+ const void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ETH_PRIVATE_H_ */
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 596cd0f39..7798217d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -4,7 +4,8 @@
name = 'ethdev'
version = 10
allow_experimental_apis = true
-sources = files('ethdev_profile.c',
+sources = files('ethdev_private.c',
+ 'ethdev_profile.c',
'rte_ethdev.c',
'rte_flow.c',
'rte_mtr.c',
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 06/13] ethdev: register ether layer as a class
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (4 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 05/13] ethdev: add private generic device iterator Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 07/13] ethdev: add device matching field name Gaetan Rivet
` (7 subsequent siblings)
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Implement the operators of an rte_class for the
ethdev abstraction layer.
Register the layer as such.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
lib/librte_ethdev/Makefile | 3 +-
lib/librte_ethdev/meson.build | 1 +
lib/librte_ethdev/rte_class_eth.c | 79 +++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_ethdev/rte_class_eth.c
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 4b0eeaac7..d720dd207 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf
+LDLIBS += -lrte_mbuf -lrte_kvargs
EXPORT_MAP := rte_ethdev_version.map
@@ -20,6 +20,7 @@ LIBABIVER := 10
SRCS-y += ethdev_private.c
SRCS-y += rte_ethdev.c
+SRCS-y += rte_class_eth.c
SRCS-y += rte_flow.c
SRCS-y += rte_tm.c
SRCS-y += rte_mtr.c
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 7798217d0..172e302f0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -6,6 +6,7 @@ version = 10
allow_experimental_apis = true
sources = files('ethdev_private.c',
'ethdev_profile.c',
+ 'rte_class_eth.c',
'rte_ethdev.c',
'rte_flow.c',
'rte_mtr.c',
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
new file mode 100644
index 000000000..b6557db97
--- /dev/null
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Gaëtan Rivet
+ */
+
+#include <string.h>
+
+#include <rte_class.h>
+#include <rte_compat.h>
+#include <rte_errno.h>
+#include <rte_kvargs.h>
+#include <rte_log.h>
+
+#include "rte_ethdev.h"
+#include "rte_ethdev_core.h"
+#include "ethdev_private.h"
+
+enum eth_params {
+ RTE_ETH_PARAMS_MAX,
+};
+
+static const char * const eth_params_keys[] = {
+ [RTE_ETH_PARAMS_MAX] = NULL,
+};
+
+struct eth_dev_match_arg {
+ struct rte_device *device;
+ struct rte_kvargs *kvlist;
+};
+
+#define eth_dev_match_arg(d, k) \
+ (&(const struct eth_dev_match_arg) { \
+ .device = (d), \
+ .kvlist = (k), \
+ })
+
+static int
+eth_dev_match(const struct rte_eth_dev *edev,
+ const void *_arg)
+{
+ const struct eth_dev_match_arg *arg = _arg;
+ const struct rte_kvargs *kvlist = arg->kvlist;
+
+ if (edev->state == RTE_ETH_DEV_UNUSED)
+ return -1;
+ if (edev->device != arg->device)
+ return -1;
+ if (kvlist == NULL)
+ /* Empty string matches everything. */
+ return 0;
+ return 0;
+}
+
+static void *
+eth_dev_iterate(const void *start,
+ const char *str,
+ const struct rte_dev_iterator *it)
+{
+ struct rte_kvargs *kvargs = NULL;
+ struct rte_eth_dev *edev = NULL;
+
+ if (str != NULL) {
+ kvargs = rte_kvargs_parse(str, eth_params_keys);
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "cannot parse argument list\n");
+ rte_errno = EINVAL;
+ return NULL;
+ }
+ }
+ edev = eth_find_device(start, eth_dev_match,
+ eth_dev_match_arg(it->device, kvargs));
+ rte_kvargs_free(kvargs);
+ return edev;
+}
+
+struct rte_class rte_class_eth = {
+ .dev_iterate = eth_dev_iterate,
+};
+
+RTE_REGISTER_CLASS(eth, rte_class_eth);
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 07/13] ethdev: add device matching field name
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (5 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 06/13] ethdev: register ether layer as a class Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-20 16:17 ` Thomas Monjalon
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 08/13] app/testpmd: add show device command Gaetan Rivet
` (6 subsequent siblings)
13 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The eth device class can now parse a field name,
matching the eth_dev name with one passed as
"class=eth,name=xxxxxx"
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
lib/librte_ethdev/rte_class_eth.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index b6557db97..66fd48dc2 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -15,10 +15,12 @@
#include "ethdev_private.h"
enum eth_params {
+ RTE_ETH_PARAMS_NAME,
RTE_ETH_PARAMS_MAX,
};
static const char * const eth_params_keys[] = {
+ [RTE_ETH_PARAMS_NAME] = "name",
[RTE_ETH_PARAMS_MAX] = NULL,
};
@@ -39,6 +41,7 @@ eth_dev_match(const struct rte_eth_dev *edev,
{
const struct eth_dev_match_arg *arg = _arg;
const struct rte_kvargs *kvlist = arg->kvlist;
+ struct rte_eth_dev_data *data;
if (edev->state == RTE_ETH_DEV_UNUSED)
return -1;
@@ -47,6 +50,10 @@ eth_dev_match(const struct rte_eth_dev *edev,
if (kvlist == NULL)
/* Empty string matches everything. */
return 0;
+ data = edev->data;
+ if (rte_kvargs_process(kvlist, "name",
+ rte_kvargs_strcmp, data->name))
+ return -1;
return 0;
}
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v2 07/13] ethdev: add device matching field name
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 07/13] ethdev: add device matching field name Gaetan Rivet
@ 2018-09-20 16:17 ` Thomas Monjalon
2018-09-21 12:16 ` Gaëtan Rivet
0 siblings, 1 reply; 47+ messages in thread
From: Thomas Monjalon @ 2018-09-20 16:17 UTC (permalink / raw)
To: Gaetan Rivet; +Cc: dev, arybchenko
19/09/2018 18:03, Gaetan Rivet:
> The eth device class can now parse a field name,
> matching the eth_dev name with one passed as
>
> "class=eth,name=xxxxxx"
I am not sure what is the purpose of the "name" property.
I think we should not need it to choose a port by its ethdev name.
If you are thinking about a vdev, we can use the rte_device name (at bus level).
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v2 07/13] ethdev: add device matching field name
2018-09-20 16:17 ` Thomas Monjalon
@ 2018-09-21 12:16 ` Gaëtan Rivet
2018-09-21 13:06 ` Thomas Monjalon
0 siblings, 1 reply; 47+ messages in thread
From: Gaëtan Rivet @ 2018-09-21 12:16 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, arybchenko
On Thu, Sep 20, 2018 at 06:17:13PM +0200, Thomas Monjalon wrote:
> 19/09/2018 18:03, Gaetan Rivet:
> > The eth device class can now parse a field name,
> > matching the eth_dev name with one passed as
> >
> > "class=eth,name=xxxxxx"
>
> I am not sure what is the purpose of the "name" property.
> I think we should not need it to choose a port by its ethdev name.
rte_eth_dev_get_port_by_name seems pretty close.
Which fields do you think should be proposed first as a getter on the eth class?
Or do you have a list of fields the eth class should be restricted to?
> If you are thinking about a vdev, we can use the rte_device name (at bus level).
This patch is only about eth class, it has no impact on buses.
--
Gaëtan Rivet
6WIND
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v2 07/13] ethdev: add device matching field name
2018-09-21 12:16 ` Gaëtan Rivet
@ 2018-09-21 13:06 ` Thomas Monjalon
0 siblings, 0 replies; 47+ messages in thread
From: Thomas Monjalon @ 2018-09-21 13:06 UTC (permalink / raw)
To: Gaëtan Rivet; +Cc: dev, arybchenko
21/09/2018 14:16, Gaëtan Rivet:
> On Thu, Sep 20, 2018 at 06:17:13PM +0200, Thomas Monjalon wrote:
> > 19/09/2018 18:03, Gaetan Rivet:
> > > The eth device class can now parse a field name,
> > > matching the eth_dev name with one passed as
> > >
> > > "class=eth,name=xxxxxx"
> >
> > I am not sure what is the purpose of the "name" property.
> > I think we should not need it to choose a port by its ethdev name.
>
> rte_eth_dev_get_port_by_name seems pretty close.
Exact, this function already exists to get a port id by name.
I think we should discourage the use of ethdev "internal" name.
The point of the devargs is to match device with explicit known properties.
> Which fields do you think should be proposed first as a getter on the eth class?
> Or do you have a list of fields the eth class should be restricted to?
In other words, which ethdev properties can help to match a port?
I think about "mac=" (which is already implemented in OVS devargs),
and "representor=" (which requires a new field in ethdev).
About representors, we could also match all representor ports of a switch
(see rte_eth_switch_info).
We could also have a property for the kernel netdev we are (or were) bound.
Does it make sense?
> > If you are thinking about a vdev, we can use the rte_device name (at bus level).
>
> This patch is only about eth class, it has no impact on buses.
So we agree :)
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 08/13] app/testpmd: add show device command
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (6 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 07/13] ethdev: add device matching field name Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 09/13] bus/pci: pre-process declarative PCI devargs Gaetan Rivet
` (5 subsequent siblings)
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
A new interactive command is offered:
show device <device description>
This commands lists all rte_device element matching the device
description. e.g.:
show device bus=pci
show device bus=vdev
show device bus=vdev/class=eth
show device bus=vdev,driver=net_ring/class=eth
show device bus=vdev/class=eth,name=net_ring0
These devices may not be otherwise useful, some buses will spawn devices
to keep track of their assets without having a driver to use them.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
app/test-pmd/cmdline.c | 54 +++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 24 +++++++++
2 files changed, 78 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0cbd340c1..a4846d9a8 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -228,6 +228,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"show port tm node stats (port_id) (node_id) (clear)\n"
" Display the port TM node stats.\n\n"
+ "show device (device_string)\n"
+ " Display devices matching the device string.\n\n"
+
);
}
@@ -7115,6 +7118,56 @@ cmdline_parse_inst_t cmd_showportall = {
},
};
+/* *** SHOW DEVICE INFO *** */
+struct cmd_showdevice_result {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t device;
+ cmdline_fixed_string_t filter;
+};
+
+static void
+cmd_showdevice_dump_device(const struct rte_device *dev)
+{
+ const struct rte_driver *drv = dev->driver;
+
+ printf("0x%p: %s:%s\n", (const void *)dev, dev->name,
+ drv ? drv->name : "<nil>");
+}
+
+static void cmd_showdevice_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_showdevice_result *res = parsed_result;
+ struct rte_dev_iterator it;
+ const struct rte_device *dev;
+
+ RTE_DEV_FOREACH(dev, res->filter, &it)
+ cmd_showdevice_dump_device(dev);
+}
+
+cmdline_parse_token_string_t cmd_showdevice_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result,
+ show, "show");
+cmdline_parse_token_string_t cmd_showdevice_device =
+ TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result,
+ device, "device");
+cmdline_parse_token_string_t cmd_showdevice_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result,
+ filter, NULL);
+
+cmdline_parse_inst_t cmd_showdevice = {
+ .f = cmd_showdevice_parsed,
+ .data = NULL,
+ .help_str = "show device <device string>",
+ .tokens = {
+ (void *)&cmd_showdevice_show,
+ (void *)&cmd_showdevice_device,
+ (void *)&cmd_showdevice_filter,
+ NULL,
+ },
+};
+
/* *** SHOW PORT INFO *** */
struct cmd_showport_result {
cmdline_fixed_string_t show;
@@ -17608,6 +17661,7 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_help_long,
(cmdline_parse_inst_t *)&cmd_quit,
(cmdline_parse_inst_t *)&cmd_load_from_file,
+ (cmdline_parse_inst_t *)&cmd_showdevice,
(cmdline_parse_inst_t *)&cmd_showport,
(cmdline_parse_inst_t *)&cmd_showqueue,
(cmdline_parse_inst_t *)&cmd_showportall,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index dde205a2b..417072cce 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2663,6 +2663,30 @@ set the traffic management default hierarchy on the port::
testpmd> set port tm hierarchy default (port_id)
+Device functions
+----------------
+
+Show devices
+~~~~~~~~~~~~
+
+Display any registered devices::
+
+ testpmd> show device <device_string>
+
+where:
+
+* ``device_string``: Device description string, of the format
+
+ layer[/layer[/layer]]
+
+ where one layer is in the form
+
+ layer_key=layer_name[,key1=value1[,...]]
+
+ Valid layer keys are ``bus`` and ``class``.
+ Their respective values is defined by registered ``bus`` and ``class``
+ drivers.
+
Filter Functions
----------------
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 09/13] bus/pci: pre-process declarative PCI devargs
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (7 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 08/13] app/testpmd: add show device command Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 10/13] bus/vdev: pre-process declarative vdev devargs Gaetan Rivet
` (4 subsequent siblings)
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The new devargs format does not recognize a particular device name.
Each bus uses its specific format.
Instead of introducing a new bus API, process those devargs privately
for the moment. Prepare them for matching during scan against the
bus devices.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/pci/bsd/pci.c | 5 ++++
drivers/bus/pci/linux/pci.c | 5 ++++
drivers/bus/pci/pci_params.c | 51 ++++++++++++++++++++++++++++++++++++
drivers/bus/pci/private.h | 16 +++++++++++
4 files changed, 77 insertions(+)
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
index 655b34b7e..046cd11d5 100644
--- a/drivers/bus/pci/bsd/pci.c
+++ b/drivers/bus/pci/bsd/pci.c
@@ -327,6 +327,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
int
rte_pci_scan(void)
{
+ struct rte_devargs *devargs;
int fd;
unsigned dev_count = 0;
struct pci_conf matches[16];
@@ -342,6 +343,10 @@ rte_pci_scan(void)
if (!rte_eal_has_pci())
return 0;
+ RTE_EAL_DEVARGS_FOREACH("pci", devargs)
+ if (rte_pci_devargs_prepare(devargs))
+ continue;
+
fd = open("/dev/pci", O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
index 04648ac93..12f246089 100644
--- a/drivers/bus/pci/linux/pci.c
+++ b/drivers/bus/pci/linux/pci.c
@@ -429,6 +429,7 @@ parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
int
rte_pci_scan(void)
{
+ struct rte_devargs *devargs;
struct dirent *e;
DIR *dir;
char dirname[PATH_MAX];
@@ -438,6 +439,10 @@ rte_pci_scan(void)
if (!rte_eal_has_pci())
return 0;
+ RTE_EAL_DEVARGS_FOREACH("pci", devargs)
+ if (rte_pci_devargs_prepare(devargs))
+ continue;
+
#ifdef VFIO_PRESENT
if (!pci_vfio_is_enabled())
RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
index 7630d4845..a09af3b1c 100644
--- a/drivers/bus/pci/pci_params.c
+++ b/drivers/bus/pci/pci_params.c
@@ -2,9 +2,12 @@
* Copyright 2018 Gaëtan Rivet
*/
+#include <string.h>
+
#include <rte_bus.h>
#include <rte_bus_pci.h>
#include <rte_dev.h>
+#include <rte_devargs.h>
#include <rte_errno.h>
#include <rte_kvargs.h>
#include <rte_pci.h>
@@ -76,3 +79,51 @@ rte_pci_dev_iterate(const void *start,
rte_kvargs_free(kvargs);
return dev;
}
+
+static int
+pci_addr_kv_parse(const char *key __rte_unused,
+ const char *value,
+ void *_devargs)
+{
+ struct rte_devargs *devargs = _devargs;
+ struct rte_pci_addr addr;
+
+ /* Verify address is valid. */
+ if (rte_pci_addr_parse(value, &addr)) {
+ rte_errno = ENODEV;
+ return -1;
+ }
+ /* Write down the address as the devargs name. */
+ rte_pci_device_name(&addr, devargs->name, sizeof(devargs->name));
+ return 0;
+}
+
+int
+rte_pci_devargs_prepare(struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvargs = NULL;
+ char *args;
+ int ret;
+
+ if (devargs->bus_str == NULL)
+ return 0;
+
+ args = strchr(devargs->bus_str, ',');
+ if (args == NULL)
+ return 0;
+ args++;
+
+ kvargs = rte_kvargs_parse(args, pci_params_keys);
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "unable to parse parameter list: %s\n",
+ devargs->bus_str);
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ ret = rte_kvargs_process(kvargs, "id",
+ &pci_addr_kv_parse, devargs);
+
+ rte_kvargs_free(kvargs);
+ return ret;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 0e689fa74..9beb24c6a 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -191,4 +191,20 @@ rte_pci_dev_iterate(const void *start,
const char *str,
const struct rte_dev_iterator *it);
+/*
+ * Prepare a devargs meant for this bus.
+ * This function is only used for a transitory period,
+ * to translate the new devargs format in one
+ * compatible with the old form.
+ *
+ * @param da
+ * Devargs to process.
+ *
+ * @return
+ * 0 on success.
+ * <0 on error.
+ */
+int
+rte_pci_devargs_prepare(struct rte_devargs *da);
+
#endif /* _PCI_PRIVATE_H_ */
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 10/13] bus/vdev: pre-process declarative vdev devargs
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (8 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 09/13] bus/pci: pre-process declarative PCI devargs Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 11/13] bus/pci: process declarative PCI devargs Gaetan Rivet
` (3 subsequent siblings)
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
The new devargs format does not recognize a particular device name.
Each bus uses its specific format.
Process each devargs privately prior to attempting a bus scan.
Prepare them if they are using the new devargs format.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/vdev/vdev.c | 10 ++++---
drivers/bus/vdev/vdev_params.c | 50 +++++++++++++++++++++++++++++++++
drivers/bus/vdev/vdev_private.h | 6 ++++
3 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index ef3ad6d99..5699e0744 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -115,8 +115,8 @@ rte_vdev_remove_custom_scan(rte_vdev_scan_callback callback, void *user_arg)
return 0;
}
-static int
-vdev_parse(const char *name, void *addr)
+int
+rte_vdev_parse(const char *name, void *addr)
{
struct rte_vdev_driver **out = addr;
struct rte_vdev_driver *driver = NULL;
@@ -148,7 +148,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
VDEV_LOG(DEBUG, "Search driver %s to probe device %s", name,
rte_vdev_device_name(dev));
- if (vdev_parse(name, &driver))
+ if (rte_vdev_parse(name, &driver))
return -1;
dev->device.driver = &driver->driver;
ret = driver->probe(dev);
@@ -447,6 +447,8 @@ vdev_scan(void)
/* for virtual devices we scan the devargs_list populated via cmdline */
RTE_EAL_DEVARGS_FOREACH("vdev", devargs) {
+ if (rte_vdev_devargs_prepare(devargs))
+ continue;
dev = calloc(1, sizeof(*dev));
if (!dev)
@@ -540,7 +542,7 @@ static struct rte_bus rte_vdev_bus = {
.find_device = rte_vdev_find_device,
.plug = vdev_plug,
.unplug = vdev_unplug,
- .parse = vdev_parse,
+ .parse = rte_vdev_parse,
.dev_iterate = rte_vdev_dev_iterate,
};
diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c
index 2f55f451f..aafaf3330 100644
--- a/drivers/bus/vdev/vdev_params.c
+++ b/drivers/bus/vdev/vdev_params.c
@@ -2,11 +2,14 @@
* Copyright 2018 Gaëtan Rivet
*/
+#include <string.h>
+
#include <rte_dev.h>
#include <rte_bus.h>
#include <rte_bus_vdev.h>
#include <rte_kvargs.h>
#include <rte_errno.h>
+#include <rte_devargs.h>
#include "vdev_logs.h"
#include "vdev_private.h"
@@ -60,3 +63,50 @@ rte_vdev_dev_iterate(const void *start,
rte_kvargs_free(kvargs);
return dev;
}
+
+static int
+vdev_driver_kv_parse(const char *key __rte_unused,
+ const char *value,
+ void *_devargs)
+{
+ struct rte_devargs *devargs = _devargs;
+ struct rte_vdev_driver *driver;
+
+ /* Verify that the driver matches. */
+ if (rte_vdev_parse(value, &driver))
+ return -1;
+
+ /* Copy the driver name as-is. */
+ snprintf(devargs->name, sizeof(devargs->name), "%s", value);
+ return 0;
+}
+
+int
+rte_vdev_devargs_prepare(struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvargs = NULL;
+ char *args;
+ int ret;
+
+ if (devargs->bus_str == NULL)
+ return 0;
+
+ args = strchr(devargs->bus_str, ',');
+ if (args == NULL)
+ return 0;
+ args++;
+
+ kvargs = rte_kvargs_parse(args, vdev_params_keys);
+ if (kvargs == NULL) {
+ VDEV_LOG(ERR, "unable to parse parameter list: %s\n",
+ devargs->bus_str);
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ ret = rte_kvargs_process(kvargs, "driver",
+ vdev_driver_kv_parse, devargs);
+
+ rte_kvargs_free(kvargs);
+ return ret;
+}
diff --git a/drivers/bus/vdev/vdev_private.h b/drivers/bus/vdev/vdev_private.h
index ba6dc48ff..da57b84dd 100644
--- a/drivers/bus/vdev/vdev_private.h
+++ b/drivers/bus/vdev/vdev_private.h
@@ -19,6 +19,12 @@ rte_vdev_dev_iterate(const void *start,
const char *str,
const struct rte_dev_iterator *it);
+int
+rte_vdev_parse(const char *name, void *addr);
+
+int
+rte_vdev_devargs_prepare(struct rte_devargs *da);
+
#ifdef __cplusplus
}
#endif
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 11/13] bus/pci: process declarative PCI devargs
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (9 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 10/13] bus/vdev: pre-process declarative vdev devargs Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 12/13] ethdev: process declarative eth devargs Gaetan Rivet
` (2 subsequent siblings)
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Introduce the facility to process future PCI parameters.
Once the matching between PCI devices and devargs has been done, it is
possible to process each devargs. New parameters would have the PCI
device handle to work with when parsing the device (bus specific)
parameters.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
drivers/bus/pci/pci_common.c | 3 +++
drivers/bus/pci/pci_params.c | 7 +++++++
drivers/bus/pci/private.h | 13 +++++++++++++
3 files changed, 23 insertions(+)
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index c7695d108..900cd9090 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -247,6 +247,9 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
if (dev->driver != NULL)
return 0;
+ if (rte_pci_devargs_process(dev) < 0)
+ return -1;
+
FOREACH_DRIVER_ON_PCIBUS(dr) {
rc = rte_pci_probe_one_driver(dr, dev);
if (rc < 0)
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
index a09af3b1c..31143c845 100644
--- a/drivers/bus/pci/pci_params.c
+++ b/drivers/bus/pci/pci_params.c
@@ -127,3 +127,10 @@ rte_pci_devargs_prepare(struct rte_devargs *devargs)
rte_kvargs_free(kvargs);
return ret;
}
+
+int
+rte_pci_devargs_process(struct rte_pci_device *pdev __rte_unused)
+{
+ /* For the moment, no PCI param needs to be processed. */
+ return 0;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 9beb24c6a..06dc85e85 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -207,4 +207,17 @@ rte_pci_dev_iterate(const void *start,
int
rte_pci_devargs_prepare(struct rte_devargs *da);
+/*
+ * Process the device devargs, if any.
+ *
+ * @param pdev
+ * PCI device
+ *
+ * @return
+ * 0 on success.
+ * <0 on error.
+ */
+int
+rte_pci_devargs_process(struct rte_pci_device *pdev);
+
#endif /* _PCI_PRIVATE_H_ */
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 12/13] ethdev: process declarative eth devargs
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (10 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 11/13] bus/pci: process declarative PCI devargs Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-09-20 10:11 ` Andrew Rybchenko
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 13/13] eal: add generic dev parameter Gaetan Rivet
2018-10-03 12:31 ` [dpdk-dev] [PATCH v2 00/13] Implement new devargs framework Thomas Monjalon
13 siblings, 1 reply; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Process the eth parameters of a devargs.
For each parameters that have a setter implemented,
the relevant field in rte_eth_dev field is written.
Currently only "name" is implemented.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_ethdev/ethdev_private.h | 5 +++
lib/librte_ethdev/rte_class_eth.c | 72 ++++++++++++++++++++++++++++++
lib/librte_ethdev/rte_ethdev.c | 7 +++
3 files changed, 84 insertions(+)
diff --git a/lib/librte_ethdev/ethdev_private.h b/lib/librte_ethdev/ethdev_private.h
index 0f5c6d5c4..c0c065165 100644
--- a/lib/librte_ethdev/ethdev_private.h
+++ b/lib/librte_ethdev/ethdev_private.h
@@ -19,6 +19,11 @@ struct rte_eth_dev *
eth_find_device(const struct rte_eth_dev *_start, rte_eth_cmp_t cmp,
const void *data);
+/* Generic rte_eth_dev parameters processor. */
+int
+rte_eth_dev_args_parse(struct rte_eth_dev *eth_dev,
+ struct rte_devargs *da);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 66fd48dc2..7a8b81423 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -6,9 +6,11 @@
#include <rte_class.h>
#include <rte_compat.h>
+#include <rte_devargs.h>
#include <rte_errno.h>
#include <rte_kvargs.h>
#include <rte_log.h>
+#include <rte_string_fns.h>
#include "rte_ethdev.h"
#include "rte_ethdev_core.h"
@@ -35,6 +37,19 @@ struct eth_dev_match_arg {
.kvlist = (k), \
})
+typedef int (*eth_dev_set_t)(struct rte_eth_dev *edev, const char *value);
+
+static enum eth_params
+ethdev_param_id(const char *key)
+{
+ int i;
+
+ for (i = 0; i < RTE_ETH_PARAMS_MAX; i++)
+ if (strcmp(key, eth_params_keys[i]) == 0)
+ return i;
+ return RTE_ETH_PARAMS_MAX;
+}
+
static int
eth_dev_match(const struct rte_eth_dev *edev,
const void *_arg)
@@ -79,6 +94,63 @@ eth_dev_iterate(const void *start,
return edev;
}
+static int
+eth_dev_set_name(struct rte_eth_dev *edev,
+ const char *value)
+{
+ size_t n;
+
+ n = strlcpy(edev->data->name, value,
+ sizeof(edev->data->name));
+
+ /* Name was truncated. */
+ if (n >= sizeof(edev->data->name)) {
+ RTE_LOG(ERR, EAL, "Name %s is too long\n", value);
+ return -1;
+ }
+ return 0;
+}
+
+static int
+ethdev_args_process(const char *key,
+ const char *value,
+ void *_edev)
+{
+ static eth_dev_set_t eth_dev_set[] = {
+ [RTE_ETH_PARAMS_NAME] = eth_dev_set_name,
+ [RTE_ETH_PARAMS_MAX] = NULL,
+ };
+ struct rte_eth_dev *edev = _edev;
+ int param;
+
+ param = ethdev_param_id(key);
+ if (eth_dev_set[param])
+ return eth_dev_set[param](edev, value);
+ return 0;
+}
+
+int
+rte_eth_dev_args_parse(struct rte_eth_dev *edev,
+ struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvargs = NULL;
+ int ret;
+
+ if (devargs == NULL || devargs->cls_str == NULL)
+ return 0;
+
+ kvargs = rte_kvargs_parse_delim(devargs->cls_str, eth_params_keys, "/");
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "cannot parse argument list\n");
+ return -EINVAL;
+ }
+ ret = rte_kvargs_process(kvargs, NULL, ethdev_args_process, edev);
+ rte_kvargs_free(kvargs);
+ if (ret != 0)
+ return -1;
+ return 0;
+}
+
struct rte_class rte_class_eth = {
.dev_iterate = eth_dev_iterate,
};
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index aa7730ce2..b03fe7f4b 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -41,6 +41,7 @@
#include "rte_ethdev.h"
#include "rte_ethdev_driver.h"
#include "ethdev_profile.h"
+#include "ethdev_private.h"
int rte_eth_dev_logtype;
@@ -3504,6 +3505,12 @@ rte_eth_dev_create(struct rte_device *device, const char *name,
}
}
+ retval = rte_eth_dev_args_parse(ethdev, device->devargs);
+ if (retval) {
+ RTE_LOG(ERR, EAL, "ethdev parsing failed");
+ goto probe_failed;
+ }
+
retval = ethdev_init(ethdev, init_params);
if (retval) {
RTE_LOG(ERR, EAL, "ethdev initialisation failed");
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* [dpdk-dev] [PATCH v2 13/13] eal: add generic dev parameter
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (11 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 12/13] ethdev: process declarative eth devargs Gaetan Rivet
@ 2018-09-19 16:03 ` Gaetan Rivet
2018-10-03 12:31 ` [dpdk-dev] [PATCH v2 00/13] Implement new devargs framework Thomas Monjalon
13 siblings, 0 replies; 47+ messages in thread
From: Gaetan Rivet @ 2018-09-19 16:03 UTC (permalink / raw)
To: dev; +Cc: Gaetan Rivet
Add the --dev parameter to the EAL.
This new parameter takes a generic device declaration as argument.
It uses the new devargs parsing API.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_eal/common/eal_common_devargs.c | 4 +++
lib/librte_eal/common/eal_common_options.c | 36 +++++++++++++++++++---
lib/librte_eal/common/eal_options.h | 2 ++
3 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index dac2402a4..f1f4628db 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -219,6 +219,10 @@ rte_devargs_parse(struct rte_devargs *da, const char *dev)
if (da == NULL)
return -EINVAL;
+ if (strncmp(dev, "bus=", 4) == 0 ||
+ strncmp(dev, "class=", 6) == 0)
+ return rte_devargs_layers_parse(da, dev);
+
/* Retrieve eventual bus info */
do {
devname = dev;
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index ddd624110..703932a30 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -54,6 +54,7 @@ const struct option
eal_long_options[] = {
{OPT_BASE_VIRTADDR, 1, NULL, OPT_BASE_VIRTADDR_NUM },
{OPT_CREATE_UIO_DEV, 0, NULL, OPT_CREATE_UIO_DEV_NUM },
+ {OPT_DEV, 1, NULL, OPT_DEV_NUM },
{OPT_FILE_PREFIX, 1, NULL, OPT_FILE_PREFIX_NUM },
{OPT_HELP, 0, NULL, OPT_HELP_NUM },
{OPT_HUGE_DIR, 1, NULL, OPT_HUGE_DIR_NUM },
@@ -111,6 +112,7 @@ TAILQ_HEAD(device_option_list, device_option);
struct device_option {
TAILQ_ENTRY(device_option) next;
+ int new;
enum rte_devtype type;
char arg[];
};
@@ -123,7 +125,8 @@ static int mem_parsed;
static int core_parsed;
static int
-eal_option_device_add(enum rte_devtype type, const char *optarg)
+eal_option_device_add(enum rte_devtype type, const char *optarg,
+ int new)
{
struct device_option *devopt;
size_t optlen;
@@ -137,6 +140,7 @@ eal_option_device_add(enum rte_devtype type, const char *optarg)
}
devopt->type = type;
+ devopt->new = new;
ret = snprintf(devopt->arg, optlen, "%s", optarg);
if (ret < 0) {
RTE_LOG(ERR, EAL, "Unable to copy device option\n");
@@ -156,7 +160,22 @@ eal_option_device_parse(void)
TAILQ_FOREACH_SAFE(devopt, &devopt_list, next, tmp) {
if (ret == 0) {
- ret = rte_devargs_add(devopt->type, devopt->arg);
+ if (devopt->new) {
+ struct rte_devargs *da;
+
+ da = calloc(1, sizeof(*da));
+ ret = rte_devargs_parse(da, devopt->arg);
+ if (ret) {
+ free(da);
+ } else {
+ ret = rte_devargs_insert(da);
+ if (ret)
+ free(da);
+ }
+ } else {
+ ret = rte_devargs_add(devopt->type,
+ devopt->arg);
+ }
if (ret)
RTE_LOG(ERR, EAL, "Unable to parse device '%s'\n",
devopt->arg);
@@ -1088,7 +1107,7 @@ eal_parse_common_option(int opt, const char *optarg,
if (w_used)
goto bw_used;
if (eal_option_device_add(RTE_DEVTYPE_BLACKLISTED_PCI,
- optarg) < 0) {
+ optarg, 0) < 0) {
return -1;
}
b_used = 1;
@@ -1098,7 +1117,7 @@ eal_parse_common_option(int opt, const char *optarg,
if (b_used)
goto bw_used;
if (eal_option_device_add(RTE_DEVTYPE_WHITELISTED_PCI,
- optarg) < 0) {
+ optarg, 0) < 0) {
return -1;
}
w_used = 1;
@@ -1234,9 +1253,16 @@ eal_parse_common_option(int opt, const char *optarg,
}
break;
+ case OPT_DEV_NUM:
+ /* devtype is meaningless in the new format. */
+ if (eal_option_device_add(0, optarg, 1) < 0) {
+ return -1;
+ }
+ break;
+
case OPT_VDEV_NUM:
if (eal_option_device_add(RTE_DEVTYPE_VIRTUAL,
- optarg) < 0) {
+ optarg, 0) < 0) {
return -1;
}
break;
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index 96e166787..8a17eb22c 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -21,6 +21,8 @@ enum {
OPT_BASE_VIRTADDR_NUM,
#define OPT_CREATE_UIO_DEV "create-uio-dev"
OPT_CREATE_UIO_DEV_NUM,
+#define OPT_DEV "dev"
+ OPT_DEV_NUM,
#define OPT_FILE_PREFIX "file-prefix"
OPT_FILE_PREFIX_NUM,
#define OPT_HUGE_DIR "huge-dir"
--
2.18.0
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v2 00/13] Implement new devargs framework
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 " Gaetan Rivet
` (12 preceding siblings ...)
2018-09-19 16:03 ` [dpdk-dev] [PATCH v2 13/13] eal: add generic dev parameter Gaetan Rivet
@ 2018-10-03 12:31 ` Thomas Monjalon
2020-02-19 5:43 ` Pavan Nikhilesh Bhagavatula
13 siblings, 1 reply; 47+ messages in thread
From: Thomas Monjalon @ 2018-10-03 12:31 UTC (permalink / raw)
To: Gaetan Rivet; +Cc: dev, Shreyansh Jain, Andrew Rybchenko
19/09/2018 18:03, Gaetan Rivet:
> Last release saw the introduction of the new devargs system.
> To this end, the "class" abstraction was described as well
> as a common API for querying and declaring devices.
>
> This patchset implements the "eth" device class and the
> query/declaration part of the framework for PCI and vdev buses,
> enabling a minimal support for the new system.
This part of the patchset is applied
(except patches 4 and 7 that were discussed).
> A new testpmd command is added to test device querying.
>
> Devargs parsing is extended in the relevant buses to test
> device declaration. This part uses the new "rte_eth_dev_create" API,
> introduced last release and used by only two PMDs, for now.
>
> The new devargs format is also made available through the new --dev parameter.
This second part of the patchset is left for next release.
> Next work is to generalize use of new API for eth_dev creation,
> compatibility layer for -w, -b and --vdev with --dev, and devargs unit test.
I think it's better to wait having the new devargs usable in these options,
so we will have more tests and feedbacks.
> Gaetan Rivet (13):
> bus/pci: implement device iteration and comparison
> bus/pci: add device matching field id
> bus/vdev: implement device iteration
> bus/vdev: add device matching field driver
> ethdev: add private generic device iterator
> ethdev: register ether layer as a class
> ethdev: add device matching field name
> app/testpmd: add show device command
> bus/pci: pre-process declarative PCI devargs
> bus/vdev: pre-process declarative vdev devargs
> bus/pci: process declarative PCI devargs
> ethdev: process declarative eth devargs
> eal: add generic dev parameter
Summary: for 18.11, patches 1, 2, 3, 5, 6 are applied, thanks!
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [dpdk-dev] [PATCH v2 00/13] Implement new devargs framework
2018-10-03 12:31 ` [dpdk-dev] [PATCH v2 00/13] Implement new devargs framework Thomas Monjalon
@ 2020-02-19 5:43 ` Pavan Nikhilesh Bhagavatula
0 siblings, 0 replies; 47+ messages in thread
From: Pavan Nikhilesh Bhagavatula @ 2020-02-19 5:43 UTC (permalink / raw)
To: Thomas Monjalon, Gaetan Rivet; +Cc: dev, Shreyansh Jain, Andrew Rybchenko
@Thomas Monjalon, Ping?. Some parts of this patch set was scheduled for 19.02.
>-----Original Message-----
>From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
>Sent: Wednesday, October 3, 2018 6:02 PM
>To: Gaetan Rivet <gaetan.rivet@6wind.com>
>Cc: dev@dpdk.org; Shreyansh Jain <shreyansh.jain@nxp.com>;
>Andrew Rybchenko <arybchenko@solarflare.com>
>Subject: Re: [dpdk-dev] [PATCH v2 00/13] Implement new devargs
>framework
>
>External Email
>
>19/09/2018 18:03, Gaetan Rivet:
>> Last release saw the introduction of the new devargs system.
>> To this end, the "class" abstraction was described as well
>> as a common API for querying and declaring devices.
>>
>> This patchset implements the "eth" device class and the
>> query/declaration part of the framework for PCI and vdev buses,
>> enabling a minimal support for the new system.
>
>This part of the patchset is applied
>(except patches 4 and 7 that were discussed).
>
>> A new testpmd command is added to test device querying.
>>
>> Devargs parsing is extended in the relevant buses to test
>> device declaration. This part uses the new "rte_eth_dev_create" API,
>> introduced last release and used by only two PMDs, for now.
>>
>> The new devargs format is also made available through the new --dev
>parameter.
>
>This second part of the patchset is left for next release.
>
>> Next work is to generalize use of new API for eth_dev creation,
>> compatibility layer for -w, -b and --vdev with --dev, and devargs unit
>test.
>
>I think it's better to wait having the new devargs usable in these
>options,
>so we will have more tests and feedbacks.
>
>> Gaetan Rivet (13):
>> bus/pci: implement device iteration and comparison
>> bus/pci: add device matching field id
>> bus/vdev: implement device iteration
>> bus/vdev: add device matching field driver
>> ethdev: add private generic device iterator
>> ethdev: register ether layer as a class
>> ethdev: add device matching field name
>> app/testpmd: add show device command
>> bus/pci: pre-process declarative PCI devargs
>> bus/vdev: pre-process declarative vdev devargs
>> bus/pci: process declarative PCI devargs
>> ethdev: process declarative eth devargs
>> eal: add generic dev parameter
>
>Summary: for 18.11, patches 1, 2, 3, 5, 6 are applied, thanks!
>
^ permalink raw reply [flat|nested] 47+ messages in thread