All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Introduce net bus
@ 2017-06-01 10:44 Gaetan Rivet
  2017-06-01 10:44 ` [PATCH 1/3] bus/net: introduce " Gaetan Rivet
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-01 10:44 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This new bus takes as devices kernel netdevices.
It offers an API for drivers to register a translation layer that would
transform the netdev name to one their regular PMD would be able to
probe.

This is PoC. It currently only works for MLX4 and MLX5 PMDs as they were
bifurcated and had very little work to do otherwise.

The planned feature is for at least all PCI drivers, be able to unbind
the device from its kmod and bind it to a choosen IO module, prior to
probing.

Additional possible feature would be a close integration with eventually
NCI-like lib, to transparently capture kernel devices, keep a control
interface present and bind / unbind the underlying hardware function as
necessary.

This bus depends on plug / unplug being implemented for the sub-bus
(here, PCI or vdev). If new buses wants to be able to capture kernel
netdevices this way, they should implement plug / unplug.

This patchset depends on:

[PATCH 0/8] bus/pci: remove PCI bus from EAL
http://dpdk.org/dev/patchwork/patch/24972/
http://dpdk.org/ml/archives/dev/2017-June/067061.html

Gaetan Rivet (3):
  bus/net: introduce net bus
  net/mlx4: net bus support
  net/mlx5: net bus support

 MAINTAINERS                                   |   6 +
 config/common_linuxapp                        |   2 +
 drivers/bus/Makefile                          |   2 +
 drivers/bus/net/Makefile                      |  66 +++++++
 drivers/bus/net/bsd/Makefile                  |  33 ++++
 drivers/bus/net/include/rte_bus_net.h         | 145 ++++++++++++++++
 drivers/bus/net/linux/Makefile                |  35 ++++
 drivers/bus/net/linux/rte_bus_net.c           | 237 ++++++++++++++++++++++++++
 drivers/bus/net/linux/rte_bus_net_version.map |   5 +
 drivers/bus/net/private.h                     | 143 ++++++++++++++++
 drivers/bus/net/rte_bus_net.c                 | 210 +++++++++++++++++++++++
 drivers/net/mlx4/mlx4.c                       |  10 ++
 drivers/net/mlx5/mlx5.c                       |  10 ++
 mk/rte.app.mk                                 |   1 +
 14 files changed, 905 insertions(+)
 create mode 100644 drivers/bus/net/Makefile
 create mode 100644 drivers/bus/net/bsd/Makefile
 create mode 100644 drivers/bus/net/include/rte_bus_net.h
 create mode 100644 drivers/bus/net/linux/Makefile
 create mode 100644 drivers/bus/net/linux/rte_bus_net.c
 create mode 100644 drivers/bus/net/linux/rte_bus_net_version.map
 create mode 100644 drivers/bus/net/private.h
 create mode 100644 drivers/bus/net/rte_bus_net.c

-- 
2.1.4

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

* [PATCH 1/3] bus/net: introduce net bus
  2017-06-01 10:44 [PATCH 0/3] Introduce net bus Gaetan Rivet
@ 2017-06-01 10:44 ` Gaetan Rivet
  2017-06-01 10:44 ` [PATCH 2/3] net/mlx4: net bus support Gaetan Rivet
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-01 10:44 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 MAINTAINERS                                   |   6 +
 config/common_linuxapp                        |   2 +
 drivers/bus/Makefile                          |   2 +
 drivers/bus/net/Makefile                      |  66 +++++++
 drivers/bus/net/bsd/Makefile                  |  33 ++++
 drivers/bus/net/include/rte_bus_net.h         | 145 ++++++++++++++++
 drivers/bus/net/linux/Makefile                |  35 ++++
 drivers/bus/net/linux/rte_bus_net.c           | 237 ++++++++++++++++++++++++++
 drivers/bus/net/linux/rte_bus_net_version.map |   5 +
 drivers/bus/net/private.h                     | 143 ++++++++++++++++
 drivers/bus/net/rte_bus_net.c                 | 210 +++++++++++++++++++++++
 mk/rte.app.mk                                 |   1 +
 12 files changed, 885 insertions(+)
 create mode 100644 drivers/bus/net/Makefile
 create mode 100644 drivers/bus/net/bsd/Makefile
 create mode 100644 drivers/bus/net/include/rte_bus_net.h
 create mode 100644 drivers/bus/net/linux/Makefile
 create mode 100644 drivers/bus/net/linux/rte_bus_net.c
 create mode 100644 drivers/bus/net/linux/rte_bus_net_version.map
 create mode 100644 drivers/bus/net/private.h
 create mode 100644 drivers/bus/net/rte_bus_net.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9f9b81b..67288c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -253,6 +253,12 @@ F: lib/librte_eventdev/
 F: drivers/event/skeleton/
 F: test/test/test_eventdev.c
 
+Bus Drivers
+-----------
+
+Net
+M: Gaetan Rivet <gaetan.rivet@6wind.com>
+F: drivers/bus/net/
 
 Networking Drivers
 ------------------
diff --git a/config/common_linuxapp b/config/common_linuxapp
index cc85cc6..fe13f38 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -48,3 +48,5 @@ CONFIG_RTE_LIBRTE_AVP_PMD=y
 CONFIG_RTE_LIBRTE_NFP_PMD=y
 CONFIG_RTE_LIBRTE_POWER=y
 CONFIG_RTE_VIRTIO_USER=y
+CONFIG_RTE_LIBRTE_NET_BUS=y
+CONFIG_RTE_LIBRTE_NET_BUS_DEBUG=n
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 1d1ddae..26cb9e2 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -37,5 +37,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
 DEPDIRS-pci = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_NET_BUS) += net
+DEPDIRS-net = $(core-libs) pci
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/net/Makefile b/drivers/bus/net/Makefile
new file mode 100644
index 0000000..a643ab0
--- /dev/null
+++ b/drivers/bus/net/Makefile
@@ -0,0 +1,66 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   Author: Gaetan Rivet
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_net.a
+LIBABIVER := 1
+
+CFLAGS += $(WERROR_FLAGS)
+ifeq ($(DEBUG),1)
+CONFIG_RTE_LIBRTE_NET_BUS_DEBUG := y
+endif
+ifeq ($(CONFIG_RTE_LIBRTE_NET_BUS_DEBUG),y)
+CFLAGS += -UNDEBUG -g -O0
+else
+CFLAGS += -DNDEBUG -O3
+endif
+CFLAGS += -I$(RTE_SDK)/drivers/bus/net
+CFLAGS += -I$(RTE_SDK)/drivers/bus/net/include
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BDSAPP),)
+SYSTEM := bsd
+endif
+
+EXPORT_MAP := $(SYSTEM)/rte_bus_net_version.map
+CFLAGS += -I$(RTE_SDK)/drivers/bus/net/$(SYSTEM)
+
+include $(RTE_SDK)/drivers/bus/net/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_NET_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_NET_BUS) += rte_bus_net.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_net.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/net/bsd/Makefile b/drivers/bus/net/bsd/Makefile
new file mode 100644
index 0000000..435ef57
--- /dev/null
+++ b/drivers/bus/net/bsd/Makefile
@@ -0,0 +1,33 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   Author: Gaetan Rivet
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+$(error Net BUS not supported on BSD yet)
diff --git a/drivers/bus/net/include/rte_bus_net.h b/drivers/bus/net/include/rte_bus_net.h
new file mode 100644
index 0000000..38b345e
--- /dev/null
+++ b/drivers/bus/net/include/rte_bus_net.h
@@ -0,0 +1,145 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A.
+ *   Author: Gaetan Rivet
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_NET_BUS_H_
+#define _RTE_NET_BUS_H_
+
+#include <sys/queue.h>
+#include <stdint.h>
+
+#include <rte_devargs.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+/**
+ * @file
+ *
+ * RTE Net bus.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Name of net bus. */
+#define RTE_BUS_NET_NAME "net"
+
+/**
+ * Structure describing an RTE net device.
+ */
+struct rte_net_device {
+	TAILQ_ENTRY(rte_net_device) next; /**< Next net device. */
+	struct rte_device device; /**< Inherit core device. */
+	struct rte_net_driver *driver; /**< Associated driver. */
+	struct rte_devargs *da; /**< Device parameters. */
+	struct rte_device *sh_dev; /**< Shadow device. */
+	char name[33]; /**< Kernel netdev name. */
+};
+
+/**
+ * Name transform callback.
+ * Transform a netdevice name into its DPDK counterpart.
+ *
+ * @param[in] name
+ *   kernel device name.
+ *
+ * @param[out] rte_name
+ *   DPDK device name.
+ *
+ * @param[in] size
+ *   size of rte_name.
+ *
+ * @return
+ *   0 for no error.
+ *   !0 otherwise.
+ */
+typedef int (*rte_bus_net_xfrm_t)(const char *name, char *rte_name, size_t size);
+
+/**
+ * Name transform base implementations.
+ */
+int rte_bus_net_virtual_xfrm(const char *name, char *rte_name, size_t size);
+int rte_bus_net_pci_xfrm(const char *name, char *rte_name, size_t size);
+
+/**
+ * Structure describing an RTE net driver.
+ */
+struct rte_net_driver {
+	TAILQ_ENTRY(rte_net_driver) next; /**< Next net driver. */
+	struct rte_driver driver; /**< Inherit core driver. */
+	struct rte_driver *sh_drv; /**< Shadow driver. */
+	char kmod[33]; /**< Kernel driver name. */
+	rte_bus_net_xfrm_t xfrm; /**< Name transform. */
+};
+
+/**
+ * Register a net driver.
+ *
+ * @param driver
+ *   A pointer to an rte_net_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_net_register(struct rte_net_driver *driver);
+
+/** Helper for net device registration from driver instance. */
+#define RTE_PMD_REGISTER_NET(nm, net_drv) \
+RTE_INIT(netinitfn_ ##nm); \
+static void netinitfn_ ##nm(void) \
+{ \
+	(net_drv).driver.name = RTE_STR(nm); \
+	RTE_VERIFY(net_drv.xfrm); \
+	rte_net_register(&net_drv); \
+} \
+RTE_PMD_EXPORT_NAME(netdev_ ##nm, __COUNTER__)
+
+#define RTE_BUS_NET_VDEV_HEADER \
+	.xfrm = rte_bus_net_virtual_xfrm,
+
+#define RTE_BUS_NET_PCI_HEADER \
+	.xfrm = rte_bus_net_pci_xfrm,
+
+/**
+ * Unregister a net driver.
+ *
+ * @param driver
+ *   A pointer to an rte_net_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_net_unregister(struct rte_net_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_NET_BUS_H_ */
diff --git a/drivers/bus/net/linux/Makefile b/drivers/bus/net/linux/Makefile
new file mode 100644
index 0000000..37af5fc
--- /dev/null
+++ b/drivers/bus/net/linux/Makefile
@@ -0,0 +1,35 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   Author: Gaetan Rivet
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += rte_bus_net.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/net/linux/rte_bus_net.c b/drivers/bus/net/linux/rte_bus_net.c
new file mode 100644
index 0000000..bd5c481
--- /dev/null
+++ b/drivers/bus/net/linux/rte_bus_net.c
@@ -0,0 +1,237 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A.
+ *   Author: Gaetan Rivet
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include <linux/limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rte_bus.h>
+
+#include "rte_bus_net.h"
+#include "private.h"
+
+/* Default path */
+const char SYSFS_NET_DEVICES[] = "/sys/class/net";
+
+int
+path_read(char *out, size_t size, const char *format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	char path[vsnprintf(NULL, 0, format, ap) + 1];
+	FILE *file;
+	int ret;
+	int err;
+
+	va_end(ap);
+	va_start(ap, format);
+	vsnprintf(path, sizeof(path), format, ap);
+	file = fopen(path, "rb");
+	if (file == NULL) {
+		ERROR("failed to open file %s (%s)",
+		      path, strerror(errno));
+		va_end(ap);
+		return -1;
+	}
+	ret = fread(out, size, 1, file);
+	err = errno;
+	if (((size_t)ret < size) && (ferror(file))) {
+		va_end(ap);
+		ret = -1;
+	}
+	fclose(file);
+	errno = err;
+	va_end(ap);
+	return ret;
+}
+
+static int
+parse_u32(const char *val, uint32_t *out)
+{
+	char *end;
+	uint64_t tmp;
+
+	errno = 0;
+	tmp = strtoull(val, &end, 0);
+	if (errno != 0 || val[0] == '\0' || end == NULL)
+		return -EINVAL;
+	if (tmp > UINT32_MAX)
+		return -ERANGE;
+	*out = (uint32_t) tmp;
+	return 0;
+}
+
+static uint32_t
+dev_flags(const char *name)
+{
+	char buf[32] = "";
+	uint32_t val;
+
+	if (path_read(buf, sizeof(buf), "%s/%s/flags",
+			net_get_sysfs_path(), name)) {
+		ERROR("failed to read flags on device %s", name);
+		return 0;
+	}
+	if (parse_u32(buf, &val)) {
+		ERROR("failed to parse %s", buf);
+		return 0;
+	}
+	return val;
+}
+
+static int
+net_scan_one(const char *name)
+{
+	struct rte_net_device *dev;
+
+	dev = calloc(1, sizeof(*dev));
+	if (dev == NULL) {
+		ERROR("failed to allocate memory");
+		return -ENOMEM;
+	}
+	snprintf(dev->name, sizeof(dev->name), "%s", name);
+	if (!net_parse(dev->name, NULL))
+		INSERT_NET_DEVICE(dev);
+	return 0;
+}
+
+int
+net_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	const char *path;
+	int ret = 0;
+	int scan_blist = 0;
+
+	path = net_get_sysfs_path();
+	dir = opendir(path);
+	if (dir == NULL) {
+		ret = errno;
+		ERROR("opendir %s failed: %s", path, strerror(errno));
+		return -1;
+	}
+	if (rte_bus_net.conf.scan_mode == RTE_BUS_SCAN_BLACKLIST)
+		scan_blist = 1;
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+		if (dev_flags(e->d_name) & 0x8)
+			continue;
+		if (scan_blist ^
+		    !net_devargs_lookup(e->d_name))
+				continue;
+		ret = net_scan_one(e->d_name);
+		if (ret)
+			goto out;
+	}
+out:
+	closedir(dir);
+	return ret;
+}
+
+int
+net_dev_stat(const char *name)
+{
+	struct stat buf;
+	int err;
+	MKSTR(path, "%s/%s", net_get_sysfs_path(), name);
+
+	snprintf(path, sizeof(path), "%s/%s",
+		 net_get_sysfs_path(), name);
+	err = errno;
+	errno = 0;
+	if (stat(path, &buf)) {
+		if (errno != ENOENT)
+			ERROR("stat(%s) failed: %s", path, strerror(errno));
+		errno = err;
+		return -1;
+	}
+	return 0;
+}
+
+static int
+link_read(const char *path, char *out, size_t size)
+{
+	struct stat buf;
+	int err;
+
+	err = errno;
+	errno = 0;
+	if (stat(path, &buf)) {
+		if (errno != ENOENT)
+			ERROR("stat(%s) failed: %s", path, strerror(errno));
+		errno = err;
+		return -1;
+	}
+	if (size > 0) {
+		char buf[PATH_MAX + 1] = "";
+		ssize_t wlen;
+		char *s;
+
+		wlen = readlink(path, buf, sizeof(buf) - 1);
+		if (wlen > 0) {
+			out[wlen] = '\0';
+		} else {
+			ERROR("readlink(%s) failed: %s", path,
+			      strerror(errno));
+			errno = err;
+			return -1;
+		}
+		for (s = &buf[wlen]; *s != '/'; s--);
+		snprintf(out, size, "%s", &s[1]);
+	}
+	return 0;
+}
+
+int
+net_dev_driver(const char *name, char *out, size_t size)
+{
+	MKSTR(path, "%s/%s/device/driver", net_get_sysfs_path(), name);
+
+	return link_read(path, out, size);
+}
+
+int
+net_dev_pci_loc(const char *name, char *out, size_t size)
+{
+	MKSTR(path, "%s/%s/device", net_get_sysfs_path(), name);
+
+	return link_read(path, out, size);
+}
diff --git a/drivers/bus/net/linux/rte_bus_net_version.map b/drivers/bus/net/linux/rte_bus_net_version.map
new file mode 100644
index 0000000..2b933d6
--- /dev/null
+++ b/drivers/bus/net/linux/rte_bus_net_version.map
@@ -0,0 +1,5 @@
+DPDK_17.08 {
+	global:
+
+	local: *;
+};
diff --git a/drivers/bus/net/private.h b/drivers/bus/net/private.h
new file mode 100644
index 0000000..4015ddf
--- /dev/null
+++ b/drivers/bus/net/private.h
@@ -0,0 +1,143 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A.
+ *   Author: Gaetan Rivet
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NET_PRIVATE_H_
+#define _NET_PRIVATE_H_
+
+#include <sys/queue.h>
+
+#include <rte_bus.h>
+
+#include "rte_bus_net.h"
+
+/* Double linked list of devices. */
+TAILQ_HEAD(net_device_list, rte_net_device);
+/* Double linked list of drivers. */
+TAILQ_HEAD(net_driver_list, rte_net_driver);
+
+extern struct net_device_list net_device_list;
+extern struct net_driver_list net_driver_list;
+
+/* Bus handle. */
+extern struct rte_bus rte_bus_net;
+
+/** Default net devices path. */
+extern const char SYSFS_NET_DEVICES[];
+
+/* Find the rte_net_driver of a kernel device. */
+struct rte_net_driver *net_drv_find(const char *name);
+
+/* Parse device name. */
+int net_parse(const char *name, void *addr);
+
+/* Scan sysfs. */
+int net_scan(void);
+
+/* Get netdev status. */
+int net_dev_stat(const char *name);
+
+/* Get netdev driver name. */
+int net_dev_driver(const char *name, char *out, size_t size);
+
+/* Get netdev pci location */
+int net_dev_pci_loc(const char *name, char *out, size_t size);
+
+/* Get sysfs path. */
+const char *net_get_sysfs_path(void);
+
+/* Find devargs of a device. */
+struct rte_devargs *net_devargs_lookup(const char *name);
+
+/* Read file content. */
+int path_read(char *out, size_t size, const char *format, ...)
+	__attribute__((format(printf, 3, 0)));
+
+/* Net Bus iterators. */
+#define FOREACH_NET_DEVICE(p) \
+	TAILQ_FOREACH(p, &(net_device_list), next)
+
+#define FOREACH_NET_DRIVER(p) \
+	TAILQ_FOREACH(p, &(net_driver_list), next)
+
+/* Net lists operators. */
+#define INSERT_NET_DEVICE(dev) \
+	TAILQ_INSERT_TAIL(&net_device_list, dev, next)
+
+#define REMOVE_NET_DEVICE(dev) \
+	TAILQ_REMOVE(&net_device_list, dev, next)
+
+#define INSERT_NET_DRIVER(drv) \
+	TAILQ_INSERT_TAIL(&net_driver_list, drv, next)
+
+#define REMOVE_NET_DRIVER(drv) \
+	TAILQ_REMOVE(&net_driver_list, drv, next)
+
+/* Debugging */
+#ifndef NDEBUG
+#include <stdio.h>
+#define DEBUG__(m, ...)						\
+	(fprintf(stderr, "%s:%d: %s(): " m "%c",		\
+		 __FILE__, __LINE__, __func__, __VA_ARGS__),	\
+	 fflush(stderr),					\
+	 (void)0)
+/*
+ * Save/restore errno around DEBUG__().
+ * XXX somewhat undefined behavior, but works.
+ */
+#define DEBUG_(...)				\
+	(errno = ((int []){			\
+		*(volatile int *)&errno,	\
+		(DEBUG__(__VA_ARGS__), 0)	\
+	})[0])
+#define DEBUG(...) DEBUG_(__VA_ARGS__, '\n')
+#define INFO(...) DEBUG(__VA_ARGS__)
+#define WARN(...) DEBUG(__VA_ARGS__)
+#define ERROR(...) DEBUG(__VA_ARGS__)
+#else /* NDEBUG */
+#define LOG__(level, m, ...) \
+	RTE_LOG(level, EAL, "NET: " m "%c", __VA_ARGS__)
+#define LOG_(level, ...) LOG__(level, __VA_ARGS__, '\n')
+#define DEBUG(...) (void)0
+#define INFO(...) LOG_(INFO, __VA_ARGS__)
+#define WARN(...) LOG_(WARNING, "WARNING: " __VA_ARGS__)
+#define ERROR(...) LOG_(ERR, "ERROR: " __VA_ARGS__)
+#endif /* NDEBUG */
+
+/* Allocate a buffer on the stack and fill it with a printf format string. */
+#define MKSTR(name, ...) \
+	char name[snprintf(NULL, 0, __VA_ARGS__) + 1]; \
+	\
+	snprintf(name, sizeof(name), __VA_ARGS__)
+
+#endif /* _NET_PRIVATE_H_ */
diff --git a/drivers/bus/net/rte_bus_net.c b/drivers/bus/net/rte_bus_net.c
new file mode 100644
index 0000000..c8da7b2
--- /dev/null
+++ b/drivers/bus/net/rte_bus_net.c
@@ -0,0 +1,210 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A.
+ *   Author: Gaetan Rivet
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#include <rte_devargs.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+#include "rte_bus_net.h"
+#include "private.h"
+
+struct net_device_list net_device_list =
+	TAILQ_HEAD_INITIALIZER(net_device_list);
+struct net_driver_list net_driver_list =
+	TAILQ_HEAD_INITIALIZER(net_driver_list);
+
+struct rte_devargs *
+net_devargs_lookup(const char *name)
+{
+	struct rte_devargs *da;
+
+	TAILQ_FOREACH(da, &devargs_list, next) {
+		if (da->bus != &rte_bus_net)
+			continue;
+		if (!strcmp(da->name, name))
+			return da;
+	}
+	return NULL;
+}
+
+struct rte_net_driver *
+net_drv_find(const char *name)
+{
+	struct rte_net_driver *drv = NULL;
+	char drv_kmod[32] = "";
+
+	if (net_dev_driver(name, drv_kmod, sizeof(drv_kmod)))
+		return NULL;
+	FOREACH_NET_DRIVER(drv)
+		if (!strcmp(drv->kmod, drv_kmod))
+			break;
+	return drv;
+}
+
+/*
+ * typeof(addr): struct rte_devargs *
+ */
+int
+net_parse(const char *name, void *addr)
+{
+	struct rte_devargs *out = addr;
+	struct rte_net_driver *drv = NULL;
+
+	if (net_dev_stat(name))
+		return 1;
+	if (addr == NULL)
+		return 0;
+	drv = net_drv_find(name);
+	if (drv) {
+		struct rte_devargs *da;
+
+		da = net_devargs_lookup(name);
+		if (drv->xfrm(name, out->name, sizeof(out->name)))
+			return 1;
+		out->args = da->args;
+		out->bus = rte_bus_from_dev(out->name);
+		return !out->bus;
+	}
+	/* no match ! */
+	return 1;
+}
+
+static int
+net_probe_one(struct rte_net_device *dev)
+{
+	struct rte_devargs *da;
+	struct rte_bus *bus;
+
+	da = calloc(1, sizeof(*da));
+	if (da == NULL) {
+		ERROR("failed to allocate devargs for device %s",
+		      dev->name);
+		return -1;
+	}
+	if (net_parse(dev->name, da)) {
+		ERROR("unable to find DPKD handler for device %s", dev->name);
+		return -1;
+	}
+	bus = da->bus;
+	if (bus->plug == NULL) {
+		ERROR("bus %s does not support plugin", bus->name);
+		return -1;
+	}
+	return bus->plug(da);
+}
+
+static int
+net_probe(void)
+{
+	struct rte_net_device *dev;
+	int ret;
+
+	FOREACH_NET_DEVICE(dev) {
+		ret = net_probe_one(dev);
+		if (ret < 0)
+			return ret;
+	}
+	return 0;
+}
+
+static struct rte_device *
+net_find_device(int (*match)(const struct rte_device *dev, const void *data),
+		const void *data)
+{
+	struct rte_net_device *dev;
+
+	FOREACH_NET_DEVICE(dev)
+		if (match(&dev->device, data))
+			return &dev->device;
+	return NULL;
+}
+
+void
+rte_net_register(struct rte_net_driver *driver)
+{
+	INSERT_NET_DRIVER(driver);
+}
+
+void
+rte_net_unregister(struct rte_net_driver *driver)
+{
+	REMOVE_NET_DRIVER(driver);
+}
+
+const char *
+net_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_NET_DEVICES");
+	if (path == NULL)
+		return SYSFS_NET_DEVICES;
+	return path;
+}
+
+int
+rte_bus_net_virtual_xfrm(const char *name, char *rte_name, size_t size)
+{
+	int ret;
+
+	ret = snprintf(rte_name, size, "net_tap_%s,iface=tap_%s,remote=%s",
+		       name, name, name);
+	return ret < 0 || ret > (int)size;
+}
+
+int
+rte_bus_net_pci_xfrm(const char *name, char *rte_name, size_t size)
+{
+	char buf[32] = "";
+	int ret;
+
+	ret = net_dev_pci_loc(name, buf, sizeof(buf));
+	if (ret)
+		return ret;
+	ret = snprintf(rte_name, size, "%s", buf);
+	return ret < 0 || ret > (int)size;
+}
+
+struct rte_bus rte_bus_net = {
+	.scan = net_scan,
+	.probe = net_probe,
+	.find_device = net_find_device,
+	.parse = net_parse,
+	.conf = {
+		.scan_mode = RTE_BUS_SCAN_UNDEFINED,
+	},
+};
+RTE_REGISTER_BUS(RTE_BUS_NET_NAME, rte_bus_net);
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d476068..22e4222 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -104,6 +104,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+_LDLIBS-$(CONFIG_RTE_LIBRTE_NET_BUS)        += -lrte_bus_net
 
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
-- 
2.1.4

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

* [PATCH 2/3] net/mlx4: net bus support
  2017-06-01 10:44 [PATCH 0/3] Introduce net bus Gaetan Rivet
  2017-06-01 10:44 ` [PATCH 1/3] bus/net: introduce " Gaetan Rivet
@ 2017-06-01 10:44 ` Gaetan Rivet
  2017-06-01 10:44 ` [PATCH 3/3] net/mlx5: " Gaetan Rivet
  2017-06-08  0:00 ` [PATCH v2 0/4] Introduce net bus Gaetan Rivet
  3 siblings, 0 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-01 10:44 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/mlx4/mlx4.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ec4419a..705620a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -62,6 +62,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_dev.h>
+#include <rte_bus_net.h>
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_mempool.h>
@@ -6097,3 +6098,12 @@ RTE_PMD_EXPORT_NAME(net_mlx4, __COUNTER__);
 RTE_PMD_REGISTER_PCI_TABLE(net_mlx4, mlx4_pci_id_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_mlx4,
 	"* ib_uverbs & mlx4_en & mlx4_core & mlx4_ib");
+
+static struct rte_net_driver mlx4_net_driver = {
+	RTE_BUS_NET_PCI_HEADER
+	.driver = {
+		.name = MLX4_DRIVER_NAME,
+	},
+	.kmod = "mlx4_core",
+};
+RTE_PMD_REGISTER_NET(mlx4, mlx4_net_driver);
-- 
2.1.4

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

* [PATCH 3/3] net/mlx5: net bus support
  2017-06-01 10:44 [PATCH 0/3] Introduce net bus Gaetan Rivet
  2017-06-01 10:44 ` [PATCH 1/3] bus/net: introduce " Gaetan Rivet
  2017-06-01 10:44 ` [PATCH 2/3] net/mlx4: net bus support Gaetan Rivet
@ 2017-06-01 10:44 ` Gaetan Rivet
  2017-06-08  0:00 ` [PATCH v2 0/4] Introduce net bus Gaetan Rivet
  3 siblings, 0 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-01 10:44 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/mlx5/mlx5.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index fc99c0d..4e33703 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -58,6 +58,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_net.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 #ifdef PEDANTIC
@@ -898,3 +899,12 @@ rte_mlx5_pmd_init(void)
 RTE_PMD_EXPORT_NAME(net_mlx5, __COUNTER__);
 RTE_PMD_REGISTER_PCI_TABLE(net_mlx5, mlx5_pci_id_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_mlx5, "* ib_uverbs & mlx5_core & mlx5_ib");
+
+static struct rte_net_driver mlx5_net_driver = {
+	RTE_BUS_NET_PCI_HEADER
+	.driver = {
+		.name = MLX5_DRIVER_NAME,
+	},
+	.kmod = "mlx5_core",
+};
+RTE_PMD_REGISTER_NET(mlx5, mlx5_net_driver);
-- 
2.1.4

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

* [PATCH v2 0/4] Introduce net bus
  2017-06-01 10:44 [PATCH 0/3] Introduce net bus Gaetan Rivet
                   ` (2 preceding siblings ...)
  2017-06-01 10:44 ` [PATCH 3/3] net/mlx5: " Gaetan Rivet
@ 2017-06-08  0:00 ` Gaetan Rivet
  2017-06-08  0:00   ` [PATCH v2 1/4] bus/net: introduce " Gaetan Rivet
                     ` (4 more replies)
  3 siblings, 5 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-08  0:00 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet, Ferruh Yigit

This new bus takes as devices kernel netdevices.
It offers an API for drivers to register a translation layer that would
transform the netdev name to one their regular PMD would be able to
probe.

This is PoC. It currently only works for MLX4 and MLX5 PMDs as they were
bifurcated and had very little work to do otherwise.

The planned feature is for at least all PCI drivers, be able to unbind
the device from its kmod and bind it to a choosen IO module, prior to
probing.

Additional possible feature would be a close integration with eventually
NCI-like lib, to transparently capture kernel devices, keep a control
interface present and bind / unbind the underlying hardware function as
necessary.

This bus depends on plug / unplug being implemented for the sub-bus
(here, PCI or vdev). If new buses wants to be able to capture kernel
netdevices this way, they should implement plug / unplug.

This patchset depends on:

[PATCH 0/8] bus/pci: remove PCI bus from EAL
http://dpdk.org/dev/patchwork/patch/24972/
http://dpdk.org/ml/archives/dev/2017-June/067061.html

v1 --> v2:

  * New xfrm callback type.
  * System access helpers now exposed.
  * Fixes a log of edge-cases.
  * Better mlx4 support with phys port autodetect.
  * Support new plug / unplug API.
  * Fixes map files.

Gaetan Rivet (4):
  bus/net: introduce net bus
  bus/net: implement hotplug bus operations
  net/mlx4: net bus support
  net/mlx5: net bus support

 MAINTAINERS                                   |   6 +
 config/common_linuxapp                        |   2 +
 drivers/bus/Makefile                          |   2 +
 drivers/bus/net/Makefile                      |  66 ++++++
 drivers/bus/net/bsd/Makefile                  |  33 +++
 drivers/bus/net/bsd/rte_bus_net_version.map   |  14 ++
 drivers/bus/net/include/rte_bus_net.h         | 205 ++++++++++++++++
 drivers/bus/net/linux/Makefile                |  35 +++
 drivers/bus/net/linux/rte_bus_net.c           | 225 ++++++++++++++++++
 drivers/bus/net/linux/rte_bus_net_version.map |  14 ++
 drivers/bus/net/private.h                     | 144 ++++++++++++
 drivers/bus/net/rte_bus_net.c                 | 325 ++++++++++++++++++++++++++
 drivers/net/mlx4/mlx4.c                       |  35 +++
 drivers/net/mlx5/mlx5.c                       |   9 +
 mk/rte.app.mk                                 |   1 +
 15 files changed, 1116 insertions(+)
 create mode 100644 drivers/bus/net/Makefile
 create mode 100644 drivers/bus/net/bsd/Makefile
 create mode 100644 drivers/bus/net/bsd/rte_bus_net_version.map
 create mode 100644 drivers/bus/net/include/rte_bus_net.h
 create mode 100644 drivers/bus/net/linux/Makefile
 create mode 100644 drivers/bus/net/linux/rte_bus_net.c
 create mode 100644 drivers/bus/net/linux/rte_bus_net_version.map
 create mode 100644 drivers/bus/net/private.h
 create mode 100644 drivers/bus/net/rte_bus_net.c

-- 
2.1.4

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

* [PATCH v2 1/4] bus/net: introduce net bus
  2017-06-08  0:00 ` [PATCH v2 0/4] Introduce net bus Gaetan Rivet
@ 2017-06-08  0:00   ` Gaetan Rivet
  2017-06-08  0:00   ` [PATCH v2 2/4] bus/net: implement hotplug bus operations Gaetan Rivet
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-08  0:00 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 MAINTAINERS                                   |   6 +
 config/common_linuxapp                        |   2 +
 drivers/bus/Makefile                          |   2 +
 drivers/bus/net/Makefile                      |  66 +++++++
 drivers/bus/net/bsd/Makefile                  |  33 ++++
 drivers/bus/net/bsd/rte_bus_net_version.map   |  14 ++
 drivers/bus/net/include/rte_bus_net.h         | 205 ++++++++++++++++++++
 drivers/bus/net/linux/Makefile                |  35 ++++
 drivers/bus/net/linux/rte_bus_net.c           | 225 ++++++++++++++++++++++
 drivers/bus/net/linux/rte_bus_net_version.map |  14 ++
 drivers/bus/net/private.h                     | 144 ++++++++++++++
 drivers/bus/net/rte_bus_net.c                 | 265 ++++++++++++++++++++++++++
 mk/rte.app.mk                                 |   1 +
 13 files changed, 1012 insertions(+)
 create mode 100644 drivers/bus/net/Makefile
 create mode 100644 drivers/bus/net/bsd/Makefile
 create mode 100644 drivers/bus/net/bsd/rte_bus_net_version.map
 create mode 100644 drivers/bus/net/include/rte_bus_net.h
 create mode 100644 drivers/bus/net/linux/Makefile
 create mode 100644 drivers/bus/net/linux/rte_bus_net.c
 create mode 100644 drivers/bus/net/linux/rte_bus_net_version.map
 create mode 100644 drivers/bus/net/private.h
 create mode 100644 drivers/bus/net/rte_bus_net.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6d23022..c726322 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -253,6 +253,12 @@ F: lib/librte_eventdev/
 F: drivers/event/skeleton/
 F: test/test/test_eventdev.c
 
+Bus Drivers
+-----------
+
+Net
+M: Gaetan Rivet <gaetan.rivet@6wind.com>
+F: drivers/bus/net/
 
 Networking Drivers
 ------------------
diff --git a/config/common_linuxapp b/config/common_linuxapp
index cc85cc6..fe13f38 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -48,3 +48,5 @@ CONFIG_RTE_LIBRTE_AVP_PMD=y
 CONFIG_RTE_LIBRTE_NFP_PMD=y
 CONFIG_RTE_LIBRTE_POWER=y
 CONFIG_RTE_VIRTIO_USER=y
+CONFIG_RTE_LIBRTE_NET_BUS=y
+CONFIG_RTE_LIBRTE_NET_BUS_DEBUG=n
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 1d1ddae..26cb9e2 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -37,5 +37,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
 DEPDIRS-pci = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_NET_BUS) += net
+DEPDIRS-net = $(core-libs) pci
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/net/Makefile b/drivers/bus/net/Makefile
new file mode 100644
index 0000000..a643ab0
--- /dev/null
+++ b/drivers/bus/net/Makefile
@@ -0,0 +1,66 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   Author: Gaetan Rivet
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_net.a
+LIBABIVER := 1
+
+CFLAGS += $(WERROR_FLAGS)
+ifeq ($(DEBUG),1)
+CONFIG_RTE_LIBRTE_NET_BUS_DEBUG := y
+endif
+ifeq ($(CONFIG_RTE_LIBRTE_NET_BUS_DEBUG),y)
+CFLAGS += -UNDEBUG -g -O0
+else
+CFLAGS += -DNDEBUG -O3
+endif
+CFLAGS += -I$(RTE_SDK)/drivers/bus/net
+CFLAGS += -I$(RTE_SDK)/drivers/bus/net/include
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BDSAPP),)
+SYSTEM := bsd
+endif
+
+EXPORT_MAP := $(SYSTEM)/rte_bus_net_version.map
+CFLAGS += -I$(RTE_SDK)/drivers/bus/net/$(SYSTEM)
+
+include $(RTE_SDK)/drivers/bus/net/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_NET_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_NET_BUS) += rte_bus_net.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_net.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/net/bsd/Makefile b/drivers/bus/net/bsd/Makefile
new file mode 100644
index 0000000..435ef57
--- /dev/null
+++ b/drivers/bus/net/bsd/Makefile
@@ -0,0 +1,33 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   Author: Gaetan Rivet
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+$(error Net BUS not supported on BSD yet)
diff --git a/drivers/bus/net/bsd/rte_bus_net_version.map b/drivers/bus/net/bsd/rte_bus_net_version.map
new file mode 100644
index 0000000..f0be361
--- /dev/null
+++ b/drivers/bus/net/bsd/rte_bus_net_version.map
@@ -0,0 +1,14 @@
+DPDK_17.08 {
+	global:
+
+	rte_net_register;
+	rte_net_unregister;
+	rte_bus_net_dev_stat;
+	rte_bus_net_driver;
+	rte_bus_net_pci_loc;
+	rte_bus_net_virtual_xfrm;
+	rte_bus_net_pci_xfrm;
+	rte_bus_net_path_read;
+
+	local: *;
+};
diff --git a/drivers/bus/net/include/rte_bus_net.h b/drivers/bus/net/include/rte_bus_net.h
new file mode 100644
index 0000000..3d960f8
--- /dev/null
+++ b/drivers/bus/net/include/rte_bus_net.h
@@ -0,0 +1,205 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A.
+ *   Author: Gaetan Rivet
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_NET_BUS_H_
+#define _RTE_NET_BUS_H_
+
+#include <sys/queue.h>
+#include <stdint.h>
+
+#include <rte_devargs.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+/**
+ * @file
+ *
+ * RTE Net bus.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Name of net bus. */
+#define RTE_BUS_NET_NAME "net"
+
+/**
+ * Structure describing an RTE net device.
+ */
+struct rte_net_device {
+	TAILQ_ENTRY(rte_net_device) next; /**< Next net device. */
+	struct rte_device device; /**< Inherit core device. */
+	struct rte_net_driver *driver; /**< Associated driver. */
+	struct rte_devargs *da; /**< Device parameters. */
+	struct rte_device *sh_dev; /**< Shadow device. */
+	char name[33]; /**< Kernel netdev name. */
+};
+
+/**
+ * Name transform callback.
+ * Transform a netdevice name into its DPDK counterpart.
+ *
+ * @param[in] src
+ *   original devargs to transform.
+ *
+ * @param[out] dst
+ *   rte_devargs resulting from the transformation.
+ *
+ * @return
+ *   0 for no error.
+ *   !0 otherwise.
+ */
+typedef int (*rte_bus_net_xfrm_t)(const struct rte_devargs *src,
+				  struct rte_devargs *dst);
+
+/**
+ * Name transform base implementations.
+ */
+int rte_bus_net_virtual_xfrm(const struct rte_devargs *src,
+			     struct rte_devargs *dst);
+int rte_bus_net_pci_xfrm(const struct rte_devargs *src,
+			 struct rte_devargs *dst);
+
+/**
+ * Structure describing an RTE net driver.
+ */
+struct rte_net_driver {
+	TAILQ_ENTRY(rte_net_driver) next; /**< Next net driver. */
+	struct rte_driver driver; /**< Inherit core driver. */
+	char kmod[33]; /**< Kernel driver name. */
+	rte_bus_net_xfrm_t xfrm; /**< Name transform. */
+};
+
+/**
+ * Register a net driver.
+ *
+ * @param driver
+ *   A pointer to an rte_net_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_net_register(struct rte_net_driver *driver);
+
+/** Helper for net device registration from driver instance. */
+#define RTE_PMD_REGISTER_NET(nm, net_drv) \
+RTE_INIT(netinitfn_ ##nm); \
+static void netinitfn_ ##nm(void) \
+{ \
+	(net_drv).driver.name = RTE_STR(nm); \
+	rte_net_register(&net_drv); \
+} \
+RTE_PMD_EXPORT_NAME(netdev_ ##nm, __COUNTER__)
+
+/**
+ * Unregister a net driver.
+ *
+ * @param driver
+ *   A pointer to an rte_net_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_net_unregister(struct rte_net_driver *driver);
+
+/**
+ * Get netdevice status.
+ *
+ * @param name
+ *   Net device name.
+ *
+ * @return
+ *   0 if device exist as a net device.
+ *   !0 otherwise.
+ */
+int rte_bus_net_dev_stat(const char *name);
+
+/**
+ * Get netdevice driver name.
+ *
+ * @param[in] name
+ *   Net device name.
+ *
+ * @param[out] out
+ *   Buffer to write the driver name to.
+ *
+ * @param[in] size
+ *   Buffer length.
+ *
+ * @return
+ *   0 if driver was successfully written.
+ *   !0 otherwise.
+ */
+int rte_bus_net_driver(const char *name, char *out, size_t size);
+
+/**
+ * Get netdevice PCI location.
+ *
+ * @param[in] name
+ *   Net device name.
+ *
+ * @param[out] out
+ *   Buffer to write the PCI address to.
+ *
+ * @param[in] size
+ *   Buffer length.
+ *
+ * @return
+ *   0 if PCI address was successfully written.
+ *   !0 otherwise.
+ */
+int rte_bus_net_pci_loc(const char *name, char *out, size_t size);
+
+/**
+ * Read the content of a file.
+ *
+ * @param[out] out
+ *   Buffer to write the content to.
+ *
+ * @param[in] size
+ *   Buffer length.
+ *
+ * @param[in] format
+ *   printf-like format string describing the path
+ *   of the file to read.
+ *
+ * @return
+ *   0 if all was written successfully.
+ *   !0 otherwise. errno is set.
+ */
+int rte_bus_net_path_read(char *out, size_t size,
+			  const char *format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_NET_BUS_H_ */
diff --git a/drivers/bus/net/linux/Makefile b/drivers/bus/net/linux/Makefile
new file mode 100644
index 0000000..37af5fc
--- /dev/null
+++ b/drivers/bus/net/linux/Makefile
@@ -0,0 +1,35 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   Author: Gaetan Rivet
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += rte_bus_net.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/net/linux/rte_bus_net.c b/drivers/bus/net/linux/rte_bus_net.c
new file mode 100644
index 0000000..2d42ca9
--- /dev/null
+++ b/drivers/bus/net/linux/rte_bus_net.c
@@ -0,0 +1,225 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A.
+ *   Author: Gaetan Rivet
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include <linux/limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rte_bus.h>
+
+#include "rte_bus_net.h"
+#include "private.h"
+
+/* Default path */
+const char SYSFS_NET_DEVICES[] = "/sys/class/net";
+
+int
+rte_bus_net_path_read(char *out, size_t size,
+		      const char *format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	char path[vsnprintf(NULL, 0, format, ap) + 1];
+	FILE *file;
+	int ret;
+	int err;
+
+	va_end(ap);
+	va_start(ap, format);
+	vsnprintf(path, sizeof(path), format, ap);
+	file = fopen(path, "rb");
+	if (file == NULL) {
+		ERROR("failed to open file %s (%s)",
+		      path, strerror(errno));
+		va_end(ap);
+		return -1;
+	}
+	ret = fread(out, size, 1, file);
+	err = errno;
+	if (((size_t)ret < size) && (ferror(file))) {
+		va_end(ap);
+		ret = -1;
+	}
+	fclose(file);
+	errno = err;
+	va_end(ap);
+	return ret;
+}
+
+static int
+parse_u32(const char *val, uint32_t *out)
+{
+	char *end;
+	uint64_t tmp;
+
+	errno = 0;
+	tmp = strtoull(val, &end, 0);
+	if (errno != 0 || val[0] == '\0' || end == NULL)
+		return -EINVAL;
+	if (tmp > UINT32_MAX)
+		return -ERANGE;
+	*out = (uint32_t) tmp;
+	return 0;
+}
+
+static uint32_t
+dev_flags(const char *name)
+{
+	char buf[32] = "";
+	uint32_t val;
+
+	if (rte_bus_net_path_read(buf, sizeof(buf), "%s/%s/flags",
+				  net_get_sysfs_path(), name)) {
+		ERROR("failed to read flags on device %s", name);
+		return 0;
+	}
+	if (parse_u32(buf, &val)) {
+		ERROR("failed to parse %s", buf);
+		return 0;
+	}
+	return val;
+}
+
+int
+net_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	const char *path;
+	int ret = 0;
+	int scan_blist = 0;
+
+	path = net_get_sysfs_path();
+	dir = opendir(path);
+	if (dir == NULL) {
+		ret = errno;
+		ERROR("opendir %s failed: %s", path, strerror(errno));
+		return -1;
+	}
+	if (rte_bus_net.conf.scan_mode == RTE_BUS_SCAN_BLACKLIST)
+		scan_blist = 1;
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+		if (dev_flags(e->d_name) & 0x8)
+			continue;
+		if (scan_blist ^
+		    !net_devargs_lookup(e->d_name))
+			continue;
+		/* Scan errors are ignored in blacklist mode. */
+		if (!net_scan_one(e->d_name) && !scan_blist)
+			goto out;
+	}
+out:
+	closedir(dir);
+	return ret;
+}
+
+int
+rte_bus_net_dev_stat(const char *name)
+{
+	struct stat buf;
+	int err;
+	MKSTR(path, "%s/%s", net_get_sysfs_path(), name);
+
+	if (name[0] == '\0')
+		return -1;
+	snprintf(path, sizeof(path), "%s/%s",
+		 net_get_sysfs_path(), name);
+	err = errno;
+	errno = 0;
+	if (stat(path, &buf)) {
+		if (errno != ENOENT)
+			ERROR("stat(%s) failed: %s", path, strerror(errno));
+		errno = err;
+		return -1;
+	}
+	return 0;
+}
+
+static int
+link_read(const char *path, char *out, size_t size)
+{
+	struct stat buf;
+	int err;
+
+	err = errno;
+	errno = 0;
+	if (stat(path, &buf)) {
+		if (errno != ENOENT)
+			ERROR("stat(%s) failed: %s", path, strerror(errno));
+		errno = err;
+		return -1;
+	}
+	if (size > 0) {
+		char buf[PATH_MAX + 1] = "";
+		ssize_t wlen;
+		char *s;
+
+		wlen = readlink(path, buf, sizeof(buf) - 1);
+		if (wlen > 0) {
+			out[wlen] = '\0';
+		} else {
+			ERROR("readlink(%s) failed: %s", path,
+			      strerror(errno));
+			errno = err;
+			return -1;
+		}
+		for (s = &buf[wlen]; *s != '/'; s--)
+			;
+		snprintf(out, size, "%s", &s[1]);
+	}
+	return 0;
+}
+
+int
+rte_bus_net_driver(const char *name, char *out, size_t size)
+{
+	MKSTR(path, "%s/%s/device/driver", net_get_sysfs_path(), name);
+
+	return link_read(path, out, size);
+}
+
+int
+rte_bus_net_pci_loc(const char *name, char *out, size_t size)
+{
+	MKSTR(path, "%s/%s/device", net_get_sysfs_path(), name);
+
+	return link_read(path, out, size);
+}
diff --git a/drivers/bus/net/linux/rte_bus_net_version.map b/drivers/bus/net/linux/rte_bus_net_version.map
new file mode 100644
index 0000000..f0be361
--- /dev/null
+++ b/drivers/bus/net/linux/rte_bus_net_version.map
@@ -0,0 +1,14 @@
+DPDK_17.08 {
+	global:
+
+	rte_net_register;
+	rte_net_unregister;
+	rte_bus_net_dev_stat;
+	rte_bus_net_driver;
+	rte_bus_net_pci_loc;
+	rte_bus_net_virtual_xfrm;
+	rte_bus_net_pci_xfrm;
+	rte_bus_net_path_read;
+
+	local: *;
+};
diff --git a/drivers/bus/net/private.h b/drivers/bus/net/private.h
new file mode 100644
index 0000000..f666b52
--- /dev/null
+++ b/drivers/bus/net/private.h
@@ -0,0 +1,144 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A.
+ *   Author: Gaetan Rivet
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NET_PRIVATE_H_
+#define _NET_PRIVATE_H_
+
+#include <sys/queue.h>
+
+#include <rte_bus.h>
+#include <rte_tailq.h>
+
+#include "rte_bus_net.h"
+
+/* Double linked list of devices. */
+TAILQ_HEAD(net_device_list, rte_net_device);
+/* Double linked list of drivers. */
+TAILQ_HEAD(net_driver_list, rte_net_driver);
+
+extern struct net_device_list net_device_list;
+extern struct net_driver_list net_driver_list;
+
+/* Bus handle. */
+extern struct rte_bus rte_bus_net;
+
+/** Default net devices path. */
+extern const char SYSFS_NET_DEVICES[];
+
+/* Find the rte_net_driver of a kernel device. */
+struct rte_net_driver *net_drv_find(const char *name);
+
+/* Parse device name. */
+int net_parse(const char *name, void *addr);
+
+/* Scan a single device. */
+struct rte_net_device *net_scan_one(const char *name);
+
+/* Scan sysfs. */
+int net_scan(void);
+
+/* Get sysfs path. */
+const char *net_get_sysfs_path(void);
+
+/* Find devargs of a device. */
+struct rte_devargs *net_devargs_lookup(const char *name);
+
+/* Read file content. */
+int path_read(char *out, size_t size, const char *format, ...)
+	__attribute__((format(printf, 3, 0)));
+
+/* Net Bus iterators. */
+#define FOREACH_NET_DEVICE(p) \
+	TAILQ_FOREACH(p, &(net_device_list), next)
+
+#define FOREACH_NET_DEVICE_SAFE(p, tmp) \
+	TAILQ_FOREACH_SAFE(p, &(net_device_list), next, tmp)
+
+#define FOREACH_NET_DRIVER(p) \
+	TAILQ_FOREACH(p, &(net_driver_list), next)
+
+#define FOREACH_NET_DRIVER_SAFE(p, tmp) \
+	TAILQ_FOREACH_SAFE(p, &(net_driver_list), next, tmp)
+
+/* Net lists operators. */
+#define INSERT_NET_DEVICE(dev) \
+	TAILQ_INSERT_TAIL(&net_device_list, dev, next)
+
+#define REMOVE_NET_DEVICE(dev) \
+	TAILQ_REMOVE(&net_device_list, dev, next)
+
+#define INSERT_NET_DRIVER(drv) \
+	TAILQ_INSERT_TAIL(&net_driver_list, drv, next)
+
+#define REMOVE_NET_DRIVER(drv) \
+	TAILQ_REMOVE(&net_driver_list, drv, next)
+
+/* Debugging */
+#ifndef NDEBUG
+#include <stdio.h>
+#define DEBUG__(m, ...)						\
+	(fprintf(stderr, "%s:%d: %s(): " m "%c",		\
+		 __FILE__, __LINE__, __func__, __VA_ARGS__),	\
+	 fflush(stderr),					\
+	 (void)0)
+/*
+ * Save/restore errno around DEBUG__().
+ * XXX somewhat undefined behavior, but works.
+ */
+#define DEBUG_(...)				\
+	(errno = ((int []){			\
+		*(volatile int *)&errno,	\
+		(DEBUG__(__VA_ARGS__), 0)	\
+	})[0])
+#define DEBUG(...) DEBUG_(__VA_ARGS__, '\n')
+#define INFO(...) DEBUG(__VA_ARGS__)
+#define WARN(...) DEBUG(__VA_ARGS__)
+#define ERROR(...) DEBUG(__VA_ARGS__)
+#else /* NDEBUG */
+#define LOG__(level, m, ...) \
+	RTE_LOG(level, EAL, "NET: " m "%c", __VA_ARGS__)
+#define LOG_(level, ...) LOG__(level, __VA_ARGS__, '\n')
+#define DEBUG(...) (void)0
+#define INFO(...) LOG_(INFO, __VA_ARGS__)
+#define WARN(...) LOG_(WARNING, "WARNING: " __VA_ARGS__)
+#define ERROR(...) LOG_(ERR, "ERROR: " __VA_ARGS__)
+#endif /* NDEBUG */
+
+/* Allocate a buffer on the stack and fill it with a printf format string. */
+#define MKSTR(name, ...) \
+	char name[snprintf(NULL, 0, __VA_ARGS__) + 1]; \
+	\
+	snprintf(name, sizeof(name), __VA_ARGS__)
+
+#endif /* _NET_PRIVATE_H_ */
diff --git a/drivers/bus/net/rte_bus_net.c b/drivers/bus/net/rte_bus_net.c
new file mode 100644
index 0000000..27a43f4
--- /dev/null
+++ b/drivers/bus/net/rte_bus_net.c
@@ -0,0 +1,265 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A.
+ *   Author: Gaetan Rivet
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#include <rte_devargs.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_errno.h>
+
+#include "rte_bus_net.h"
+#include "private.h"
+
+struct net_device_list net_device_list =
+	TAILQ_HEAD_INITIALIZER(net_device_list);
+struct net_driver_list net_driver_list =
+	TAILQ_HEAD_INITIALIZER(net_driver_list);
+
+struct rte_devargs *
+net_devargs_lookup(const char *name)
+{
+	struct rte_devargs *da;
+
+	TAILQ_FOREACH(da, &devargs_list, next) {
+		if (da->bus != &rte_bus_net)
+			continue;
+		if (!strcmp(da->name, name))
+			return da;
+	}
+	return NULL;
+}
+
+struct rte_net_driver *
+net_drv_find(const char *name)
+{
+	struct rte_net_driver *drv = NULL;
+	char drv_kmod[32] = "";
+
+	if (rte_bus_net_driver(name, drv_kmod, sizeof(drv_kmod)))
+		return NULL;
+	FOREACH_NET_DRIVER(drv)
+		if (!strcmp(drv->kmod, drv_kmod))
+			break;
+	return drv;
+}
+
+/*
+ * typeof(addr): struct rte_net_device *
+ */
+int
+net_parse(const char *name, void *addr)
+{
+	struct rte_net_device *dev = addr;
+	struct rte_net_driver *drv = NULL;
+	struct rte_devargs devargs;
+	struct rte_devargs *da;
+	struct rte_devargs *sub;
+
+	if (rte_bus_net_dev_stat(name))
+		return 1;
+	if (addr == NULL)
+		return 0;
+	drv = net_drv_find(name);
+	if (drv == NULL) {
+		DEBUG("unable to find driver");
+		rte_errno = EFAULT;
+		return -1;
+	}
+	dev->driver = drv;
+	da = dev->device.devargs;
+	if (!da) {
+		da = &devargs;
+		snprintf(da->name, sizeof(da->name), "%s", name);
+		da->args = NULL;
+		sub = calloc(1, sizeof(*sub));
+		dev->device.name = sub->name;
+	} else {
+		sub = rte_eal_devargs_clone(da);
+		dev->device.name = da->name;
+	}
+	if (sub == NULL) {
+		DEBUG("unable to clone devargs");
+		rte_errno = ENOMEM;
+		return -1;
+	}
+	dev->da = sub;
+	if (drv->xfrm(da, sub)) {
+		DEBUG("unable to parse device name");
+		rte_errno = ENODEV;
+		return -1;
+	}
+	sub->bus = rte_bus_from_dev(sub->name);
+	return !sub->bus;
+}
+
+struct rte_net_device *
+net_scan_one(const char *name)
+{
+	struct rte_net_device *dev;
+
+	dev = calloc(1, sizeof(*dev));
+	if (dev == NULL) {
+		ERROR("failed to allocate memory");
+		return NULL;
+	}
+	snprintf(dev->name, sizeof(dev->name), "%s", name);
+	dev->device.devargs = net_devargs_lookup(dev->name);
+	if (!net_parse(dev->name, dev)) {
+		INSERT_NET_DEVICE(dev);
+		return dev;
+	}
+	free(dev);
+	return NULL;
+}
+
+static int
+net_probe_one(struct rte_net_device *dev)
+{
+	struct rte_devargs *da;
+	struct rte_device *rdev;
+	struct rte_bus *bus;
+	int ret;
+
+	da = dev->da;
+	bus = da->bus;
+	if (bus->plug == NULL) {
+		ERROR("bus %s does not support plugin", bus->name);
+		return -1;
+	}
+	rdev = bus->plug(da);
+	ret = rdev ? 0 : -rte_errno;
+	if (rdev)
+		dev->sh_dev = rdev;
+	return ret;
+}
+
+static int
+net_probe(void)
+{
+	struct rte_net_device *dev;
+	int ret;
+
+	FOREACH_NET_DEVICE(dev) {
+		ret = net_probe_one(dev);
+		if (ret < 0)
+			return ret;
+	}
+	return 0;
+}
+
+static struct rte_device *
+net_find_device(int (*match)(const struct rte_device *dev, const void *data),
+		const void *data)
+{
+	struct rte_net_device *dev;
+
+	FOREACH_NET_DEVICE(dev)
+		if (match(&dev->device, data))
+			return &dev->device;
+	return NULL;
+}
+
+void
+rte_net_register(struct rte_net_driver *driver)
+{
+	if (driver->xfrm == NULL)
+		driver->xfrm = rte_bus_net_pci_xfrm;
+	INSERT_NET_DRIVER(driver);
+}
+
+void
+rte_net_unregister(struct rte_net_driver *driver)
+{
+	REMOVE_NET_DRIVER(driver);
+}
+
+const char *
+net_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_NET_DEVICES");
+	if (path == NULL)
+		return SYSFS_NET_DEVICES;
+	return path;
+}
+
+int
+rte_bus_net_virtual_xfrm(const struct rte_devargs *src,
+			 struct rte_devargs *dst)
+{
+	size_t argslen;
+
+	/* dev name. */
+	snprintf(dst->name, sizeof(dst->name),
+		 "net_tap_%s", src->name);
+	/* dev args. */
+	if (dst->args)
+		free(dst->args);
+	argslen = snprintf(NULL, 0, "iface=tap_%s,remote=%s,%s",
+			   src->name, src->name, src->args) + 1;
+	dst->args = calloc(1, argslen);
+	if (dst->args == NULL)
+		return -1;
+	snprintf(dst->args, argslen, "iface=tap_%s,remote=%s,%s",
+		 src->name, src->name, src->args);
+	return 0;
+}
+
+int
+rte_bus_net_pci_xfrm(const struct rte_devargs *src,
+		     struct rte_devargs *dst)
+{
+	char buf[32] = "";
+	int ret;
+
+	ret = rte_bus_net_pci_loc(src->name, buf, sizeof(buf));
+	if (ret)
+		return ret;
+	ret = snprintf(dst->name, sizeof(dst->name), "%s", buf);
+	dst->args = strdup(src->args);
+	return ret < 0 || ret > (int)sizeof(dst->name) || dst->args == NULL;
+}
+
+struct rte_bus rte_bus_net = {
+	.scan = net_scan,
+	.probe = net_probe,
+	.find_device = net_find_device,
+	.parse = net_parse,
+	.conf = {
+		.scan_mode = RTE_BUS_SCAN_UNDEFINED,
+	},
+};
+RTE_REGISTER_BUS(RTE_BUS_NET_NAME, rte_bus_net);
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d536a20..ad6a9c6 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -104,6 +104,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+_LDLIBS-$(CONFIG_RTE_LIBRTE_NET_BUS)        += -lrte_bus_net
 
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
-- 
2.1.4

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

* [PATCH v2 2/4] bus/net: implement hotplug bus operations
  2017-06-08  0:00 ` [PATCH v2 0/4] Introduce net bus Gaetan Rivet
  2017-06-08  0:00   ` [PATCH v2 1/4] bus/net: introduce " Gaetan Rivet
@ 2017-06-08  0:00   ` Gaetan Rivet
  2017-06-08  0:01   ` [PATCH v2 3/4] net/mlx4: net bus support Gaetan Rivet
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-08  0:00 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/net/rte_bus_net.c | 60 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/drivers/bus/net/rte_bus_net.c b/drivers/bus/net/rte_bus_net.c
index 27a43f4..f5c7c95 100644
--- a/drivers/bus/net/rte_bus_net.c
+++ b/drivers/bus/net/rte_bus_net.c
@@ -253,11 +253,71 @@ rte_bus_net_pci_xfrm(const struct rte_devargs *src,
 	return ret < 0 || ret > (int)sizeof(dst->name) || dst->args == NULL;
 }
 
+static struct rte_device *
+net_plug(struct rte_devargs *da)
+{
+	struct rte_net_device *dev;
+
+	dev = net_scan_one(da->name);
+	if (dev == NULL) {
+		rte_errno = EFAULT;
+		return NULL;
+	}
+	if (net_probe_one(dev)) {
+		rte_errno = ENODEV;
+		return NULL;
+	}
+	return dev->sh_dev;
+}
+
+static int
+net_unplug(struct rte_device *dev)
+{
+	struct rte_net_device *ndev;
+	void *tmp;
+	int ret;
+	int err;
+
+	FOREACH_NET_DEVICE_SAFE(ndev, tmp) {
+		struct rte_device *rdev;
+		struct rte_devargs *da;
+		struct rte_devargs *sub;
+
+		if (dev != &ndev->device &&
+		    dev != ndev->sh_dev)
+			continue;
+		rdev = ndev->sh_dev;
+		if (rdev == NULL)
+			continue;
+		da = ndev->device.devargs;
+		sub = rdev->devargs;
+		ret = sub->bus->unplug(rdev);
+		if (ret) {
+			err = rte_errno;
+			ERROR("unplug failed");
+			rte_errno = err;
+			return ret;
+		}
+		free(sub);
+		rte_eal_devargs_rmv(da);
+		REMOVE_NET_DEVICE(ndev);
+		free(ndev);
+		break;
+	}
+	if (ndev == NULL) {
+		ERROR("no such device");
+		return -ENODEV;
+	}
+	return 0;
+}
+
 struct rte_bus rte_bus_net = {
 	.scan = net_scan,
 	.probe = net_probe,
 	.find_device = net_find_device,
 	.parse = net_parse,
+	.plug = net_plug,
+	.unplug = net_unplug,
 	.conf = {
 		.scan_mode = RTE_BUS_SCAN_UNDEFINED,
 	},
-- 
2.1.4

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

* [PATCH v2 3/4] net/mlx4: net bus support
  2017-06-08  0:00 ` [PATCH v2 0/4] Introduce net bus Gaetan Rivet
  2017-06-08  0:00   ` [PATCH v2 1/4] bus/net: introduce " Gaetan Rivet
  2017-06-08  0:00   ` [PATCH v2 2/4] bus/net: implement hotplug bus operations Gaetan Rivet
@ 2017-06-08  0:01   ` Gaetan Rivet
  2017-06-08  0:01   ` [PATCH v2 4/4] net/mlx5: " Gaetan Rivet
  2017-06-08  7:31   ` [PATCH v2 0/4] Introduce net bus Thomas Monjalon
  4 siblings, 0 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-08  0:01 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/mlx4/mlx4.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index b9554d5..9dfff5f 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -62,6 +62,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_dev.h>
+#include <rte_bus_net.h>
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_mempool.h>
@@ -6302,3 +6303,37 @@ RTE_PMD_EXPORT_NAME(net_mlx4, __COUNTER__);
 RTE_PMD_REGISTER_PCI_TABLE(net_mlx4, mlx4_pci_id_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_mlx4,
 	"* ib_uverbs & mlx4_en & mlx4_core & mlx4_ib");
+
+static int
+mlx4_net_pci_xfrm(const struct rte_devargs *src,
+		  struct rte_devargs *dst)
+{
+	char buf[32] = "";
+	size_t arglen;
+	int ret;
+
+	ret = rte_bus_net_pci_loc(src->name, buf, sizeof(buf));
+	if (ret)
+		return ret;
+	snprintf(dst->name, sizeof(dst->name), "%s", buf);
+	memset(buf, 0, sizeof(buf));
+	ret = rte_bus_net_path_read(buf, sizeof(buf),
+				    "/sys/class/net/%s/dev_port", src->name);
+	if (ret)
+		return ret;
+	arglen = snprintf(NULL, 0, "port=%s,%s", buf, src->args) + 1;
+	dst->args = calloc(1, arglen);
+	if (dst->args == NULL)
+		return -ENOMEM;
+	snprintf(dst->args, arglen, "port=%s,%s", buf, src->args);
+	return 0;
+}
+
+static struct rte_net_driver mlx4_net_driver = {
+	.driver = {
+		.name = MLX4_DRIVER_NAME,
+	},
+	.kmod = "mlx4_core",
+	.xfrm = mlx4_net_pci_xfrm,
+};
+RTE_PMD_REGISTER_NET(mlx4, mlx4_net_driver);
-- 
2.1.4

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

* [PATCH v2 4/4] net/mlx5: net bus support
  2017-06-08  0:00 ` [PATCH v2 0/4] Introduce net bus Gaetan Rivet
                     ` (2 preceding siblings ...)
  2017-06-08  0:01   ` [PATCH v2 3/4] net/mlx4: net bus support Gaetan Rivet
@ 2017-06-08  0:01   ` Gaetan Rivet
  2017-06-08  7:31   ` [PATCH v2 0/4] Introduce net bus Thomas Monjalon
  4 siblings, 0 replies; 11+ messages in thread
From: Gaetan Rivet @ 2017-06-08  0:01 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/mlx5/mlx5.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index bcb2c1b..0ba13e9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -58,6 +58,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_net.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 #ifdef PEDANTIC
@@ -899,3 +900,11 @@ rte_mlx5_pmd_init(void)
 RTE_PMD_EXPORT_NAME(net_mlx5, __COUNTER__);
 RTE_PMD_REGISTER_PCI_TABLE(net_mlx5, mlx5_pci_id_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_mlx5, "* ib_uverbs & mlx5_core & mlx5_ib");
+
+static struct rte_net_driver mlx5_net_driver = {
+	.driver = {
+		.name = MLX5_DRIVER_NAME,
+	},
+	.kmod = "mlx5_core",
+};
+RTE_PMD_REGISTER_NET(mlx5, mlx5_net_driver);
-- 
2.1.4

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

* Re: [PATCH v2 0/4] Introduce net bus
  2017-06-08  0:00 ` [PATCH v2 0/4] Introduce net bus Gaetan Rivet
                     ` (3 preceding siblings ...)
  2017-06-08  0:01   ` [PATCH v2 4/4] net/mlx5: " Gaetan Rivet
@ 2017-06-08  7:31   ` Thomas Monjalon
  2017-06-08 20:31     ` Gaëtan Rivet
  4 siblings, 1 reply; 11+ messages in thread
From: Thomas Monjalon @ 2017-06-08  7:31 UTC (permalink / raw)
  To: Gaetan Rivet; +Cc: dev, Ferruh Yigit

08/06/2017 02:00, Gaetan Rivet:
> This new bus takes as devices kernel netdevices.
> It offers an API for drivers to register a translation layer that would
> transform the netdev name to one their regular PMD would be able to
> probe.
> 
> This is PoC. It currently only works for MLX4 and MLX5 PMDs as they were
> bifurcated and had very little work to do otherwise.
> 
> The planned feature is for at least all PCI drivers, be able to unbind
> the device from its kmod and bind it to a choosen IO module, prior to
> probing.
> 
> Additional possible feature would be a close integration with eventually
> NCI-like lib, to transparently capture kernel devices, keep a control
> interface present and bind / unbind the underlying hardware function as
> necessary.

I'm sorry, I do not understand the description.
Please start with a real problem statement and explain how it is solved.
Thanks

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

* Re: [PATCH v2 0/4] Introduce net bus
  2017-06-08  7:31   ` [PATCH v2 0/4] Introduce net bus Thomas Monjalon
@ 2017-06-08 20:31     ` Gaëtan Rivet
  0 siblings, 0 replies; 11+ messages in thread
From: Gaëtan Rivet @ 2017-06-08 20:31 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Ferruh Yigit, users

Hi Thomas,

On Thu, Jun 08, 2017 at 09:31:23AM +0200, Thomas Monjalon wrote:
> I'm sorry, I do not understand the description.
> Please start with a real problem statement and explain how it is solved.
> Thanks

Sure.

Currently, we probe devices by using

./usertools/dpkd-devbind.py -b igb_uio 00:02.0
./build/app/whatever -w 00:02.0
./usertools/dpkd-devbind.py -b ixgbe 00:02.0

Wouldn't it be nice to be able to:

./build/app/whatever -w ens2

Instead?

Many things are missing for this. This PoC only shows the simplest
case with a bifurcated driver, but the concept is there.

This bus is an intepretation layer to transform a kernel netdevice name
into a usable DPDK device, which should give enough info about its
dependencies: bus, IO module, resource management policies,
etc... to prepare it.

I plan to add binding / unbinding afterward, and I wanted to
propose this early enough as there were talks of kernel control plane,
and this could be a building block to this general direction.

Auto-unbind assumes a clean exit from the DPDK application. This might
be a big departure from current assumptions, where buses very seldom
plan for ending operations. i.e. rte_bus has scan and probe, but no
remove API. While unplug should soon exist, this is a crude workaround.

-- 
Gaëtan Rivet
6WIND

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

end of thread, other threads:[~2017-06-08 20:31 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-01 10:44 [PATCH 0/3] Introduce net bus Gaetan Rivet
2017-06-01 10:44 ` [PATCH 1/3] bus/net: introduce " Gaetan Rivet
2017-06-01 10:44 ` [PATCH 2/3] net/mlx4: net bus support Gaetan Rivet
2017-06-01 10:44 ` [PATCH 3/3] net/mlx5: " Gaetan Rivet
2017-06-08  0:00 ` [PATCH v2 0/4] Introduce net bus Gaetan Rivet
2017-06-08  0:00   ` [PATCH v2 1/4] bus/net: introduce " Gaetan Rivet
2017-06-08  0:00   ` [PATCH v2 2/4] bus/net: implement hotplug bus operations Gaetan Rivet
2017-06-08  0:01   ` [PATCH v2 3/4] net/mlx4: net bus support Gaetan Rivet
2017-06-08  0:01   ` [PATCH v2 4/4] net/mlx5: " Gaetan Rivet
2017-06-08  7:31   ` [PATCH v2 0/4] Introduce net bus Thomas Monjalon
2017-06-08 20:31     ` Gaëtan Rivet

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.