* [PATCH v6 16/21] eal/soc: additional features for SoC
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Additional features introduced:
- Find kernel driver through sysfs bindings
- Dummy implementation for mapping to kernel driver
- DMA coherency value from sysfs
- Numa node number from sysfs
- Support for updating device during probe if already registered
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: merge multiple patches into single set]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/common/eal_common_soc.c | 30 ++++++++
lib/librte_eal/common/eal_private.h | 23 ++++++
lib/librte_eal/common/include/rte_soc.h | 28 +++++++
lib/librte_eal/linuxapp/eal/eal_soc.c | 129 ++++++++++++++++++++++++++++++++
4 files changed, 210 insertions(+)
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 44f5559..29c38e0 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -114,6 +114,26 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
return ret;
}
+ if (!dev->is_dma_coherent) {
+ if (!(drv->drv_flags & RTE_SOC_DRV_ACCEPT_NONCC)) {
+ RTE_LOG(DEBUG, EAL,
+ " device is not DMA coherent, skipping\n");
+ return 1;
+ }
+ }
+
+ if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING) {
+ /* map resources */
+ ret = rte_eal_soc_map_device(dev);
+ if (ret)
+ return ret;
+ } else if (drv->drv_flags & RTE_SOC_DRV_FORCE_UNBIND
+ && rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ /* unbind */
+ if (soc_unbind_kernel_driver(dev) < 0)
+ return -1;
+ }
+
dev->driver = drv;
RTE_VERIFY(drv->probe != NULL);
return drv->probe(drv, dev);
@@ -166,6 +186,10 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
if (drv->remove && (drv->remove(dev) < 0))
return -1; /* negative value is an error */
+ if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING)
+ /* unmap resources for devices */
+ rte_eal_soc_unmap_device(dev);
+
/* clear driver structure */
dev->driver = NULL;
@@ -241,6 +265,12 @@ rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
if (addr == NULL)
return -1;
+ /* update current SoC device in global list, kernel bindings might have
+ * changed since last time we looked at it.
+ */
+ if (soc_update_device(addr) < 0)
+ goto err_return;
+
TAILQ_FOREACH(dev, &soc_device_list, next) {
if (rte_eal_compare_soc_addr(&dev->addr, addr))
continue;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index d810f9f..30c648d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -159,6 +159,29 @@ int pci_update_device(const struct rte_pci_addr *addr);
int pci_unbind_kernel_driver(struct rte_pci_device *dev);
/**
+ * Update a soc device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ * The SoC address to look for
+ * @return
+ * - 0 on success.
+ * - negative on error.
+ */
+int soc_update_device(const struct rte_soc_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ * 0 on success, negative on error
+ */
+int soc_unbind_kernel_driver(struct rte_soc_device *dev);
+
+/**
* Map the PCI resource of a PCI device in virtual memory
*
* This function is private to EAL.
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 8be3db7..d7f7ec8 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -46,9 +46,11 @@ extern "C" {
#include <stdio.h>
#include <stdlib.h>
+#include <sys/queue.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
+#include <limits.h>
#include <rte_dev.h>
#include <rte_eal.h>
@@ -63,6 +65,14 @@ extern struct soc_device_list soc_device_list;
TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+#define SOC_MAX_RESOURCE 6
+
+struct rte_soc_resource {
+ uint64_t phys_addr;
+ uint64_t len;
+ void *addr;
+};
+
struct rte_soc_id {
union {
const char *compatible; /**< OF compatible specification */
@@ -84,8 +94,12 @@ struct rte_soc_device {
struct rte_device device; /**< Inherit code device */
struct rte_soc_addr addr; /**< SoC device Location */
struct rte_soc_id *id; /**< SoC device ID list */
+ struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
struct rte_intr_handle intr_handle; /**< Interrupt handle */
struct rte_soc_driver *driver; /**< Associated driver */
+ int numa_node; /**< NUMA node connection */
+ int is_dma_coherent; /**< DMA coherent device */
+ enum rte_kernel_driver kdrv; /**< Kernel driver */
};
struct rte_soc_driver;
@@ -139,6 +153,8 @@ struct rte_soc_driver {
#define RTE_SOC_DRV_INTR_LSC 0x0008
/** Device driver supports detaching capability */
#define RTE_SOC_DRV_DETACHABLE 0x0010
+/** Device driver accepts DMA non-coherent devices */
+#define RTE_SOC_DRV_ACCEPT_NONCC 0x0020
/**
* Utility function to write a SoC device name, this device name can later be
@@ -256,6 +272,18 @@ int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
int rte_eal_soc_detach(const struct rte_soc_addr *addr);
/**
+ * Map SoC device resources into userspace.
+ *
+ * This is called by the EAL if (drv_flags & RTE_SOC_DRV_NEED_MAPPING).
+ */
+int rte_eal_soc_map_device(struct rte_soc_device *dev);
+
+/**
+ * Unmap the device resources.
+ */
+void rte_eal_soc_unmap_device(struct rte_soc_device *dev);
+
+/**
* Dump discovered SoC devices.
*
* @param f
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index d8dfe97..95f7565 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -63,6 +63,45 @@ soc_get_sysfs_path(void)
return path;
}
+int
+soc_unbind_kernel_driver(struct rte_soc_device *dev)
+{
+ char devpath[PATH_MAX];
+
+ snprintf(devpath, sizeof(devpath), "%s/%s",
+ soc_get_sysfs_path(), dev->addr.name);
+
+ return rte_eal_unbind_kernel_driver(devpath, dev->addr.name);
+}
+
+int
+rte_eal_soc_map_device(struct rte_soc_device *dev)
+{
+ int ret = -1;
+
+ /* try mapping the NIC resources using VFIO if it exists */
+ switch (dev->kdrv) {
+ default:
+ RTE_LOG(DEBUG, EAL,
+ " Not managed by a supported kernel driver, skipped\n");
+ ret = 1;
+ break;
+ }
+
+ return ret;
+}
+
+void
+rte_eal_soc_unmap_device(struct rte_soc_device *dev)
+{
+ switch (dev->kdrv) {
+ default:
+ RTE_LOG(DEBUG, EAL,
+ " Not managed by a supported kernel driver, skipped\n");
+ break;
+ }
+}
+
static char *
dev_read_uevent(const char *dirname)
{
@@ -260,6 +299,68 @@ dev_content_free(struct rte_soc_device *dev)
}
}
+static int
+dev_setup_associated_driver(struct rte_soc_device *dev, const char *dirname)
+{
+ char filename[PATH_MAX];
+ char driver[PATH_MAX];
+ int ret;
+
+ /* parse driver */
+ snprintf(filename, sizeof(filename), "%s/driver", dirname);
+ ret = rte_eal_get_kernel_driver_by_path(filename, driver);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Fail to get kernel driver for %s\n",
+ dirname);
+ return 1;
+ }
+
+ if (!ret)
+ dev->kdrv = RTE_KDRV_UNKNOWN;
+ else
+ dev->kdrv = RTE_KDRV_NONE;
+
+ return 0;
+}
+
+static int
+dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname)
+{
+ char filename[PATH_MAX];
+
+ /* if no NUMA support, set default to 0 */
+ unsigned long tmp = 0;
+ int ret = 0;
+
+ /* get numa node */
+ snprintf(filename, sizeof(filename), "%s/numa_node", dirname);
+
+ if (eal_parse_sysfs_value(filename, &tmp) < 0)
+ ret = 1;
+
+ dev->numa_node = tmp;
+ return ret;
+}
+
+static int
+dev_detect_is_coherent(struct rte_soc_device *dev)
+{
+ char filename[PATH_MAX];
+ FILE *f;
+
+ if (dev->addr.fdt_path == NULL)
+ return 0; /* no way to detect */
+
+ snprintf(filename, sizeof(filename), "%s%s/dma-coherent",
+ "/proc/device-tree", dev->addr.fdt_path);
+ f = fopen(filename, "r");
+ if (f == NULL)
+ return 0;
+
+ fclose(f);
+ return 1;
+}
+
/**
* Scan one SoC sysfs entry, and fill the devices list from it.
* We require to have the uevent file with records: OF_FULLNAME and
@@ -299,6 +400,18 @@ soc_scan_one(const char *dirname, const char *name)
goto fail;
free(uevent); /* not needed anymore */
+ ret = dev_setup_associated_driver(dev, dirname);
+ if (ret)
+ goto fail;
+
+ ret = dev_setup_numa_node(dev, dirname);
+ if (ret < 0)
+ goto fail;
+
+ dev->is_dma_coherent = dev_detect_is_coherent(dev);
+ RTE_LOG(DEBUG, EAL, " DMA %s\n",
+ dev->is_dma_coherent ? "coherent" : "non-coherent");
+
/* device is valid, add in list (sorted) */
if (TAILQ_EMPTY(&soc_device_list)) {
TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
@@ -313,6 +426,11 @@ soc_scan_one(const char *dirname, const char *name)
if (ret < 0) {
TAILQ_INSERT_BEFORE(dev2, dev, next);
} else { /* already registered */
+ dev2->kdrv = dev->kdrv;
+ dev2->is_dma_coherent = dev->is_dma_coherent;
+ memmove(dev2->mem_resource, dev->mem_resource,
+ sizeof(dev->mem_resource));
+
dev_content_free(dev2);
dev2->addr.fdt_path = dev->addr.fdt_path;
dev2->id = dev->id;
@@ -333,6 +451,17 @@ fail:
}
int
+soc_update_device(const struct rte_soc_addr *addr)
+{
+ char filename[PATH_MAX];
+
+ snprintf(filename, sizeof(filename), "%s/%s",
+ soc_get_sysfs_path(), addr->name);
+
+ return soc_scan_one(filename, addr->name);
+}
+
+int
rte_eal_soc_scan_platform_bus(void)
{
struct dirent *e;
--
2.7.4
^ permalink raw reply related
* [PATCH v6 15/21] eal/soc: add default scan for Soc devices
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Default implementation which scans the sysfs platform devices hierarchy.
For each device, extract the ueven and convert into rte_soc_device.
The information populated can then be used in probe to match against
the drivers registered.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: restructure commit to be an optional implementation]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
v5:
- Update rte_eal_soc_scan to rte_eal_soc_scan_platform_bus
- Fix comments over scan and match functions
---
lib/librte_eal/common/include/rte_soc.h | 16 +-
lib/librte_eal/linuxapp/eal/eal_soc.c | 315 ++++++++++++++++++++++++++++++++
2 files changed, 329 insertions(+), 2 deletions(-)
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 38f897d..8be3db7 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -64,7 +64,10 @@ TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
struct rte_soc_id {
- const char *compatible; /**< OF compatible specification */
+ union {
+ const char *compatible; /**< OF compatible specification */
+ char *_compatible;
+ };
uint64_t priv_data; /**< SoC Driver specific data */
};
@@ -200,7 +203,16 @@ rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
}
/**
- * Default function for matching the Soc driver with device. Each driver can
+ * Helper function for scanning for new SoC devices on platform bus.
+ *
+ * @return
+ * 0 on success
+ * !0 on failure to scan
+ */
+int rte_eal_soc_scan_platform_bus(void);
+
+/**
+ * Helper function for matching the Soc driver with device. Each driver can
* either use this function or define their own soc matching function.
* This function relies on the compatible string extracted from sysfs. But,
* a SoC might have different way of identifying its devices. Such SoC can
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 3929a76..d8dfe97 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -48,6 +48,321 @@
#include <eal_filesystem.h>
#include <eal_private.h>
+/** Pathname of SoC devices directory. */
+#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+
+static const char *
+soc_get_sysfs_path(void)
+{
+ const char *path = NULL;
+
+ path = getenv("SYSFS_SOC_DEVICES");
+ if (path == NULL)
+ return SYSFS_SOC_DEVICES;
+
+ return path;
+}
+
+static char *
+dev_read_uevent(const char *dirname)
+{
+ char filename[PATH_MAX];
+ struct stat st;
+ char *buf;
+ ssize_t total = 0;
+ int fd;
+
+ snprintf(filename, sizeof(filename), "%s/uevent", dirname);
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ RTE_LOG(WARNING, EAL, "Failed to open file %s\n", filename);
+ return strdup("");
+ }
+
+ if (fstat(fd, &st) < 0) {
+ RTE_LOG(ERR, EAL, "Failed to stat file %s\n", filename);
+ close(fd);
+ return NULL;
+ }
+
+ if (st.st_size == 0) {
+ close(fd);
+ return strdup("");
+ }
+
+ buf = malloc(st.st_size + 1);
+ if (buf == NULL) {
+ RTE_LOG(ERR, EAL, "Failed to alloc memory to read %s\n",
+ filename);
+ close(fd);
+ return NULL;
+ }
+
+ while (total < st.st_size) {
+ ssize_t rlen = read(fd, buf + total, st.st_size - total);
+ if (rlen < 0) {
+ if (errno == EINTR)
+ continue;
+
+ RTE_LOG(ERR, EAL, "Failed to read file %s\n", filename);
+
+ free(buf);
+ close(fd);
+ return NULL;
+ }
+ if (rlen == 0) /* EOF */
+ break;
+
+ total += rlen;
+ }
+
+ buf[total] = '\0';
+ close(fd);
+
+ return buf;
+}
+
+static const char *
+dev_uevent_find(const char *uevent, const char *key)
+{
+ const size_t keylen = strlen(key);
+ const size_t total = strlen(uevent);
+ const char *p = uevent;
+
+ /* check whether it is the first key */
+ if (!strncmp(uevent, key, keylen))
+ return uevent + keylen;
+
+ /* check 2nd key or further... */
+ do {
+ p = strstr(p, key);
+ if (p == NULL)
+ break;
+
+ if (p[-1] == '\n') /* check we are at a new line */
+ return p + keylen;
+
+ p += keylen; /* skip this one */
+ } while (p - uevent < (ptrdiff_t) total);
+
+ return NULL;
+}
+
+static char *
+strdup_until_nl(const char *p)
+{
+ const char *nl = strchr(p, '\n');
+ if (nl == NULL)
+ return strdup(p); /* no newline, copy until '\0' */
+
+ return strndup(p, nl - p);
+}
+
+static int
+dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
+{
+ const char *of;
+ const char *compat_n;
+ char *err;
+ long n;
+ char compat[strlen("OF_COMPATIBLE_NNNN=")];
+ long i;
+
+ of = dev_uevent_find(uevent, "OF_FULLNAME=");
+ if (of == NULL)
+ return 1; /* don't care about this device */
+
+ dev->addr.fdt_path = strdup_until_nl(of);
+ if (dev->addr.fdt_path == NULL) {
+ RTE_LOG(ERR, PMD,
+ "Failed to alloc memory for fdt_path\n");
+ return -1;
+ }
+
+ RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n",
+ dev->addr.name, dev->addr.fdt_path);
+
+ compat_n = dev_uevent_find(uevent, "OF_COMPATIBLE_N=");
+ if (compat_n == NULL) {
+ RTE_LOG(ERR, EAL, "No OF_COMPATIBLE_N found\n");
+ return -1;
+ }
+
+ n = strtoul(compat_n, &err, 0);
+ if (*err != '\n' && err != NULL) {
+ RTE_LOG(ERR, EAL, "Failed to parse OF_COMPATIBLE_N: %.10s\n",
+ err);
+ goto fail_fdt_path;
+ }
+
+ if (n == 0)
+ return 1; /* cannot match anything */
+ if (n > 9999) { /* match NNNN */
+ RTE_LOG(ERR, EAL, "OF_COMPATIBLE_N is invalid: %ld\n", n);
+ goto fail_fdt_path;
+ }
+
+ dev->id = calloc(n + 1, sizeof(*dev->id));
+ if (dev->id == NULL) {
+ RTE_LOG(ERR, PMD, "Failed to alloc memory for ID\n");
+ free(dev->addr.fdt_path);
+ return -1;
+ }
+
+ for (i = 0; i < n; ++i) {
+ snprintf(compat, sizeof(compat), "OF_COMPATIBLE_%lu=", i);
+ const char *val;
+
+ val = dev_uevent_find(uevent, compat);
+ if (val == NULL) {
+ RTE_LOG(ERR, EAL, "%s was not found\n", compat);
+ goto fail_id;
+ }
+
+ dev->id[i]._compatible = strdup_until_nl(val);
+ if (dev->id[i]._compatible == NULL) {
+ RTE_LOG(ERR, PMD,
+ "Failed to alloc memory for compatible\n");
+ goto fail_id;
+ }
+
+ RTE_LOG(DEBUG, EAL, " compatible: %s\n",
+ dev->id[i].compatible);
+ }
+
+ dev->id[n]._compatible = NULL; /* mark last one */
+
+ return 0;
+
+fail_id:
+ while (i-- >= 0)
+ free(dev->id[i]._compatible);
+ free(dev->id);
+fail_fdt_path:
+ free(dev->addr.fdt_path);
+ return -1;
+}
+
+static void
+dev_content_free(struct rte_soc_device *dev)
+{
+ int i;
+
+ if (dev->addr.fdt_path)
+ free(dev->addr.fdt_path);
+
+ if (dev->id != NULL) {
+ for (i = 0; dev->id[i]._compatible; ++i)
+ free(dev->id[i]._compatible);
+
+ free(dev->id);
+ dev->id = NULL;
+ }
+}
+
+/**
+ * Scan one SoC sysfs entry, and fill the devices list from it.
+ * We require to have the uevent file with records: OF_FULLNAME and
+ * OF_COMPATIBLE array (with at least one entry). Otherwise, such device
+ * is skipped.
+ */
+static int
+soc_scan_one(const char *dirname, const char *name)
+{
+ struct rte_soc_device *dev;
+ char *uevent;
+ int ret;
+
+ uevent = dev_read_uevent(dirname);
+ if (uevent == NULL)
+ return -1;
+
+ if (uevent[0] == '\0') {
+ /* ignore directory without uevent file */
+ free(uevent);
+ return 1;
+ }
+
+ dev = malloc(sizeof(*dev) + strlen(name) + 1);
+ if (dev == NULL) {
+ RTE_LOG(ERR, PMD, "Failed to alloc memory for %s\n", name);
+ free(uevent);
+ return -1;
+ }
+
+ memset(dev, 0, sizeof(*dev));
+ dev->addr.name = (char *) (dev + 1);
+ strcpy(dev->addr.name, name);
+
+ ret = dev_parse_uevent(dev, uevent);
+ if (ret)
+ goto fail;
+ free(uevent); /* not needed anymore */
+
+ /* device is valid, add in list (sorted) */
+ if (TAILQ_EMPTY(&soc_device_list)) {
+ TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+ } else {
+ struct rte_soc_device *dev2;
+
+ TAILQ_FOREACH(dev2, &soc_device_list, next) {
+ ret = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr);
+ if (ret > 0)
+ continue;
+
+ if (ret < 0) {
+ TAILQ_INSERT_BEFORE(dev2, dev, next);
+ } else { /* already registered */
+ dev_content_free(dev2);
+ dev2->addr.fdt_path = dev->addr.fdt_path;
+ dev2->id = dev->id;
+ free(dev);
+ }
+ return 0;
+ }
+ TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+ }
+
+ return 0;
+
+fail:
+ free(uevent);
+ dev_content_free(dev);
+ free(dev);
+ return ret;
+}
+
+int
+rte_eal_soc_scan_platform_bus(void)
+{
+ struct dirent *e;
+ DIR *dir;
+ char dirname[PATH_MAX];
+
+ dir = opendir(soc_get_sysfs_path());
+ if (dir == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ while ((e = readdir(dir)) != NULL) {
+ if (e->d_name[0] == '.')
+ continue;
+
+ snprintf(dirname, sizeof(dirname), "%s/%s",
+ soc_get_sysfs_path(), e->d_name);
+ if (soc_scan_one(dirname, e->d_name) < 0)
+ goto error;
+ }
+ closedir(dir);
+ return 0;
+
+error:
+ closedir(dir);
+ return -1;
+}
+
/* Init the SoC EAL subsystem */
int
rte_eal_soc_init(void)
--
2.7.4
^ permalink raw reply related
* [PATCH v6 14/21] eal/soc: add intr_handle
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/common/include/rte_soc.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 40490b9..38f897d 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
#include <rte_dev.h>
#include <rte_eal.h>
#include <rte_debug.h>
+#include <rte_interrupts.h>
extern struct soc_driver_list soc_driver_list;
/**< Global list of SoC Drivers */
@@ -80,6 +81,7 @@ struct rte_soc_device {
struct rte_device device; /**< Inherit code device */
struct rte_soc_addr addr; /**< SoC device Location */
struct rte_soc_id *id; /**< SoC device ID list */
+ struct rte_intr_handle intr_handle; /**< Interrupt handle */
struct rte_soc_driver *driver; /**< Associated driver */
};
--
2.7.4
^ permalink raw reply related
* [PATCH v6 13/21] eal/soc: add drv_flags
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index fb5ea7b..40490b9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -123,8 +123,18 @@ struct rte_soc_driver {
soc_scan_t *scan_fn; /**< Callback for scanning SoC bus*/
soc_match_t *match_fn; /**< Callback to match dev<->drv */
const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+ uint32_t drv_flags; /**< Control handling of device */
};
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound even if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE 0x0010
+
/**
* Utility function to write a SoC device name, this device name can later be
* used to retrieve the corresponding rte_soc_addr using above functions.
--
2.7.4
^ permalink raw reply related
* [PATCH v6 12/21] eal/soc: extend and utilize devargs
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/common/eal_common_dev.c | 27 +++++++++----
lib/librte_eal/common/eal_common_devargs.c | 17 ++++++++
lib/librte_eal/common/eal_common_soc.c | 61 ++++++++++++++++++++++++-----
lib/librte_eal/common/include/rte_devargs.h | 8 ++++
lib/librte_eal/common/include/rte_soc.h | 24 ++++++++++++
5 files changed, 120 insertions(+), 17 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 457d227..ebbcf47 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -107,17 +107,23 @@ rte_eal_dev_init(void)
int rte_eal_dev_attach(const char *name, const char *devargs)
{
- struct rte_pci_addr addr;
+ struct rte_soc_addr soc_addr;
+ struct rte_pci_addr pci_addr;
if (name == NULL || devargs == NULL) {
RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
return -EINVAL;
}
- if (eal_parse_pci_DomBDF(name, &addr) == 0) {
- if (rte_eal_pci_probe_one(&addr) < 0)
+ memset(&soc_addr, 0, sizeof(soc_addr));
+ if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+ if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+ free(soc_addr.name);
+ goto err;
+ }
+ } else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+ if (rte_eal_pci_probe_one(&pci_addr) < 0)
goto err;
-
} else {
if (rte_eal_vdev_init(name, devargs))
goto err;
@@ -132,15 +138,22 @@ err:
int rte_eal_dev_detach(const char *name)
{
- struct rte_pci_addr addr;
+ struct rte_soc_addr soc_addr;
+ struct rte_pci_addr pci_addr;
if (name == NULL) {
RTE_LOG(ERR, EAL, "Invalid device provided.\n");
return -EINVAL;
}
- if (eal_parse_pci_DomBDF(name, &addr) == 0) {
- if (rte_eal_pci_detach(&addr) < 0)
+ memset(&soc_addr, 0, sizeof(soc_addr));
+ if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+ if (rte_eal_soc_detach(&soc_addr) < 0) {
+ free(soc_addr.name);
+ goto err;
+ }
+ } else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+ if (rte_eal_pci_detach(&pci_addr) < 0)
goto err;
} else {
if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
#include <string.h>
#include <rte_pci.h>
+#include <rte_soc.h>
#include <rte_devargs.h>
#include "eal_private.h"
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
goto fail;
break;
+
+ case RTE_DEVTYPE_WHITELISTED_SOC:
+ case RTE_DEVTYPE_BLACKLISTED_SOC:
+ /* try to parse soc device with prefix "soc:" */
+ if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+ goto fail;
+ break;
+
case RTE_DEVTYPE_VIRTUAL:
/* save driver name */
ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
devargs->pci.addr.devid,
devargs->pci.addr.function,
devargs->args);
+ else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+ fprintf(f, " SoC whitelist %s %s\n",
+ devargs->soc.addr.name,
+ devargs->soc.addr.fdt_path);
+ else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+ fprintf(f, " SoC blacklist %s %s\n",
+ devargs->soc.addr.name,
+ devargs->soc.addr.fdt_path);
else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
fprintf(f, " VIRTUAL %s %s\n",
devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 256cef8..44f5559 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
#include <rte_log.h>
#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
#include <rte_soc.h>
#include "eal_private.h"
@@ -70,6 +72,21 @@ rte_eal_soc_match_compat(struct rte_soc_driver *drv,
return 1;
}
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+ struct rte_devargs *devargs;
+
+ TAILQ_FOREACH(devargs, &devargs_list, next) {
+ if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+ devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+ continue;
+ if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+ return devargs;
+ }
+
+ return NULL;
+}
+
static int
rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
struct rte_soc_device *dev)
@@ -85,6 +102,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
return ret;
}
+ RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+ dev->addr.name, dev->device.numa_node);
+ RTE_LOG(DEBUG, EAL, " probe driver %s\n", drv->driver.name);
+
+ /* no initialization when blacklisted, return without error */
+ if (dev->device.devargs != NULL
+ && dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+ RTE_LOG(DEBUG, EAL,
+ " device is blacklisted, skipping\n");
+ return ret;
+ }
+
dev->driver = drv;
RTE_VERIFY(drv->probe != NULL);
return drv->probe(drv, dev);
@@ -129,8 +158,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
return ret;
}
- RTE_LOG(DEBUG, EAL, "SoC device %s\n",
- dev->addr.name);
+ RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+ dev->addr.name, dev->device.numa_node);
RTE_LOG(DEBUG, EAL, " remove driver: %s\n", drv->driver.name);
@@ -233,17 +262,29 @@ int
rte_eal_soc_probe(void)
{
struct rte_soc_device *dev = NULL;
+ struct rte_devargs *devargs = NULL;
int ret = 0;
+ int probe_all = 0;
+
+ if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+ probe_all = 1;
TAILQ_FOREACH(dev, &soc_device_list, next) {
- ret = soc_probe_all_drivers(dev);
- if (ret < 0) {
- RTE_LOG(DEBUG, EAL, "Requested device %s"
- " cannot be used\n", dev->addr.name);
- /* Failure for a particular device is logged and
- * ignored
- */
- }
+
+ /* set devargs in SoC structure */
+ devargs = soc_devargs_lookup(dev);
+ if (devargs != NULL)
+ dev->device.devargs = devargs;
+
+ /* probe all or only whitelisted devices */
+ if (probe_all)
+ ret = soc_probe_all_drivers(dev);
+ else if (devargs != NULL &&
+ devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+ ret = soc_probe_all_drivers(dev);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Requested device %s "
+ "cannot be used\n", dev->addr.name);
}
return ret;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 88120a1..b5dd436 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
#include <stdio.h>
#include <sys/queue.h>
#include <rte_pci.h>
+#include <rte_soc.h>
/**
* Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
enum rte_devtype {
RTE_DEVTYPE_WHITELISTED_PCI,
RTE_DEVTYPE_BLACKLISTED_PCI,
+ RTE_DEVTYPE_WHITELISTED_SOC,
+ RTE_DEVTYPE_BLACKLISTED_SOC,
RTE_DEVTYPE_VIRTUAL,
};
@@ -83,6 +86,11 @@ struct rte_devargs {
/** PCI location. */
struct rte_pci_addr addr;
} pci;
+ /** Used if type is RTE_DEVTYPE_*_SOC. */
+ struct {
+ /** SoC location. */
+ struct rte_soc_addr addr;
+ } soc;
/** Used if type is RTE_DEVTYPE_VIRTUAL. */
struct {
/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 53a321b..fb5ea7b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -164,6 +164,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
}
/**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ * - 0 on success
+ * - 1 when not a SoC spec
+ * - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+ if (strstr(spec, "soc:") == spec) {
+ addr->name = strdup(spec + 4);
+ if (addr->name == NULL)
+ return -1;
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
* Default function for matching the Soc driver with device. Each driver can
* either use this function or define their own soc matching function.
* This function relies on the compatible string extracted from sysfs. But,
--
2.7.4
^ permalink raw reply related
* [PATCH v6 10/21] eal/soc: init SoC infra from EAL
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/bsdapp/eal/Makefile | 1 +
lib/librte_eal/bsdapp/eal/eal.c | 4 +++
lib/librte_eal/bsdapp/eal/eal_soc.c | 46 ++++++++++++++++++++++++++++
lib/librte_eal/common/eal_private.h | 10 +++++++
lib/librte_eal/linuxapp/eal/Makefile | 1 +
lib/librte_eal/linuxapp/eal/eal.c | 3 ++
lib/librte_eal/linuxapp/eal/eal_soc.c | 56 +++++++++++++++++++++++++++++++++++
7 files changed, 121 insertions(+)
create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index a15b762..42b3a2b 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 9b93da3..2d62b9d 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
#include <rte_string_fns.h>
#include <rte_cpuflags.h>
#include <rte_interrupts.h>
+#include <rte_soc.h>
#include <rte_pci.h>
#include <rte_dev.h>
#include <rte_devargs.h>
@@ -564,6 +565,9 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_init() < 0)
rte_panic("Cannot init PCI\n");
+ if (rte_eal_soc_init() < 0)
+ rte_panic("Cannot init SoC\n");
+
eal_check_mem_on_local_socket();
if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..cb297ff
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,46 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+ return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 0e8d6f7..d810f9f 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -122,6 +122,16 @@ int rte_eal_pci_init(void);
struct rte_soc_driver;
struct rte_soc_device;
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ * 0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
struct rte_pci_driver;
struct rte_pci_device;
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index a520477..59e30fa 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -65,6 +65,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 00af21c..098ba02 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -810,6 +810,9 @@ rte_eal_init(int argc, char **argv)
rte_panic("Cannot init VFIO\n");
#endif
+ if (rte_eal_soc_init() < 0)
+ rte_panic("Cannot init SoC\n");
+
if (rte_eal_memory_init() < 0)
rte_panic("Cannot init memory\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..04848b9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,56 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+ return 0;
+}
--
2.7.4
^ permalink raw reply related
* [PATCH v6 09/21] eal: introduce command line enable SoC option
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Support --enable-soc. SoC support is disabled by default.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: Change --no-soc to --enable-soc; disabled by default]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/testpmd_app_ug/run_app.rst | 4 ++++
lib/librte_eal/common/eal_common_options.c | 5 +++++
lib/librte_eal/common/eal_internal_cfg.h | 1 +
lib/librte_eal/common/eal_options.h | 2 ++
4 files changed, 12 insertions(+)
diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index d7c5120..4dafe5f 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
Use malloc instead of hugetlbfs.
+* ``--enable-soc``
+
+ Enable SoC framework support
+
Testpmd Command-line Options
----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6ca8af1..2156ab3 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -75,6 +75,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_ENABLE_SOC, 0, NULL, OPT_ENABLE_SOC_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 },
@@ -843,6 +844,10 @@ eal_parse_common_option(int opt, const char *optarg,
break;
/* long options */
+ case OPT_ENABLE_SOC_NUM:
+ conf->enable_soc = 1;
+ break;
+
case OPT_HUGE_UNLINK_NUM:
conf->hugepage_unlink = 1;
break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..2a6e3ea 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
unsigned hugepage_unlink; /**< true to unlink backing files */
volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
volatile unsigned no_pci; /**< true to disable PCI */
+ volatile unsigned enable_soc; /**< true to enable SoC */
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..6e679c3 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -49,6 +49,8 @@ enum {
OPT_BASE_VIRTADDR_NUM,
#define OPT_CREATE_UIO_DEV "create-uio-dev"
OPT_CREATE_UIO_DEV_NUM,
+#define OPT_ENABLE_SOC "enable-soc"
+ OPT_ENABLE_SOC_NUM,
#define OPT_FILE_PREFIX "file-prefix"
OPT_FILE_PREFIX_NUM,
#define OPT_HUGE_DIR "huge-dir"
--
2.7.4
^ permalink raw reply related
* [PATCH v6 08/21] eal/soc: implement SoC device list and dump
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
SoC devices would be linked in a separate list (from PCI). This is used for
probe function.
A helper for dumping the device list is added.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 2 ++
lib/librte_eal/common/eal_common_soc.c | 34 +++++++++++++++++++++++++
lib/librte_eal/common/include/rte_soc.h | 9 +++++++
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 2 ++
4 files changed, 47 insertions(+)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cf6fb8e..86e3cfd 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,11 +171,13 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_dump;
rte_eal_soc_register;
rte_eal_soc_unregister;
rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
+ soc_device_list;
soc_driver_list;
} DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 56135ed..5dcddc5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stddef.h>
+#include <stdio.h>
#include <sys/queue.h>
#include <rte_log.h>
@@ -40,6 +42,38 @@
/* Global SoC driver list */
struct soc_driver_list soc_driver_list =
TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+ TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+ int i;
+
+ fprintf(f, "%s", dev->addr.name);
+ fprintf(f, " - fdt_path: %s\n",
+ dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
+
+ for (i = 0; dev->id && dev->id[i].compatible; ++i)
+ fprintf(f, " %s\n", dev->id[i].compatible);
+
+ return 0;
+}
+
+/* dump devices on the bus to an output stream */
+void
+rte_eal_soc_dump(FILE *f)
+{
+ struct rte_soc_device *dev = NULL;
+
+ if (!f)
+ return;
+
+ TAILQ_FOREACH(dev, &soc_device_list, next) {
+ soc_dump_one_device(f, dev);
+ }
+}
/* register a driver */
void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 23b06a9..347e611 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,8 +56,12 @@ extern "C" {
extern struct soc_driver_list soc_driver_list;
/**< Global list of SoC Drivers */
+extern struct soc_device_list soc_device_list;
+/**< Global list of SoC Devices */
TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+
struct rte_soc_id {
const char *compatible; /**< OF compatible specification */
@@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
}
/**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
+
+/**
* Register a SoC driver.
*/
void rte_eal_soc_register(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index ab6b985..0155025 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,11 +175,13 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_dump;
rte_eal_soc_register;
rte_eal_soc_unregister;
rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
+ soc_device_list;
soc_driver_list;
} DPDK_16.07;
--
2.7.4
^ permalink raw reply related
* [PATCH v6 07/21] eal/soc: add SoC PMD register/unregister logic
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Registeration of a SoC driver through a helper RTE_PMD_REGISTER_SOC
(on the lines of RTE_PMD_REGISTER_PCI). soc_driver_list stores all the
registered drivers.
Test case has been introduced to verify the registration and
deregistration.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: update PMD registration method]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
app/test/test_soc.c | 111 ++++++++++++++++++++++++
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +
lib/librte_eal/common/eal_common_soc.c | 56 ++++++++++++
lib/librte_eal/common/include/rte_soc.h | 26 ++++++
lib/librte_eal/linuxapp/eal/Makefile | 1 +
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +
6 files changed, 200 insertions(+)
create mode 100644 lib/librte_eal/common/eal_common_soc.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index 916a863..ac03e64 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -75,6 +75,108 @@ static int test_compare_addr(void)
free(a2.name);
free(a1.name);
free(a0.name);
+
+ return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+ struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+ .soc_drv = {
+ .driver = {
+ .name = "empty_pmd0"
+ },
+ },
+};
+
+struct test_wrapper empty_pmd1 = {
+ .soc_drv = {
+ .driver = {
+ .name = "empty_pmd1"
+ },
+ },
+};
+
+static int
+count_registered_socdrvs(void)
+{
+ int i;
+ struct rte_soc_driver *drv;
+
+ i = 0;
+ TAILQ_FOREACH(drv, &soc_driver_list, next)
+ i += 1;
+
+ return i;
+}
+
+static int
+test_register_unregister(void)
+{
+ struct rte_soc_driver *drv;
+ int count;
+
+ rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+ TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+ "No PMD is present but the empty_pmd0 should be there");
+ drv = TAILQ_FIRST(&soc_driver_list);
+ TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
+ "The registered PMD is not empty_pmd0 but '%s'",
+ drv->driver.name);
+
+ rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+ count = count_registered_socdrvs();
+ TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+ rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+ count = count_registered_socdrvs();
+ TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+ rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+ printf("%s has been successful\n", __func__);
+ return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+ TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+ struct rte_soc_driver *drv;
+
+ /* no real drivers for the test */
+ while (!TAILQ_EMPTY(&soc_driver_list)) {
+ drv = TAILQ_FIRST(&soc_driver_list);
+ rte_eal_soc_unregister(drv);
+ TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+ }
+
+ return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+ struct rte_soc_driver *drv;
+
+ /* bring back real drivers after the test */
+ while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+ drv = TAILQ_FIRST(&real_soc_driver_list);
+ TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+ rte_eal_soc_register(drv);
+ }
+
return 0;
}
@@ -84,6 +186,15 @@ test_soc(void)
if (test_compare_addr())
return -1;
+ if (test_soc_setup())
+ return -1;
+
+ if (test_register_unregister())
+ return -1;
+
+ if (test_soc_cleanup())
+ return -1;
+
return 0;
}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 11d9f59..cf6fb8e 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,8 +171,11 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_register;
+ rte_eal_soc_unregister;
rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
+ soc_driver_list;
} DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..56135ed
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,56 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+/* Global SoC driver list */
+struct soc_driver_list soc_driver_list =
+ TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+ TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+ TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 5c32737..23b06a9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -51,8 +51,14 @@ extern "C" {
#include <string.h>
#include <rte_dev.h>
+#include <rte_eal.h>
#include <rte_debug.h>
+extern struct soc_driver_list soc_driver_list;
+/**< Global list of SoC Drivers */
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
struct rte_soc_id {
const char *compatible; /**< OF compatible specification */
uint64_t priv_data; /**< SoC Driver specific data */
@@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
return strcmp(a0->name, a1->name);
}
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+/** Helper for SoC device registeration from PMD Drivers */
+#define RTE_PMD_REGISTER_SOC(nm, soc_drv) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{\
+ (soc_drv).driver.name = RTE_STR(nm);\
+ rte_eal_soc_register(&soc_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..a520477 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 22b5b59..ab6b985 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,8 +175,11 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_register;
+ rte_eal_soc_unregister;
rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
+ soc_driver_list;
} DPDK_16.07;
--
2.7.4
^ permalink raw reply related
* [PATCH v6 06/21] eal/soc: introduce very essential SoC infra definitions
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Define initial structures and functions for the SoC infrastructure.
This patch supports only a very minimal functions for now.
More features will be added in the following commits.
Includes rte_device/rte_driver inheritance of
rte_soc_device/rte_soc_driver.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
app/test/Makefile | 1 +
app/test/test_soc.c | 90 +++++++++++++++++++++
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_private.h | 4 +
lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
5 files changed, 234 insertions(+), 1 deletion(-)
create mode 100644 app/test/test_soc.c
create mode 100644 lib/librte_eal/common/include/rte_soc.h
diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..30295af 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,7 @@ APP = test
#
SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
SRCS-y += test.c
+SRCS-y += test_soc.c
SRCS-y += resource.c
SRCS-y += test_resource.c
test_resource.res: test_resource.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..916a863
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,90 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+ char *c = strdup(s);
+
+ if (c == NULL)
+ rte_panic("failed to strdup '%s'\n", s);
+
+ return c;
+}
+
+static int test_compare_addr(void)
+{
+ struct rte_soc_addr a0;
+ struct rte_soc_addr a1;
+ struct rte_soc_addr a2;
+
+ a0.name = safe_strdup("ethernet0");
+ a0.fdt_path = NULL;
+
+ a1.name = safe_strdup("ethernet0");
+ a1.fdt_path = NULL;
+
+ a2.name = safe_strdup("ethernet1");
+ a2.fdt_path = NULL;
+
+ TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+ "Failed to compare two soc addresses that equal");
+ TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+ "Failed to compare two soc addresses that differs");
+
+ free(a2.name);
+ free(a1.name);
+ free(a0.name);
+ return 0;
+}
+
+static int
+test_soc(void)
+{
+ if (test_compare_addr())
+ return -1;
+
+ return 0;
+}
+
+REGISTER_TEST_COMMAND(soc_autotest, test_soc);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..b414008 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
INC := rte_branch_prediction.h rte_common.h
INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
INC += rte_per_lcore.h rte_random.h
INC += rte_tailq.h rte_interrupts.h rte_alarm.h
INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index c8c2131..0e8d6f7 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <rte_pci.h>
+#include <rte_soc.h>
/**
* Initialize the memzone subsystem (private to eal).
@@ -118,6 +119,9 @@ int rte_eal_log_init(const char *id, int facility);
*/
int rte_eal_pci_init(void);
+struct rte_soc_driver;
+struct rte_soc_device;
+
struct rte_pci_driver;
struct rte_pci_device;
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..5c32737
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,138 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_debug.h>
+
+struct rte_soc_id {
+ const char *compatible; /**< OF compatible specification */
+ uint64_t priv_data; /**< SoC Driver specific data */
+};
+
+struct rte_soc_addr {
+ char *name; /**< name used in sysfs */
+ char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+ TAILQ_ENTRY(rte_soc_device) next; /**< Next probed SoC device */
+ struct rte_device device; /**< Inherit code device */
+ struct rte_soc_addr addr; /**< SoC device Location */
+ struct rte_soc_id *id; /**< SoC device ID list */
+ struct rte_soc_driver *driver; /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Probe function for the driver called during SoC probing.
+ */
+typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Remove function for the driver called during hotplugging.
+ */
+typedef int (soc_remove_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+ TAILQ_ENTRY(rte_soc_driver) next; /**< Next in list */
+ struct rte_driver driver; /**< Inherit core driver. */
+ soc_probe_t *probe; /**< Device probe */
+ soc_remove_t *remove; /**< Device remove */
+ const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ * The SoC address
+ * @param output
+ * The output buffer string
+ * @param size
+ * The output buffer size
+ * @return
+ * 0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+ char *output, size_t size)
+{
+ int ret;
+
+ RTE_VERIFY(addr != NULL);
+ RTE_VERIFY(size >= strlen(addr->name));
+ ret = snprintf(output, size, "%s", addr->name);
+ RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+ const struct rte_soc_addr *a1)
+{
+ if (a0 == NULL || a1 == NULL)
+ return -1;
+
+ RTE_VERIFY(a0->name != NULL);
+ RTE_VERIFY(a1->name != NULL);
+
+ return strcmp(a0->name, a1->name);
+}
+
+#endif
--
2.7.4
^ permalink raw reply related
* [PATCH v6 05/21] eal: define container macro
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/common/include/rte_common.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8152bd9 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,24 @@ rte_bsf32(uint32_t v)
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#endif
+/**
+ * Return pointer to the wrapping struct instance.
+ * Example:
+ *
+ * struct wrapper {
+ * ...
+ * struct child c;
+ * ...
+ * };
+ *
+ * struct child *x = obtain(...);
+ * struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(p, type, member) \
+ ((type *) (((char *) (p)) - offsetof(type, member)))
+#endif
+
#define _RTE_STR(x) #x
/** Take a macro value and get a string version of it */
#define RTE_STR(x) _RTE_STR(x)
--
2.7.4
^ permalink raw reply related
* [PATCH v6 02/21] eal: generalize PCI map/unmap resource to EAL
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
The functions pci_map_resource, pci_unmap_resource are generic so the
pci_* prefix can be omitted. The functions are moved to the
eal_common_dev.c so they can be reused by other infrastructure.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/bsdapp/eal/eal_pci.c | 2 +-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 2 ++
lib/librte_eal/common/eal_common_dev.c | 39 +++++++++++++++++++++++++
lib/librte_eal/common/eal_common_pci.c | 39 -------------------------
lib/librte_eal/common/eal_common_pci_uio.c | 16 +++++-----
lib/librte_eal/common/include/rte_dev.h | 32 ++++++++++++++++++++
lib/librte_eal/common/include/rte_pci.h | 32 --------------------
lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 5 ++--
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 2 ++
10 files changed, 89 insertions(+), 82 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 8b3ed88..7ed0115 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -228,7 +228,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
/* if matching map is found, then use it */
offset = res_idx * pagesz;
- mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+ mapaddr = rte_eal_map_resource(NULL, fd, (off_t)offset,
(size_t)dev->mem_resource[res_idx].len, 0);
close(fd);
if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2f81f7c..11d9f59 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -170,6 +170,8 @@ DPDK_16.11 {
rte_delay_us_callback_register;
rte_eal_dev_attach;
rte_eal_dev_detach;
+ rte_eal_map_resource;
+ rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 4f3b493..457d227 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -36,6 +36,7 @@
#include <string.h>
#include <inttypes.h>
#include <sys/queue.h>
+#include <sys/mman.h>
#include <rte_dev.h>
#include <rte_devargs.h>
@@ -151,3 +152,41 @@ err:
RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", name);
return -EINVAL;
}
+
+/* map a particular resource from a file */
+void *
+rte_eal_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+ int additional_flags)
+{
+ void *mapaddr;
+
+ /* Map the Memory resource of device */
+ mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | additional_flags, fd, offset);
+ if (mapaddr == MAP_FAILED) {
+ RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s"
+ " (%p)\n", __func__, fd, requested_addr,
+ (unsigned long)size, (unsigned long)offset,
+ strerror(errno), mapaddr);
+ } else
+ RTE_LOG(DEBUG, EAL, " Device memory mapped at %p\n", mapaddr);
+
+ return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+rte_eal_unmap_resource(void *requested_addr, size_t size)
+{
+ if (requested_addr == NULL)
+ return;
+
+ /* Unmap the Memory resource of device */
+ if (munmap(requested_addr, size)) {
+ RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+ __func__, requested_addr, (unsigned long)size,
+ strerror(errno));
+ } else
+ RTE_LOG(DEBUG, EAL, " Device memory unmapped at %p\n",
+ requested_addr);
+}
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 638cd86..464acc1 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -67,7 +67,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/queue.h>
-#include <sys/mman.h>
#include <rte_interrupts.h>
#include <rte_log.h>
@@ -114,44 +113,6 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
return NULL;
}
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
- int additional_flags)
-{
- void *mapaddr;
-
- /* Map the PCI memory resource of device */
- mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
- MAP_SHARED | additional_flags, fd, offset);
- if (mapaddr == MAP_FAILED) {
- RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
- __func__, fd, requested_addr,
- (unsigned long)size, (unsigned long)offset,
- strerror(errno), mapaddr);
- } else
- RTE_LOG(DEBUG, EAL, " PCI memory mapped at %p\n", mapaddr);
-
- return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
- if (requested_addr == NULL)
- return;
-
- /* Unmap the PCI memory resource of device */
- if (munmap(requested_addr, size)) {
- RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
- __func__, requested_addr, (unsigned long)size,
- strerror(errno));
- } else
- RTE_LOG(DEBUG, EAL, " PCI memory unmapped at %p\n",
- requested_addr);
-}
-
/*
* If vendor/device ID match, call the probe() function of the
* driver.
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
index 367a681..3402518 100644
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ b/lib/librte_eal/common/eal_common_pci_uio.c
@@ -75,9 +75,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
return -1;
}
- void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
- fd, (off_t)uio_res->maps[i].offset,
- (size_t)uio_res->maps[i].size, 0);
+ void *mapaddr = rte_eal_map_resource(
+ uio_res->maps[i].addr, fd,
+ (off_t)uio_res->maps[i].offset,
+ (size_t)uio_res->maps[i].size,
+ 0);
/* fd is not needed in slave process, close it */
close(fd);
if (mapaddr != uio_res->maps[i].addr) {
@@ -88,11 +90,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
if (mapaddr != MAP_FAILED) {
/* unmap addrs correctly mapped */
for (j = 0; j < i; j++)
- pci_unmap_resource(
+ rte_eal_unmap_resource(
uio_res->maps[j].addr,
(size_t)uio_res->maps[j].size);
/* unmap addr wrongly mapped */
- pci_unmap_resource(mapaddr,
+ rte_eal_unmap_resource(mapaddr,
(size_t)uio_res->maps[i].size);
}
return -1;
@@ -150,7 +152,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
return 0;
error:
for (i = 0; i < map_idx; i++) {
- pci_unmap_resource(uio_res->maps[i].addr,
+ rte_eal_unmap_resource(uio_res->maps[i].addr,
(size_t)uio_res->maps[i].size);
rte_free(uio_res->maps[i].path);
}
@@ -167,7 +169,7 @@ pci_uio_unmap(struct mapped_pci_resource *uio_res)
return;
for (i = 0; i != uio_res->nb_maps; i++) {
- pci_unmap_resource(uio_res->maps[i].addr,
+ rte_eal_unmap_resource(uio_res->maps[i].addr,
(size_t)uio_res->maps[i].size);
if (rte_eal_process_type() == RTE_PROC_PRIMARY)
rte_free(uio_res->maps[i].path);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 6975b9f..5be6326 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -235,6 +235,38 @@ int rte_eal_dev_attach(const char *name, const char *devargs);
*/
int rte_eal_dev_detach(const char *name);
+/*
+ * @internal
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ * The starting address for the new mapping range.
+ * @param fd
+ * The file descriptor.
+ * @param offset
+ * The offset for the mapping range.
+ * @param size
+ * The size for the mapping range.
+ * @param additional_flags
+ * The additional flags for the mapping range.
+ * @return
+ * - On success, the function returns a pointer to the mapped area.
+ * - On error, the value MAP_FAILED is returned.
+ */
+void *rte_eal_map_resource(void *requested_addr, int fd, off_t offset,
+ size_t size, int additional_flags);
+
+/**
+ * @internal
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ * The address for the unmapping range.
+ * @param size
+ * The size for the unmapping range.
+ */
+void rte_eal_unmap_resource(void *requested_addr, size_t size);
+
#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
#define RTE_PMD_EXPORT_NAME(name, idx) \
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 2c7046f..7d6eef5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -399,38 +399,6 @@ int rte_eal_pci_map_device(struct rte_pci_device *dev);
void rte_eal_pci_unmap_device(struct rte_pci_device *dev);
/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- * The starting address for the new mapping range.
- * @param fd
- * The file descriptor.
- * @param offset
- * The offset for the mapping range.
- * @param size
- * The size for the mapping range.
- * @param additional_flags
- * The additional flags for the mapping range.
- * @return
- * - On success, the function returns a pointer to the mapped area.
- * - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
- size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- * The address for the unmapping range.
- * @param size
- * The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
* Probe the single PCI device.
*
* Scan the content of the PCI bus, and find the pci device specified by pci
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..5c34421 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -347,7 +347,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
if (pci_map_addr == NULL)
pci_map_addr = pci_find_max_end_va();
- mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+ mapaddr = rte_eal_map_resource(pci_map_addr, fd, 0,
(size_t)dev->mem_resource[res_idx].len, 0);
close(fd);
if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 5f478c5..5ad8cbe 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -465,7 +465,8 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
void *map_addr = NULL;
if (memreg[0].size) {
/* actual map of first part */
- map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+ map_addr = rte_eal_map_resource(bar_addr,
+ vfio_dev_fd,
memreg[0].offset,
memreg[0].size,
MAP_FIXED);
@@ -477,7 +478,7 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
void *second_addr = RTE_PTR_ADD(bar_addr,
memreg[1].offset -
(uintptr_t)reg.offset);
- map_addr = pci_map_resource(second_addr,
+ map_addr = rte_eal_map_resource(second_addr,
vfio_dev_fd, memreg[1].offset,
memreg[1].size,
MAP_FIXED);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 83721ba..22b5b59 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,6 +174,8 @@ DPDK_16.11 {
rte_delay_us_callback_register;
rte_eal_dev_attach;
rte_eal_dev_detach;
+ rte_eal_map_resource;
+ rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
--
2.7.4
^ permalink raw reply related
* [PATCH v6 04/21] eal/linux: generalize PCI kernel driver extraction to EAL
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Generalize the PCI-specific pci_get_kernel_driver_by_path. The function
is general enough, we have just moved it to eal.c, changed the prefix to
rte_eal and provided it privately to other parts of EAL.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/bsdapp/eal/eal.c | 7 +++++++
lib/librte_eal/common/eal_private.h | 14 ++++++++++++++
lib/librte_eal/linuxapp/eal/eal.c | 29 +++++++++++++++++++++++++++++
lib/librte_eal/linuxapp/eal/eal_pci.c | 31 +------------------------------
4 files changed, 51 insertions(+), 30 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5271fc2..9b93da3 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -640,3 +640,10 @@ rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
{
return -ENOTSUP;
}
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename __rte_unused,
+ char *dri_name __rte_unused)
+{
+ return -ENOTSUP;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index b0c208a..c8c2131 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -269,6 +269,20 @@ int rte_eal_check_module(const char *module_name);
int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
/**
+ * Extract the kernel driver name from the absolute path to the driver.
+ *
+ * @param filename path to the driver ("<path-to-device>/driver")
+ * @path dri_name target buffer where to place the driver name
+ * (should be at least PATH_MAX long)
+ *
+ * @return
+ * -1 on failure
+ * 0 when successful
+ * 1 when there is no such driver
+ */
+int rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name);
+
+/**
* Get cpu core_id.
*
* This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 5f6676d..00af21c 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -969,3 +969,32 @@ error:
fclose(f);
return -1;
}
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+ int count;
+ char path[PATH_MAX];
+ char *name;
+
+ if (!filename || !dri_name)
+ return -1;
+
+ count = readlink(filename, path, PATH_MAX);
+ if (count >= PATH_MAX)
+ return -1;
+
+ /* For device does not have a driver */
+ if (count < 0)
+ return 1;
+
+ path[count] = '\0';
+
+ name = strrchr(path, '/');
+ if (name) {
+ strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index a03553f..e1cf9e8 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -78,35 +78,6 @@ pci_unbind_kernel_driver(struct rte_pci_device *dev)
return rte_eal_unbind_kernel_driver(devpath, devid);
}
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
- int count;
- char path[PATH_MAX];
- char *name;
-
- if (!filename || !dri_name)
- return -1;
-
- count = readlink(filename, path, PATH_MAX);
- if (count >= PATH_MAX)
- return -1;
-
- /* For device does not have a driver */
- if (count < 0)
- return 1;
-
- path[count] = '\0';
-
- name = strrchr(path, '/');
- if (name) {
- strncpy(dri_name, name + 1, strlen(name + 1) + 1);
- return 0;
- }
-
- return -1;
-}
-
/* Map pci device */
int
rte_eal_pci_map_device(struct rte_pci_device *dev)
@@ -354,7 +325,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
/* parse driver */
snprintf(filename, sizeof(filename), "%s/driver", dirname);
- ret = pci_get_kernel_driver_by_path(filename, driver);
+ ret = rte_eal_get_kernel_driver_by_path(filename, driver);
if (ret < 0) {
RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
free(dev);
--
2.7.4
^ permalink raw reply related
* [PATCH v6 03/21] eal/linux: generalize PCI kernel unbinding driver to EAL
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided
into two parts. First, determination of the path and string identification
of the device to be unbound. Second, the actual unbind operation which is
generic.
BSD implementation updated as ENOTSUP
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
Changes since v2:
- update BSD support for unbind kernel driver
---
lib/librte_eal/bsdapp/eal/eal.c | 7 +++++++
lib/librte_eal/bsdapp/eal/eal_pci.c | 4 ++--
lib/librte_eal/common/eal_private.h | 13 +++++++++++++
lib/librte_eal/linuxapp/eal/eal.c | 26 ++++++++++++++++++++++++++
lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
5 files changed, 57 insertions(+), 26 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 35e3117..5271fc2 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -633,3 +633,10 @@ rte_eal_process_type(void)
{
return rte_config.process_type;
}
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
+ const char *devid __rte_unused)
+{
+ return -ENOTSUP;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 7ed0115..703f034 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -89,11 +89,11 @@
/* unbind kernel driver for this device */
int
-pci_unbind_kernel_driver(struct rte_pci_device *dev __rte_unused)
+pci_unbind_kernel_driver(struct rte_pci_device *dev)
{
RTE_LOG(ERR, EAL, "RTE_PCI_DRV_FORCE_UNBIND flag is not implemented "
"for BSD\n");
- return -ENOTSUP;
+ return rte_eal_unbind_kernel_driver(dev);
}
/* Map pci device */
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6..b0c208a 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -256,6 +256,19 @@ int rte_eal_alarm_init(void);
int rte_eal_check_module(const char *module_name);
/**
+ * Unbind kernel driver bound to the device specified by the given devpath,
+ * and its string identification.
+ *
+ * @param devpath path to the device directory ("/sys/.../devices/<name>")
+ * @param devid identification of the device (<name>)
+ *
+ * @return
+ * -1 unbind has failed
+ * 0 module has been unbound
+ */
+int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
+
+/**
* Get cpu core_id.
*
* This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 2075282..5f6676d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -943,3 +943,29 @@ rte_eal_check_module(const char *module_name)
/* Module has been found */
return 1;
}
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
+{
+ char filename[PATH_MAX];
+ FILE *f;
+
+ snprintf(filename, sizeof(filename),
+ "%s/driver/unbind", devpath);
+
+ f = fopen(filename, "w");
+ if (f == NULL) /* device was not bound */
+ return 0;
+
+ if (fwrite(devid, strlen(devid), 1, f) == 0) {
+ RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
+ filename);
+ goto error;
+ }
+
+ fclose(f);
+ return 0;
+error:
+ fclose(f);
+ return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 876ba38..a03553f 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -59,38 +59,23 @@ int
pci_unbind_kernel_driver(struct rte_pci_device *dev)
{
int n;
- FILE *f;
- char filename[PATH_MAX];
- char buf[BUFSIZ];
+ char devpath[PATH_MAX];
+ char devid[BUFSIZ];
struct rte_pci_addr *loc = &dev->addr;
- /* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
- snprintf(filename, sizeof(filename),
- "%s/" PCI_PRI_FMT "/driver/unbind", pci_get_sysfs_path(),
+ /* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
+ snprintf(devpath, sizeof(devpath),
+ "%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
loc->domain, loc->bus, loc->devid, loc->function);
- f = fopen(filename, "w");
- if (f == NULL) /* device was not bound */
- return 0;
-
- n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
+ n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
loc->domain, loc->bus, loc->devid, loc->function);
- if ((n < 0) || (n >= (int)sizeof(buf))) {
+ if ((n < 0) || (n >= (int)sizeof(devid))) {
RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
- goto error;
- }
- if (fwrite(buf, n, 1, f) == 0) {
- RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
- filename);
- goto error;
+ return -1;
}
- fclose(f);
- return 0;
-
-error:
- fclose(f);
- return -1;
+ return rte_eal_unbind_kernel_driver(devpath, devid);
}
static int
--
2.7.4
^ permalink raw reply related
* [PATCH v6 01/21] eal: generalize PCI kernel driver enum to EAL
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
Changes since v0:
- fix compilation error due to missing include
---
lib/librte_eal/common/include/rte_dev.h | 12 ++++++++++++
lib/librte_eal/common/include/rte_pci.h | 9 ---------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 8840380..6975b9f 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -109,6 +109,18 @@ struct rte_mem_resource {
void *addr; /**< Virtual address, NULL when not mapped. */
};
+/**
+ * Kernel driver passthrough type
+ */
+enum rte_kernel_driver {
+ RTE_KDRV_UNKNOWN = 0,
+ RTE_KDRV_IGB_UIO,
+ RTE_KDRV_VFIO,
+ RTE_KDRV_UIO_GENERIC,
+ RTE_KDRV_NIC_UIO,
+ RTE_KDRV_NONE,
+};
+
/** Double linked list of device drivers. */
TAILQ_HEAD(rte_driver_list, rte_driver);
/** Double linked list of devices. */
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ce8847..2c7046f 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -135,15 +135,6 @@ struct rte_pci_addr {
struct rte_devargs;
-enum rte_kernel_driver {
- RTE_KDRV_UNKNOWN = 0,
- RTE_KDRV_IGB_UIO,
- RTE_KDRV_VFIO,
- RTE_KDRV_UIO_GENERIC,
- RTE_KDRV_NIC_UIO,
- RTE_KDRV_NONE,
-};
-
/**
* A structure describing a PCI device.
*/
--
2.7.4
^ permalink raw reply related
* [PATCH v6 00/21] Introduce SoC device/driver framework for EAL
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477310380-17944-1-git-send-email-shreyansh.jain@nxp.com>
Introduction:
=============
This patch set is direct derivative of Jan's original series [1],[2].
- This version is based on master HEAD (ca41215)
- In this, I am merging the series [11] back. It was initially part
of this set but I had split considering that those changes in PCI
were good standalone as well. But, 1) not much feedback was avail-
able and 2) this patchset is a use-case for those patches making
it easier to review. Just like what Jan had intended in original
series.
- SoC support is not enabled by default. It needs the 'enable-soc' toggle
on command line. This is primarily because this patchset is still
experimental and we would like to keep it isolated from non-SoC ops.
Though, it does impact the ABI.
Aim:
====
As of now EAL is primarly focused on PCI initialization/probing.
rte_eal_init()
|- rte_eal_pci_init(): Find PCI devices from sysfs
|- ...
|- rte_eal_memzone_init()
|- ...
`- rte_eal_pci_probe(): Driver<=>Device initialization
This patchset introduces SoC framework which would enable SoC drivers and
drivers to be plugged into EAL, very similar to how PCI drivers/devices are
done today.
This is a stripped down version of PCI framework which allows the SoC PMDs
to implement their own routines for detecting devices and linking devices to
drivers.
1) Changes to EAL
rte_eal_init()
|- rte_eal_pci_init(): Find PCI devices from sysfs
|- rte_eal_soc_init(): Calls PMDs->scan_fn
|- ...
|- rte_eal_memzone_init()
|- ...
|- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
`- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();
2) New device/driver structures:
- rte_soc_driver (inheriting rte_driver)
- rte_soc_device (inheriting rte_device)
- rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
respectively.
3) The SoC PMDs need to:
- define rte_soc_driver with necessary scan and match callbacks
- Register themselves using DRIVER_REGISTER_SOC()
- Implement respective bus scanning in the scan callbacks to add necessary
devices to SoC device list
- Implement necessary eth_dev_init/uninint for ethernet instances
4) Design considerations that are same as PCI:
- SoC initialization is being done through rte_eal_init(), just after PCI
initialization is done.
- As in case of PCI, probe is done after rte_eal_pci_probe() to link the
devices detected with the drivers registered.
- Device attach/detach functions are available and have been designed on
the lines of PCI framework.
- PMDs register using DRIVER_REGISTER_SOC, very similar to
DRIVER_REGISTER_PCI for PCI devices.
- Linked list of SoC driver and devices exists independent of the other
driver/device list, but inheriting rte_driver/rte_driver, these are
also part of a global list.
5) Design considerations that are different from PCI:
- Each driver implements its own scan and match function. PCI uses the BDF
format to read the device from sysfs, but this _may_not_ be a case for a
SoC ethernet device.
= This is an important change from initial proposal by Jan in [2].
Unlike his attempt to use /sys/bus/platform, this patch relies on the
PMD to detect the devices. This is because SoC may require specific or
additional info for device detection. Further, SoC may have embedded
devices/MACs which require initialization which cannot be covered
through sysfs parsing.
`-> Point (6) below is a side note to above.
= PCI based PMDs rely on EAL's capability to detect devices. This
proposal puts the onus on PMD to detect devices, add to soc_device_list
and wait for Probe. Matching, of device<=>driver is again PMD's
callback.
6) Adding default scan and match helpers for PMDs
- The design warrrants the PMDs implement their own scan of devices
on bus, and match routines for probe implementation.
This patch introduces helpers which can be used by PMDs for scan of
the platform bus and matching devices against the compatible string
extracted from the scan.
- Intention is to make it easier to integrate known SoC which expose
platform bus compliant information (compat, sys/bus/platform...).
- PMDs which have deviations from this standard model can implement and
hook their bus scanning and probe match callbacks while registering
driver.
Patchset Overview:
==================
- Patches 0001~0004 are from [11] - moving some PCI specific functions
and definitions to non-PCI area.
- Patches 0005~0008 introduce the base infrastructure and test case
- Patch 0009 is for command line support for no-soc, on lines of no-pci
- Patch 0010 enables EAL to handle SoC type devices
- Patch 0011 adds support for scan and probe callbacks and updates the test
framework with relevant test case.
- Patch 0012~0014 enable device argument, driver specific flags and
interrupt handling related basic infra. Subsequent patches build up on
them.
- Patch 0015~0016 add support for default function which PMDs can use for
scanning platform bus. These functions are optional and need to be hooked
to by PMDs.
- Patch 0017~0019 makes changes to PCI as well as ethdev code to remove
assumption that eth_driver is a PCI driver.
- Patch 0020 adds necessary ethdev probe/remove functions for PMDs to use
- Patch 0021 adds support for SoC driver/devices, along with probe/remove
functions for Cryptodev devices.
Future/Pending Changes:
=======================
- Device whitelisting/blacklist still relies on command line '-b' and '-c'
which are internally implemented using OPT_PCI_BLACKLIST/OPT_PCI_WHITELIST.
This needs to be changed to a generic form - OPT_DEV_*LIST - probably.
- No cryptodriver currently uses SoC framework - probably a example driver
can be created to demonstrate usage.
- test case for enable-soc command line parameter
- This patch impacts a couple of ABIs (rte_device/driver) and thus require
a patch for bump of libraries (if need be) and documentation.
[1] http://dpdk.org/ml/archives/dev/2016-January/030915.html
[2] http://www.dpdk.org/ml/archives/dev/2016-May/038486.html
[3] http://dpdk.org/ml/archives/dev/2016-August/045707.html
[4] http://dpdk.org/ml/archives/dev/2016-May/038948.html
[5] http://dpdk.org/ml/archives/dev/2016-May/038953.html
[6] http://dpdk.org/ml/archives/dev/2016-May/038487.html
[7] http://dpdk.org/ml/archives/dev/2016-May/038488.html
[8] http://dpdk.org/ml/archives/dev/2016-May/038489.html
[9] http://dpdk.org/ml/archives/dev/2016-May/038491.html
[10] http://dpdk.org/ml/archives/dev/2016-September/046256.html
[11] http://dpdk.org/ml/archives/dev/2016-October/048915.html
Changes since v5:
- fix devinit/devuninit name change; it was in wrong patch
- rebased over HEAD (ca41215)
- Update to pending section of coverletter
Changes since v4:
- change name of rte_eal_soc_scan function name to
rte_eal_soc_scan_platform_bus. This still remains a helper function.
- Fix comments over scan and match functions
Changes since v3:
- rebasing over HEAD (fed622df tag: v16.11-rc1)
- Add support for default scan function; PMD can use this for
scanning on platform bus.
- Support for kernel driver bind/unbind, numa and DMA from
Jan's original patches.
- SoC is disabled by default. '--enable-soc' command line parameter
enables it. doc updated.
- Updated testcase function names and comments
- Map file addition alphabetically ordered
- Patch author corrected
Changes since v2:
- Rebasing over rte_driver/device patchset v9 [10]
- Added cryptodev support for SoC
- Default match function for SoC device<=>Driver
- Some variables renamed to reflect 'drv' rather than 'dr'
Change since v1 [2]:
- Removed patch 1-5 which were for generalizing some PCI specific routines
into EAL. These patches are good-to-have but not directly linked to SoC
and hence would be proposed separately.
- Removed support for sysfs parsing (patches 6~9)
- Rebasing over the recent (v8) version of rte_driver/device patchset
- Rebasing over master (16.07)
- Changes to various map file to change API intro to 16.11 from 16.07
Jan Viktorin (19):
eal: generalize PCI kernel driver enum to EAL
eal: generalize PCI map/unmap resource to EAL
eal/linux: generalize PCI kernel unbinding driver to EAL
eal/linux: generalize PCI kernel driver extraction to EAL
eal: define container macro
eal/soc: introduce very essential SoC infra definitions
eal/soc: add SoC PMD register/unregister logic
eal/soc: implement SoC device list and dump
eal: introduce command line enable SoC option
eal/soc: init SoC infra from EAL
eal/soc: extend and utilize devargs
eal/soc: add drv_flags
eal/soc: add intr_handle
eal/soc: add default scan for Soc devices
eal/soc: additional features for SoC
ether: utilize container_of for pci_drv
ether: verify we copy info from a PCI device
ether: extract function eth_dev_get_intr_handle
ether: introduce ethernet dev probe remove
Shreyansh Jain (2):
eal/soc: implement probing of drivers
eal/crypto: Support rte_soc_driver/device for cryptodev
app/test/Makefile | 1 +
app/test/test_soc.c | 404 +++++++++++++++++++
doc/guides/testpmd_app_ug/run_app.rst | 4 +
lib/librte_cryptodev/rte_cryptodev.c | 122 +++++-
lib/librte_cryptodev/rte_cryptodev.h | 3 +
lib/librte_cryptodev/rte_cryptodev_pmd.h | 18 +-
lib/librte_cryptodev/rte_cryptodev_version.map | 2 +
lib/librte_eal/bsdapp/eal/Makefile | 1 +
lib/librte_eal/bsdapp/eal/eal.c | 18 +
lib/librte_eal/bsdapp/eal/eal_pci.c | 6 +-
lib/librte_eal/bsdapp/eal/eal_soc.c | 46 +++
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 11 +
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_common_dev.c | 66 ++-
lib/librte_eal/common/eal_common_devargs.c | 17 +
lib/librte_eal/common/eal_common_options.c | 5 +
lib/librte_eal/common/eal_common_pci.c | 39 --
lib/librte_eal/common/eal_common_pci_uio.c | 16 +-
lib/librte_eal/common/eal_common_soc.c | 368 +++++++++++++++++
lib/librte_eal/common/eal_internal_cfg.h | 1 +
lib/librte_eal/common/eal_options.h | 2 +
lib/librte_eal/common/eal_private.h | 64 +++
lib/librte_eal/common/include/rte_common.h | 18 +
lib/librte_eal/common/include/rte_dev.h | 44 ++
lib/librte_eal/common/include/rte_devargs.h | 8 +
lib/librte_eal/common/include/rte_pci.h | 41 --
lib/librte_eal/common/include/rte_soc.h | 322 +++++++++++++++
lib/librte_eal/linuxapp/eal/Makefile | 2 +
lib/librte_eal/linuxapp/eal/eal.c | 63 +++
lib/librte_eal/linuxapp/eal/eal_pci.c | 62 +--
lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 5 +-
lib/librte_eal/linuxapp/eal/eal_soc.c | 515 ++++++++++++++++++++++++
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 11 +
lib/librte_ether/rte_ethdev.c | 166 +++++++-
lib/librte_ether/rte_ethdev.h | 33 +-
36 files changed, 2343 insertions(+), 165 deletions(-)
create mode 100644 app/test/test_soc.c
create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
create mode 100644 lib/librte_eal/common/eal_common_soc.c
create mode 100644 lib/librte_eal/common/include/rte_soc.h
create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c
--
2.7.4
^ permalink raw reply
* [PATCH] doc: fix mlx5 features overview
From: Nelio Laranjeiro @ 2016-10-27 15:04 UTC (permalink / raw)
To: dev
Fixes: 75ef62a94301 ("net/mlx5: fix link speed capability information")
Fixes: 188408719888 ("net/mlx5: fix support for newer link speeds")
Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---
doc/guides/nics/features/mlx5.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/guides/nics/features/mlx5.ini b/doc/guides/nics/features/mlx5.ini
index e84612f..f811e3f 100644
--- a/doc/guides/nics/features/mlx5.ini
+++ b/doc/guides/nics/features/mlx5.ini
@@ -4,6 +4,7 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Speed capabilities = Y
Link status = Y
Link status event = Y
Queue start/stop = Y
--
2.1.4
^ permalink raw reply related
* Re: [PATCH v11 1/6] ethdev: add Tx preparation
From: Thomas Monjalon @ 2016-10-27 15:01 UTC (permalink / raw)
To: Tomasz Kulasek; +Cc: dev
In-Reply-To: <1477486575-25148-2-git-send-email-tomaszx.kulasek@intel.com>
Hi Tomasz,
This is a major new function in the API and I still have some comments.
2016-10-26 14:56, Tomasz Kulasek:
> --- a/config/common_base
> +++ b/config/common_base
> +CONFIG_RTE_ETHDEV_TX_PREP=y
We cannot enable it until it is implemented in every drivers.
> struct rte_eth_dev {
> eth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */
> eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
> + eth_tx_prep_t tx_pkt_prep; /**< Pointer to PMD transmit prepare function. */
> struct rte_eth_dev_data *data; /**< Pointer to device data */
> const struct eth_driver *driver;/**< Driver for this device */
> const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
Could you confirm why tx_pkt_prep is not in dev_ops?
I guess we want to have several implementations?
Shouldn't we have a const struct control_dev_ops and a struct datapath_dev_ops?
> +rte_eth_tx_prep(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **tx_pkts,
> + uint16_t nb_pkts)
The word "prep" can be understood as "prepend".
Why not rte_eth_tx_prepare?
> +/**
> + * Fix pseudo header checksum
> + *
> + * This function fixes pseudo header checksum for TSO and non-TSO tcp/udp in
> + * provided mbufs packet data.
> + *
> + * - for non-TSO tcp/udp packets full pseudo-header checksum is counted and set
> + * in packet data,
> + * - for TSO the IP payload length is not included in pseudo header.
> + *
> + * This function expects that used headers are in the first data segment of
> + * mbuf, are not fragmented and can be safely modified.
What happens otherwise?
> + *
> + * @param m
> + * The packet mbuf to be fixed.
> + * @return
> + * 0 if checksum is initialized properly
> + */
> +static inline int
> +rte_phdr_cksum_fix(struct rte_mbuf *m)
Could we find a better name for this function?
- About the prefix, rte_ip_ ?
- About the scope, where this phdr_cksum is specified?
Isn't it an intel_phdr_cksum to match what hardware expects?
- About the verb, is it really fixing something broken?
Or just writing into a mbuf?
I would suggest rte_ip_intel_cksum_prepare.
^ permalink raw reply
* Re: Unable to change source MAC address of packet
From: Padam Jeet Singh @ 2016-10-27 14:45 UTC (permalink / raw)
To: Wiles, Keith; +Cc: dev@dpdk.org
In-Reply-To: <DCD7B69C-9945-4C4B-AAA3-119F4F88D2CE@intel.com>
> On 27-Oct-2016, at 7:37 pm, Wiles, Keith <keith.wiles@intel.com> wrote:
>
>
>> On Oct 27, 2016, at 6:33 AM, Padam Jeet Singh <padam.singh@inventum.net> wrote:
>>
>> Hi,
>>
>> I am crafting a packet in which the source MAC address as set in the Ethernet header is different than the transmit port’s default MAC address. A packet capture of the packets coming out of this port however comes with source MAC address of the port’s default MAC address.
>>
>> Altering the destination MAC address works fine and shows up correctly in packet capture.
>>
>> The underlying network interface is an i210 and some logs added to the eth_igb_xmit_pkts function show that the packets I have crafted indeed are reaching the driver with the source MAC address set in the packet code of the application.
>>
>> How can I disable this automatic source MAC address setting?
>
> The packets sent with rte_eth_tx_burst() are not forced to a give MAC address. If you are using something on top of DPDK like Pktgen or OVS or something, then it may try to force a source MAC address.
No… not using pktgen or OVS. Plain simple code to take a packets from a KNI, change source mac address on all received packets, and then tx_burst them to a port.
> Maybe the hardware does it, but we need to know the NIC being used and then someone maybe able to answer. I do not know of any Intel NICs do that.
Intel i210 NIC (gigabit Ethernet) is being used. I have gone through the i210 documentation and can’t see anything specific to setting of MAC address in hardware for TX side. For RX side there are validations like MAC filtering, but nothing over TX.
>
> Is this what you are doing.
I agree that rte_eth_tx_burst does not overwrite the source MAC as I was able to trace all the way to the IGB driver that source mac makes it intact. There is no offload flags enabled in the mbuf. Yet the packets to the other side comes out as with source mac address of the port.
Is there any standard DPDK app which crafts packets with different source MAC than the port’s physical mac? (I checked the l2fwd example loads the port mac before transmitting and then uses the same in TX function).
>
>>
>> Thanks,
>> Padam
>
> Regards,
> Keith
>
^ permalink raw reply
* Re: Unable to change source MAC address of packet
From: Wiles, Keith @ 2016-10-27 14:07 UTC (permalink / raw)
To: Padam Jeet Singh; +Cc: dev@dpdk.org
In-Reply-To: <73B7F896-A39A-4805-915B-6B7E80994681@inventum.net>
> On Oct 27, 2016, at 6:33 AM, Padam Jeet Singh <padam.singh@inventum.net> wrote:
>
> Hi,
>
> I am crafting a packet in which the source MAC address as set in the Ethernet header is different than the transmit port’s default MAC address. A packet capture of the packets coming out of this port however comes with source MAC address of the port’s default MAC address.
>
> Altering the destination MAC address works fine and shows up correctly in packet capture.
>
> The underlying network interface is an i210 and some logs added to the eth_igb_xmit_pkts function show that the packets I have crafted indeed are reaching the driver with the source MAC address set in the packet code of the application.
>
> How can I disable this automatic source MAC address setting?
The packets sent with rte_eth_tx_burst() are not forced to a give MAC address. If you are using something on top of DPDK like Pktgen or OVS or something, then it may try to force a source MAC address. Maybe the hardware does it, but we need to know the NIC being used and then someone maybe able to answer. I do not know of any Intel NICs do that.
Is this what you are doing.
>
> Thanks,
> Padam
Regards,
Keith
^ permalink raw reply
* Unable to change source MAC address of packet
From: Padam Jeet Singh @ 2016-10-27 13:33 UTC (permalink / raw)
To: dev
Hi,
I am crafting a packet in which the source MAC address as set in the Ethernet header is different than the transmit port’s default MAC address. A packet capture of the packets coming out of this port however comes with source MAC address of the port’s default MAC address.
Altering the destination MAC address works fine and shows up correctly in packet capture.
The underlying network interface is an i210 and some logs added to the eth_igb_xmit_pkts function show that the packets I have crafted indeed are reaching the driver with the source MAC address set in the packet code of the application.
How can I disable this automatic source MAC address setting?
Thanks,
Padam
^ permalink raw reply
* Re: [PATCH] pci: Don't call probe callback if driver already loaded.
From: David Marchand @ 2016-10-27 13:30 UTC (permalink / raw)
To: Ben Walker; +Cc: dev@dpdk.org
In-Reply-To: <CALwxeUtVUNuvKdyk9Y2EW5-MbrEi8W8e2YV3P39m_NGf8NbN0g@mail.gmail.com>
On Thu, Oct 27, 2016 at 3:28 PM, David Marchand
<david.marchand@6wind.com> wrote:
> On Tue, Oct 25, 2016 at 11:50 PM, Ben Walker <benjamin.walker@intel.com> wrote:
>> If the user asks to probe multiple times, the probe
>> callback should only be called on devices that don't have
>> a driver already loaded.
>>
>> This is useful if a driver is registered after the
>> execution of a program has started and the list of devices
>> needs to be re-scanned.
>
> Why not use the hotplug api, attaching explicitely one pci device ?
Ah, scratch that.
I've been too quick to reply.
Ok, you are loading a new driver.
--
David Marchand
^ permalink raw reply
* Re: [PATCH] pci: Don't call probe callback if driver already loaded.
From: David Marchand @ 2016-10-27 13:28 UTC (permalink / raw)
To: Ben Walker; +Cc: dev@dpdk.org
In-Reply-To: <1477432240-20406-1-git-send-email-benjamin.walker@intel.com>
Hello Benjamin,
On Tue, Oct 25, 2016 at 11:50 PM, Ben Walker <benjamin.walker@intel.com> wrote:
> If the user asks to probe multiple times, the probe
> callback should only be called on devices that don't have
> a driver already loaded.
>
> This is useful if a driver is registered after the
> execution of a program has started and the list of devices
> needs to be re-scanned.
Why not use the hotplug api, attaching explicitely one pci device ?
> Signed-off-by: Ben Walker <benjamin.walker@intel.com>
> ---
> lib/librte_eal/common/eal_common_pci.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
> index 638cd86..971ad20 100644
> --- a/lib/librte_eal/common/eal_common_pci.c
> +++ b/lib/librte_eal/common/eal_common_pci.c
> @@ -289,6 +289,10 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
> if (dev == NULL)
> return -1;
>
> + /* Check if a driver is already loaded */
> + if (dev->driver != NULL)
> + return 0;
> +
This can do the trick, yes.
To be safe, I think we are missing a check in
rte_eal_pci_probe_one_driver() so that dev->driver is only set when
the probe function from the driver did succeed.
--
David Marchand
^ permalink raw reply
* Re: [PATCH v11 1/6] ethdev: add Tx preparation
From: Olivier Matz @ 2016-10-27 12:38 UTC (permalink / raw)
To: Tomasz Kulasek, dev
In-Reply-To: <1477486575-25148-2-git-send-email-tomaszx.kulasek@intel.com>
On 10/26/2016 02:56 PM, Tomasz Kulasek wrote:
> Added API for `rte_eth_tx_prep`
>
> [...]
>
> Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
^ permalink raw reply
* Tcpdump
From: Dror Birkman @ 2016-10-27 12:25 UTC (permalink / raw)
To: dev
Hi,
I have a DPDK application that binds to an interface and processes packets.
For debugging purposes I want to run tcpdump on this interface.
IYO, what is my best option with hurting the performance of the application
too much?
TIA,
Dror
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox