return -1;
}
+void *
+pci_find_max_end_va(void)
+{
+ const struct rte_memseg *seg = rte_eal_get_physmem_layout();
+ const struct rte_memseg *last = seg;
+ unsigned i = 0;
+
+ for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
+ if (seg->addr == NULL)
+ break;
+
+ if (seg->addr > last->addr)
+ last = seg;
+
+ }
+ return RTE_PTR_ADD(last->addr, last->len);
+}
+
+
/* map a particular resource from a file */
void *
pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size)
/* Map the PCI memory resource of device */
mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset);
- if (mapaddr == MAP_FAILED ||
- (requested_addr != NULL && mapaddr != requested_addr)) {
+ 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);
- goto fail;
+ } else {
+ RTE_LOG(DEBUG, EAL, " PCI memory mapped at %p\n", mapaddr);
}
- RTE_LOG(DEBUG, EAL, " PCI memory mapped at %p\n", mapaddr);
-
return mapaddr;
-
-fail:
- return NULL;
}
/* parse the "resource" sysfs file */
TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
extern struct mapped_pci_res_list *pci_res_list;
+/*
+ * Helper function to map PCI resources right after hugepages in virtual memory
+ */
+extern void *pci_map_addr;
+void *pci_find_max_end_va(void);
+
void *pci_map_resource(void *requested_addr, int fd, off_t offset,
size_t size);
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
+#include <sys/mman.h>
#include <rte_log.h>
#include <rte_pci.h>
static int pci_parse_sysfs_value(const char *filename, uint64_t *val);
+void *pci_map_addr = NULL;
+
#define OFF_MAX ((uint64_t)(off_t)-1)
static int
if (maps[j].addr != NULL)
fail = 1;
else {
- mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+ /* try mapping somewhere close to the end of hugepages */
+ if (pci_map_addr == NULL)
+ pci_map_addr = pci_find_max_end_va();
+
+ mapaddr = pci_map_resource(pci_map_addr, fd, (off_t)offset,
(size_t)maps[j].size);
- if (mapaddr == NULL)
+ if (mapaddr == MAP_FAILED)
fail = 1;
+
+ pci_map_addr = RTE_PTR_ADD(mapaddr, (size_t) maps[j].size);
}
if (fail) {
#include <sys/eventfd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <rte_log.h>
#include <rte_pci.h>
if (i == msix_bar)
continue;
- bar_addr = pci_map_resource(maps[i].addr, vfio_dev_fd, reg.offset,
- reg.size);
+ if (internal_config.process_type == RTE_PROC_PRIMARY) {
+ /* try mapping somewhere close to the end of hugepages */
+ if (pci_map_addr == NULL)
+ pci_map_addr = pci_find_max_end_va();
+
+ bar_addr = pci_map_resource(pci_map_addr, vfio_dev_fd, reg.offset,
+ reg.size);
+ pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+ } else {
+ bar_addr = pci_map_resource(maps[i].addr, vfio_dev_fd, reg.offset,
+ reg.size);
+ }
- if (bar_addr == NULL) {
+ if (bar_addr == MAP_FAILED ||
+ (internal_config.process_type == RTE_PROC_SECONDARY &&
+ bar_addr != maps[i].addr)) {
RTE_LOG(ERR, EAL, " %s mapping BAR%i failed: %s\n", pci_addr, i,
strerror(errno));
close(vfio_dev_fd);