pci: unmap igb_uio resources
authorTetsuya Mukawa <mukawa@igel.co.jp>
Wed, 25 Feb 2015 19:32:22 +0000 (04:32 +0900)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 25 Feb 2015 23:03:07 +0000 (00:03 +0100)
The patch adds functions for unmapping igb_uio resources. The patch is only
for Linux and igb_uio environment. VFIO and BSD are not supported.

Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>
config/common_bsdapp
config/common_linuxapp
lib/librte_eal/linuxapp/eal/eal_pci.c
lib/librte_eal/linuxapp/eal/eal_pci_init.h
lib/librte_eal/linuxapp/eal/eal_pci_uio.c

index 4bbacaf..1672998 100644 (file)
@@ -115,6 +115,12 @@ CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
 #
 CONFIG_RTE_LIBRTE_EAL_LINUXAPP=n
 
+#
+# Compile Environment Abstraction Layer to support hotplug
+# So far, Hotplug functions only support linux
+#
+CONFIG_RTE_LIBRTE_EAL_HOTPLUG=n
+
 #
 # Compile Environment Abstraction Layer to support Vmware TSC map
 #
index 2ea6711..e741aa4 100644 (file)
@@ -113,6 +113,11 @@ CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0
 #
 CONFIG_RTE_LIBRTE_EAL_LINUXAPP=y
 
+#
+# Compile Environment Abstraction Layer to support hotplug
+#
+CONFIG_RTE_LIBRTE_EAL_HOTPLUG=y
+
 #
 # Compile Environment Abstraction Layer to support Vmware TSC map
 #
index 06bfc1a..d03429c 100644 (file)
@@ -168,6 +168,23 @@ pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
        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);
+}
+
 /* parse the "resource" sysfs file */
 static int
 pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
index 03d2b52..6af84d1 100644 (file)
@@ -72,6 +72,13 @@ void *pci_map_resource(void *requested_addr, int fd, off_t offset,
 /* map IGB_UIO resource prototype */
 int pci_uio_map_resource(struct rte_pci_device *dev);
 
+void pci_unmap_resource(void *requested_addr, size_t size);
+
+#ifdef RTE_LIBRTE_EAL_HOTPLUG
+/* unmap IGB_UIO resource prototype */
+void pci_uio_unmap_resource(struct rte_pci_device *dev);
+#endif /* RTE_LIBRTE_EAL_HOTPLUG */
+
 #ifdef VFIO_PRESENT
 
 #define VFIO_MAX_GROUPS 64
index c5e0cf3..35d31c5 100644 (file)
@@ -386,3 +386,68 @@ pci_uio_map_resource(struct rte_pci_device *dev)
 
        return 0;
 }
+
+#ifdef RTE_LIBRTE_EAL_HOTPLUG
+static void
+pci_uio_unmap(struct mapped_pci_resource *uio_res)
+{
+       int i;
+
+       if (uio_res == NULL)
+               return;
+
+       for (i = 0; i != uio_res->nb_maps; i++)
+               pci_unmap_resource(uio_res->maps[i].addr,
+                               (size_t)uio_res->maps[i].size);
+}
+
+static struct mapped_pci_resource *
+pci_uio_find_resource(struct rte_pci_device *dev)
+{
+       struct mapped_pci_resource *uio_res;
+
+       if (dev == NULL)
+               return NULL;
+
+       TAILQ_FOREACH(uio_res, pci_res_list, next) {
+
+               /* skip this element if it doesn't match our PCI address */
+               if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+                       return uio_res;
+       }
+       return NULL;
+}
+
+/* unmap the PCI resource of a PCI device in virtual memory */
+void
+pci_uio_unmap_resource(struct rte_pci_device *dev)
+{
+       struct mapped_pci_resource *uio_res;
+
+       if (dev == NULL)
+               return;
+
+       /* find an entry for the device */
+       uio_res = pci_uio_find_resource(dev);
+       if (uio_res == NULL)
+               return;
+
+       /* secondary processes - just free maps */
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return pci_uio_unmap(uio_res);
+
+       TAILQ_REMOVE(pci_res_list, uio_res, next);
+
+       /* unmap all resources */
+       pci_uio_unmap(uio_res);
+
+       /* free uio resource */
+       rte_free(uio_res);
+
+       /* close fd if in primary process */
+       close(dev->intr_handle.fd);
+
+       dev->intr_handle.fd = -1;
+       dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
+#endif /* RTE_LIBRTE_EAL_HOTPLUG */