net/bonding: use local prefix namespace
[dpdk.git] / lib / librte_eal / linuxapp / eal / eal_pci.c
index 595622b..cee4b94 100644 (file)
@@ -41,6 +41,7 @@
 #include <rte_malloc.h>
 #include <rte_devargs.h>
 #include <rte_memcpy.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_private.h"
@@ -310,22 +311,20 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
                        dev->max_vfs = (uint16_t)tmp;
        }
 
-       /* get numa node */
+       /* get numa node, default to 0 if not present */
        snprintf(filename, sizeof(filename), "%s/numa_node",
                 dirname);
-       if (access(filename, R_OK) != 0) {
-               /* if no NUMA support, set default to 0 */
-               dev->device.numa_node = 0;
+
+       if (access(filename, F_OK) != -1) {
+               if (eal_parse_sysfs_value(filename, &tmp) == 0)
+                       dev->device.numa_node = tmp;
+               else
+                       dev->device.numa_node = -1;
        } else {
-               if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-                       free(dev);
-                       return -1;
-               }
-               dev->device.numa_node = tmp;
+               dev->device.numa_node = 0;
        }
 
-       rte_pci_device_name(addr, dev->name, sizeof(dev->name));
-       dev->device.name = dev->name;
+       pci_name_set(dev);
 
        /* parse resources */
        snprintf(filename, sizeof(filename), "%s/resource", dirname);
@@ -364,7 +363,7 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
                int ret;
 
                TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-                       ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+                       ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
                        if (ret > 0)
                                continue;
 
@@ -373,6 +372,7 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
                        } else { /* already registered */
                                dev2->kdrv = dev->kdrv;
                                dev2->max_vfs = dev->max_vfs;
+                               pci_name_set(dev2);
                                memmove(dev2->mem_resource, dev->mem_resource,
                                        sizeof(dev->mem_resource));
                                free(dev);
@@ -430,10 +430,10 @@ parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
 
        /* now convert to int values */
        errno = 0;
-       addr->domain = (uint16_t)strtoul(splitaddr.domain, NULL, 16);
-       addr->bus = (uint8_t)strtoul(splitaddr.bus, NULL, 16);
-       addr->devid = (uint8_t)strtoul(splitaddr.devid, NULL, 16);
-       addr->function = (uint8_t)strtoul(splitaddr.function, NULL, 10);
+       addr->domain = strtoul(splitaddr.domain, NULL, 16);
+       addr->bus = strtoul(splitaddr.bus, NULL, 16);
+       addr->devid = strtoul(splitaddr.devid, NULL, 16);
+       addr->function = strtoul(splitaddr.function, NULL, 10);
        if (errno != 0)
                goto error;
 
@@ -457,9 +457,14 @@ rte_pci_scan(void)
        struct rte_pci_addr addr;
 
        /* for debug purposes, PCI can be disabled */
-       if (internal_config.no_pci)
+       if (!rte_eal_has_pci())
                return 0;
 
+#ifdef VFIO_PRESENT
+       if (!pci_vfio_is_enabled())
+               RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
+#endif
+
        dir = opendir(pci_get_sysfs_path());
        if (dir == NULL) {
                RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
@@ -488,6 +493,101 @@ error:
        return -1;
 }
 
+/*
+ * Is pci device bound to any kdrv
+ */
+static inline int
+pci_one_device_is_bound(void)
+{
+       struct rte_pci_device *dev = NULL;
+       int ret = 0;
+
+       FOREACH_DEVICE_ON_PCIBUS(dev) {
+               if (dev->kdrv == RTE_KDRV_UNKNOWN ||
+                   dev->kdrv == RTE_KDRV_NONE) {
+                       continue;
+               } else {
+                       ret = 1;
+                       break;
+               }
+       }
+       return ret;
+}
+
+/*
+ * Any one of the device bound to uio
+ */
+static inline int
+pci_one_device_bound_uio(void)
+{
+       struct rte_pci_device *dev = NULL;
+
+       FOREACH_DEVICE_ON_PCIBUS(dev) {
+               if (dev->kdrv == RTE_KDRV_IGB_UIO ||
+                  dev->kdrv == RTE_KDRV_UIO_GENERIC) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Any one of the device has iova as va
+ */
+static inline int
+pci_one_device_has_iova_va(void)
+{
+       struct rte_pci_device *dev = NULL;
+       struct rte_pci_driver *drv = NULL;
+
+       FOREACH_DRIVER_ON_PCIBUS(drv) {
+               if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
+                       FOREACH_DEVICE_ON_PCIBUS(dev) {
+                               if (dev->kdrv == RTE_KDRV_VFIO &&
+                                   rte_pci_match(drv, dev))
+                                       return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+       bool is_bound;
+       bool is_vfio_noiommu_enabled = true;
+       bool has_iova_va;
+       bool is_bound_uio;
+
+       is_bound = pci_one_device_is_bound();
+       if (!is_bound)
+               return RTE_IOVA_DC;
+
+       has_iova_va = pci_one_device_has_iova_va();
+       is_bound_uio = pci_one_device_bound_uio();
+#ifdef VFIO_PRESENT
+       is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
+                                       true : false;
+#endif
+
+       if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
+               return RTE_IOVA_VA;
+
+       if (has_iova_va) {
+               RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
+               if (is_vfio_noiommu_enabled)
+                       RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
+               if (is_bound_uio)
+                       RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
+       }
+
+       return RTE_IOVA_PA;
+}
+
 /* Read PCI config space. */
 int rte_pci_read_config(const struct rte_pci_device *device,
                void *buf, size_t len, off_t offset)