From 5a60a7ffc8016cd3889405c2b615277505d0e28f Mon Sep 17 00:00:00 2001 From: Tetsuya Mukawa Date: Wed, 8 Jul 2015 19:34:47 +0900 Subject: [PATCH] pci: introduce functions to alloc and free uio resource This patch adds new functions called pci_uio_alloc_resource() and pci_uio_free_resource(). The functions hides how to prepare or free uio resource in linuxapp and bsdapp. With the function, pci_uio_map_resource() will be more abstracted. Signed-off-by: Tetsuya Mukawa Acked-by: David Marchand --- lib/librte_eal/bsdapp/eal/eal_pci.c | 85 ++++++++++++++------- lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 93 +++++++++++++++-------- 2 files changed, 118 insertions(+), 60 deletions(-) diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c index 64fd539dbf..52efa9e01b 100644 --- a/lib/librte_eal/bsdapp/eal/eal_pci.c +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c @@ -187,28 +187,27 @@ pci_uio_map_secondary(struct rte_pci_device *dev) return 1; } -/* map the PCI resource of a PCI device in virtual memory */ -static int -pci_uio_map_resource(struct rte_pci_device *dev) +static void +pci_uio_free_resource(struct rte_pci_device *dev, + struct mapped_pci_resource *uio_res) +{ + rte_free(uio_res); + + if (dev->intr_handle.fd) { + close(dev->intr_handle.fd); + dev->intr_handle.fd = -1; + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + } +} + +static int +pci_uio_alloc_resource(struct rte_pci_device *dev, + struct mapped_pci_resource **uio_res) { - int i, map_idx = 0; char devname[PATH_MAX]; /* contains the /dev/uioX */ - void *mapaddr; - uint64_t phaddr; - uint64_t offset; - uint64_t pagesz; - struct rte_pci_addr *loc = &dev->addr; - struct mapped_pci_resource *uio_res = NULL; - struct mapped_pci_res_list *uio_res_list = - RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list); - struct pci_map *maps; + struct rte_pci_addr *loc; - dev->intr_handle.fd = -1; - dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; - - /* secondary processes - use already recorded details */ - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return pci_uio_map_secondary(dev); + loc = &dev->addr; snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u", dev->addr.bus, dev->addr.devid, dev->addr.function); @@ -229,18 +228,53 @@ pci_uio_map_resource(struct rte_pci_device *dev) dev->intr_handle.type = RTE_INTR_HANDLE_UIO; /* allocate the mapping details for secondary processes*/ - if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) { + *uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0); + if (*uio_res == NULL) { RTE_LOG(ERR, EAL, "%s(): cannot store uio mmap details\n", __func__); goto error; } - snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname); - memcpy(&uio_res->pci_addr, &dev->addr, sizeof(uio_res->pci_addr)); + snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname); + memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr)); + return 0; + +error: + pci_uio_free_resource(dev, *uio_res); + return -1; +} + +/* map the PCI resource of a PCI device in virtual memory */ +static int +pci_uio_map_resource(struct rte_pci_device *dev) +{ + int i, map_idx = 0, ret; + char *devname; + void *mapaddr; + uint64_t phaddr; + uint64_t offset; + uint64_t pagesz; + struct mapped_pci_resource *uio_res = NULL; + struct mapped_pci_res_list *uio_res_list = + RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list); + struct pci_map *maps; + + dev->intr_handle.fd = -1; + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + + /* secondary processes - use already recorded details */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return pci_uio_map_secondary(dev); + + /* allocate uio resource */ + ret = pci_uio_alloc_resource(dev, &uio_res); + if (ret) + return ret; /* Map all BARs */ pagesz = sysconf(_SC_PAGESIZE); + devname = uio_res->path; maps = uio_res->maps; for (i = 0; i != PCI_MAX_RESOURCE; i++) { @@ -296,12 +330,7 @@ pci_uio_map_resource(struct rte_pci_device *dev) error: for (i = 0; i < map_idx; i++) rte_free(maps[i].path); - rte_free(uio_res); - if (dev->intr_handle.fd >= 0) { - close(dev->intr_handle.fd); - dev->intr_handle.fd = -1; - dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; - } + pci_uio_free_resource(dev, uio_res); return -1; } diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c index d8f61b5328..de92ce53fd 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c @@ -252,30 +252,34 @@ pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf, return uio_num; } -/* map the PCI resource of a PCI device in virtual memory */ -int -pci_uio_map_resource(struct rte_pci_device *dev) +static void +pci_uio_free_resource(struct rte_pci_device *dev, + struct mapped_pci_resource *uio_res) +{ + rte_free(uio_res); + + if (dev->intr_handle.uio_cfg_fd >= 0) { + close(dev->intr_handle.uio_cfg_fd); + dev->intr_handle.uio_cfg_fd = -1; + } + if (dev->intr_handle.fd) { + close(dev->intr_handle.fd); + dev->intr_handle.fd = -1; + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + } +} + +static int +pci_uio_alloc_resource(struct rte_pci_device *dev, + struct mapped_pci_resource **uio_res) { - int i, map_idx = 0; char dirname[PATH_MAX]; char cfgname[PATH_MAX]; char devname[PATH_MAX]; /* contains the /dev/uioX */ - void *mapaddr; int uio_num; - uint64_t phaddr; - struct rte_pci_addr *loc = &dev->addr; - struct mapped_pci_resource *uio_res = NULL; - struct mapped_pci_res_list *uio_res_list = - RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list); - struct pci_map *maps; + struct rte_pci_addr *loc; - dev->intr_handle.fd = -1; - dev->intr_handle.uio_cfg_fd = -1; - dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; - - /* secondary processes - use already recorded details */ - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return pci_uio_map_secondary(dev); + loc = &dev->addr; /* find uio resource */ uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname)); @@ -316,15 +320,49 @@ pci_uio_map_resource(struct rte_pci_device *dev) } /* allocate the mapping details for secondary processes*/ - uio_res = rte_zmalloc("UIO_RES", sizeof(*uio_res), 0); - if (uio_res == NULL) { + *uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0); + if (*uio_res == NULL) { RTE_LOG(ERR, EAL, "%s(): cannot store uio mmap details\n", __func__); goto error; } - snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname); - memcpy(&uio_res->pci_addr, &dev->addr, sizeof(uio_res->pci_addr)); + snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname); + memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr)); + + return 0; + +error: + pci_uio_free_resource(dev, *uio_res); + return -1; +} + +/* map the PCI resource of a PCI device in virtual memory */ +int +pci_uio_map_resource(struct rte_pci_device *dev) +{ + int i, map_idx = 0, ret; + char devname[PATH_MAX]; /* contains the /dev/uioX */ + void *mapaddr; + uint64_t phaddr; + struct rte_pci_addr *loc = &dev->addr; + struct mapped_pci_resource *uio_res = NULL; + struct mapped_pci_res_list *uio_res_list = + RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list); + struct pci_map *maps; + + dev->intr_handle.fd = -1; + dev->intr_handle.uio_cfg_fd = -1; + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + + /* secondary processes - use already recorded details */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return pci_uio_map_secondary(dev); + + /* allocate uio resource */ + ret = pci_uio_alloc_resource(dev, &uio_res); + if (ret) + return ret; /* Map all BARs */ maps = uio_res->maps; @@ -398,16 +436,7 @@ pci_uio_map_resource(struct rte_pci_device *dev) (size_t)uio_res->maps[i].size); rte_free(maps[i].path); } - rte_free(uio_res); - if (dev->intr_handle.uio_cfg_fd >= 0) { - close(dev->intr_handle.uio_cfg_fd); - dev->intr_handle.uio_cfg_fd = -1; - } - if (dev->intr_handle.fd >= 0) { - close(dev->intr_handle.fd); - dev->intr_handle.fd = -1; - dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; - } + pci_uio_free_resource(dev, uio_res); return -1; }