From patchwork Mon Nov 10 11:34:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anatoly Burakov X-Patchwork-Id: 1235 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 352897E1C; Mon, 10 Nov 2014 12:24:57 +0100 (CET) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 7D31D6828 for ; Mon, 10 Nov 2014 12:24:55 +0100 (CET) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 10 Nov 2014 03:32:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,352,1413270000"; d="scan'208";a="605244009" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga001.jf.intel.com with ESMTP; 10 Nov 2014 03:34:38 -0800 Received: from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com [10.237.217.46]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id sAABYb2e001448; Mon, 10 Nov 2014 11:34:37 GMT Received: from sivswdev02.ir.intel.com (localhost [127.0.0.1]) by sivswdev02.ir.intel.com with ESMTP id sAABYa6g008322; Mon, 10 Nov 2014 11:34:37 GMT Received: (from aburakov@localhost) by sivswdev02.ir.intel.com with id sAABYWQ0008317; Mon, 10 Nov 2014 11:34:32 GMT From: Anatoly Burakov To: dev@dpdk.org Date: Mon, 10 Nov 2014 11:34:32 +0000 Message-Id: <1415619272-8281-1-git-send-email-anatoly.burakov@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1415347284-15468-1-git-send-email-liang.xu@cinfotech.cn> References: <1415347284-15468-1-git-send-email-liang.xu@cinfotech.cn> Subject: [dpdk-dev] [PATCH v7] eal: map PCI memory resources after hugepages X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Multi-process DPDK application must mmap hugepages and pci resources into the same virtual address space. By default the virtual addresses are chosen by the primary process automatically when calling the mmap. But sometimes the chosen virtual addresses aren't usable in secondary process - for example, secondary process is linked with more libraries than primary process, and the library occupies the same address space that the primary process has requested for PCI mappings. This patch makes EAL map PCI BARs right after the hugepages (instead of location chosen by mmap) in virtual memory. Signed-off-by: Anatoly Burakov Signed-off-by: Liang Xu --- lib/librte_eal/linuxapp/eal/eal_pci.c | 19 +++++++++++++++++++ lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 9 ++++++++- lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 13 +++++++++++-- lib/librte_eal/linuxapp/eal/include/eal_pci_init.h | 6 ++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index 5fe3961..dae8739 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -97,6 +97,25 @@ error: 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) diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c index 7e62266..5090bf1 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c @@ -48,6 +48,8 @@ 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 @@ -371,10 +373,15 @@ pci_uio_map_resource(struct rte_pci_device *dev) if (maps[j].addr != NULL) fail = 1; else { - mapaddr = pci_map_resource(NULL, fd, (off_t)offset, + 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) fail = 1; + + pci_map_addr = RTE_PTR_ADD(pci_map_addr, maps[j].size); } if (fail) { diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c index c776ddc..fb6ee7a 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c @@ -720,8 +720,17 @@ pci_vfio_map_resource(struct rte_pci_device *dev) 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) { + 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(pci_map_addr, reg.size); + } else { + bar_addr = pci_map_resource(maps[i].addr, vfio_dev_fd, reg.offset, + reg.size); + } if (bar_addr == NULL) { RTE_LOG(ERR, EAL, " %s mapping BAR%i failed: %s\n", pci_addr, i, diff --git a/lib/librte_eal/linuxapp/eal/include/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/include/eal_pci_init.h index d758bee..1070eb8 100644 --- a/lib/librte_eal/linuxapp/eal/include/eal_pci_init.h +++ b/lib/librte_eal/linuxapp/eal/include/eal_pci_init.h @@ -59,6 +59,12 @@ struct mapped_pci_resource { 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);