From patchwork Thu Nov 1 19:53:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Lucero X-Patchwork-Id: 47689 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8AB931B101; Thu, 1 Nov 2018 20:53:32 +0100 (CET) Received: from netronome.com (host-79-78-33-110.static.as9105.net [79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 2B33D1B101 for ; Thu, 1 Nov 2018 20:53:31 +0100 (CET) Received: from netronome.com (localhost [127.0.0.1]) by netronome.com (8.15.2/8.15.2/Debian-10) with ESMTP id wA1JrUwR019519 for ; Thu, 1 Nov 2018 19:53:30 GMT Received: (from root@localhost) by netronome.com (8.15.2/8.15.2/Submit) id wA1JrU0E019518 for dev@dpdk.org; Thu, 1 Nov 2018 19:53:30 GMT From: Alejandro Lucero To: dev@dpdk.org Date: Thu, 1 Nov 2018 19:53:24 +0000 Message-Id: <20181101195330.19464-2-alejandro.lucero@netronome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181101195330.19464-1-alejandro.lucero@netronome.com> References: <20181101195330.19464-1-alejandro.lucero@netronome.com> Subject: [dpdk-dev] [PATCH v2 1/7] mem: fix call to DMA mask check X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The param needs to be the maskbits and not the mask. Fixes: 223b7f1d5ef6 ("mem: add function for checking memseg IOVA") Signed-off-by: Alejandro Lucero --- lib/librte_eal/common/malloc_heap.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c index 1973b6e6e..d1019e3cd 100644 --- a/lib/librte_eal/common/malloc_heap.c +++ b/lib/librte_eal/common/malloc_heap.c @@ -294,7 +294,6 @@ alloc_pages_on_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size, size_t alloc_sz; int allocd_pages; void *ret, *map_addr; - uint64_t mask; alloc_sz = (size_t)pg_sz * n_segs; @@ -323,8 +322,7 @@ alloc_pages_on_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size, } if (mcfg->dma_maskbits) { - mask = ~((1ULL << mcfg->dma_maskbits) - 1); - if (rte_eal_check_dma_mask(mask)) { + if (rte_eal_check_dma_mask(mcfg->dma_maskbits)) { RTE_LOG(ERR, EAL, "%s(): couldn't allocate memory due to DMA mask\n", __func__); From patchwork Thu Nov 1 19:53:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Lucero X-Patchwork-Id: 47694 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C666F1B1FD; Thu, 1 Nov 2018 20:53:39 +0100 (CET) Received: from netronome.com (host-79-78-33-110.static.as9105.net [79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 3DC1F1B108 for ; Thu, 1 Nov 2018 20:53:31 +0100 (CET) Received: from netronome.com (localhost [127.0.0.1]) by netronome.com (8.15.2/8.15.2/Debian-10) with ESMTP id wA1JrUv6019523 for ; Thu, 1 Nov 2018 19:53:30 GMT Received: (from root@localhost) by netronome.com (8.15.2/8.15.2/Submit) id wA1JrUIW019522 for dev@dpdk.org; Thu, 1 Nov 2018 19:53:30 GMT From: Alejandro Lucero To: dev@dpdk.org Date: Thu, 1 Nov 2018 19:53:25 +0000 Message-Id: <20181101195330.19464-3-alejandro.lucero@netronome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181101195330.19464-1-alejandro.lucero@netronome.com> References: <20181101195330.19464-1-alejandro.lucero@netronome.com> Subject: [dpdk-dev] [PATCH v2 2/7] mem: use proper prefix X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Current name rte_eal_check_dma_mask does not follow the naming used in the rest of the file. Signed-off-by: Alejandro Lucero --- doc/guides/rel_notes/release_18_11.rst | 2 +- drivers/bus/pci/linux/pci.c | 2 +- drivers/net/nfp/nfp_net.c | 2 +- lib/librte_eal/common/eal_common_memory.c | 4 ++-- lib/librte_eal/common/include/rte_memory.h | 2 +- lib/librte_eal/common/malloc_heap.c | 2 +- lib/librte_eal/rte_eal_version.map | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst index 376128f68..11a27405c 100644 --- a/doc/guides/rel_notes/release_18_11.rst +++ b/doc/guides/rel_notes/release_18_11.rst @@ -63,7 +63,7 @@ New Features * **Added check for ensuring allocated memory addressable by devices.** Some devices can have addressing limitations so a new function, - ``rte_eal_check_dma_mask``, has been added for checking allocated memory is + ``rte_mem_check_dma_mask``, has been added for checking allocated memory is not out of the device range. Because now memory can be dynamically allocated after initialization, a dma mask is kept and any new allocated memory will be checked out against that dma mask and rejected if out of range. If more than diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c index 45c24ef7e..0a81e063b 100644 --- a/drivers/bus/pci/linux/pci.c +++ b/drivers/bus/pci/linux/pci.c @@ -590,7 +590,7 @@ pci_one_device_iommu_support_va(struct rte_pci_device *dev) mgaw = ((vtd_cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1; - return rte_eal_check_dma_mask(mgaw) == 0 ? true : false; + return rte_mem_check_dma_mask(mgaw) == 0 ? true : false; } #elif defined(RTE_ARCH_PPC_64) static bool diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c index bab1f68eb..54c6da924 100644 --- a/drivers/net/nfp/nfp_net.c +++ b/drivers/net/nfp/nfp_net.c @@ -2703,7 +2703,7 @@ nfp_net_init(struct rte_eth_dev *eth_dev) pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); /* NFP can not handle DMA addresses requiring more than 40 bits */ - if (rte_eal_check_dma_mask(40)) { + if (rte_mem_check_dma_mask(40)) { RTE_LOG(ERR, PMD, "device %s can not be used:", pci_dev->device.name); RTE_LOG(ERR, PMD, "\trestricted dma mask to 40 bits!\n"); diff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c index 12dcedf5c..e0f08f39a 100644 --- a/lib/librte_eal/common/eal_common_memory.c +++ b/lib/librte_eal/common/eal_common_memory.c @@ -49,7 +49,7 @@ static uint64_t system_page_sz; * Current known limitations are 39 or 40 bits. Setting the starting address * at 4GB implies there are 508GB or 1020GB for mapping the available * hugepages. This is likely enough for most systems, although a device with - * addressing limitations should call rte_eal_check_dma_mask for ensuring all + * addressing limitations should call rte_mem_check_dma_mask for ensuring all * memory is within supported range. */ static uint64_t baseaddr = 0x100000000; @@ -447,7 +447,7 @@ check_iova(const struct rte_memseg_list *msl __rte_unused, /* check memseg iovas are within the required range based on dma mask */ int __rte_experimental -rte_eal_check_dma_mask(uint8_t maskbits) +rte_mem_check_dma_mask(uint8_t maskbits) { struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; uint64_t mask; diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h index ce9370582..ad3f3cfb0 100644 --- a/lib/librte_eal/common/include/rte_memory.h +++ b/lib/librte_eal/common/include/rte_memory.h @@ -464,7 +464,7 @@ unsigned rte_memory_get_nchannel(void); unsigned rte_memory_get_nrank(void); /* check memsegs iovas are within a range based on dma mask */ -int __rte_experimental rte_eal_check_dma_mask(uint8_t maskbits); +int __rte_experimental rte_mem_check_dma_mask(uint8_t maskbits); /** * Drivers based on uio will not load unless physical diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c index d1019e3cd..4997c5ef5 100644 --- a/lib/librte_eal/common/malloc_heap.c +++ b/lib/librte_eal/common/malloc_heap.c @@ -322,7 +322,7 @@ alloc_pages_on_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size, } if (mcfg->dma_maskbits) { - if (rte_eal_check_dma_mask(mcfg->dma_maskbits)) { + if (rte_mem_check_dma_mask(mcfg->dma_maskbits)) { RTE_LOG(ERR, EAL, "%s(): couldn't allocate memory due to DMA mask\n", __func__); diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 04f624246..4eb16ee3b 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -295,7 +295,6 @@ EXPERIMENTAL { rte_devargs_parsef; rte_devargs_remove; rte_devargs_type_count; - rte_eal_check_dma_mask; rte_eal_cleanup; rte_fbarray_attach; rte_fbarray_destroy; @@ -331,6 +330,7 @@ EXPERIMENTAL { rte_malloc_heap_socket_is_external; rte_mem_alloc_validator_register; rte_mem_alloc_validator_unregister; + rte_mem_check_dma_mask; rte_mem_event_callback_register; rte_mem_event_callback_unregister; rte_mem_iova2virt; From patchwork Thu Nov 1 19:53:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Lucero X-Patchwork-Id: 47691 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EF8B91B185; Thu, 1 Nov 2018 20:53:35 +0100 (CET) Received: from netronome.com (host-79-78-33-110.static.as9105.net [79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 3FF101B128 for ; Thu, 1 Nov 2018 20:53:31 +0100 (CET) Received: from netronome.com (localhost [127.0.0.1]) by netronome.com (8.15.2/8.15.2/Debian-10) with ESMTP id wA1JrVwl019527 for ; Thu, 1 Nov 2018 19:53:31 GMT Received: (from root@localhost) by netronome.com (8.15.2/8.15.2/Submit) id wA1JrVka019526 for dev@dpdk.org; Thu, 1 Nov 2018 19:53:31 GMT From: Alejandro Lucero To: dev@dpdk.org Date: Thu, 1 Nov 2018 19:53:26 +0000 Message-Id: <20181101195330.19464-4-alejandro.lucero@netronome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181101195330.19464-1-alejandro.lucero@netronome.com> References: <20181101195330.19464-1-alejandro.lucero@netronome.com> Subject: [dpdk-dev] [PATCH v2 3/7] mem: add function for setting DMA mask X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch adds the possibility of setting a dma mask to be used once the memory initialization is done. This is currently needed when IOVA mode is set by PCI related code and an x86 IOMMU hardware unit is present. Current code calls rte_mem_check_dma_mask but it is wrong to do so at that point because the memory has not been initialized yet. Signed-off-by: Alejandro Lucero --- lib/librte_eal/common/eal_common_memory.c | 16 ++++++++++++++++ lib/librte_eal/common/include/rte_memory.h | 10 ++++++++++ lib/librte_eal/rte_eal_version.map | 1 + 3 files changed, 27 insertions(+) diff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c index e0f08f39a..cc4f1d80f 100644 --- a/lib/librte_eal/common/eal_common_memory.c +++ b/lib/librte_eal/common/eal_common_memory.c @@ -480,6 +480,22 @@ rte_mem_check_dma_mask(uint8_t maskbits) return 0; } +/* + * Set dma mask to use when memory initialization is done. + * + * This function should ONLY be used by code executed before the memory + * initialization. PMDs should use rte_mem_check_dma_mask if addressing + * limitations by the device. + */ +void __rte_experimental +rte_mem_set_dma_mask(uint8_t maskbits) +{ + struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; + + mcfg->dma_maskbits = mcfg->dma_maskbits == 0 ? maskbits : + RTE_MIN(mcfg->dma_maskbits, maskbits); +} + /* return the number of memory channels */ unsigned rte_memory_get_nchannel(void) { diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h index ad3f3cfb0..abbfe2364 100644 --- a/lib/librte_eal/common/include/rte_memory.h +++ b/lib/librte_eal/common/include/rte_memory.h @@ -466,6 +466,16 @@ unsigned rte_memory_get_nrank(void); /* check memsegs iovas are within a range based on dma mask */ int __rte_experimental rte_mem_check_dma_mask(uint8_t maskbits); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Set dma mask to use once memory initialization is done. + * Previous function rte_mem_check_dma_mask can not be used + * safely until memory has been initialized. + */ +void __rte_experimental rte_mem_set_dma_mask(uint8_t maskbits); + /** * Drivers based on uio will not load unless physical * addresses are obtainable. It is only possible to get diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 4eb16ee3b..51ee948ba 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -334,6 +334,7 @@ EXPERIMENTAL { rte_mem_event_callback_register; rte_mem_event_callback_unregister; rte_mem_iova2virt; + rte_mem_set_dma_mask; rte_mem_virt2memseg; rte_mem_virt2memseg_list; rte_memseg_contig_walk; From patchwork Thu Nov 1 19:53:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Lucero X-Patchwork-Id: 47692 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7A8661B1EA; Thu, 1 Nov 2018 20:53:37 +0100 (CET) Received: from netronome.com (host-79-78-33-110.static.as9105.net [79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 41D501B131 for ; Thu, 1 Nov 2018 20:53:31 +0100 (CET) Received: from netronome.com (localhost [127.0.0.1]) by netronome.com (8.15.2/8.15.2/Debian-10) with ESMTP id wA1JrVd2019531 for ; Thu, 1 Nov 2018 19:53:31 GMT Received: (from root@localhost) by netronome.com (8.15.2/8.15.2/Submit) id wA1JrVBm019530 for dev@dpdk.org; Thu, 1 Nov 2018 19:53:31 GMT From: Alejandro Lucero To: dev@dpdk.org Date: Thu, 1 Nov 2018 19:53:27 +0000 Message-Id: <20181101195330.19464-5-alejandro.lucero@netronome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181101195330.19464-1-alejandro.lucero@netronome.com> References: <20181101195330.19464-1-alejandro.lucero@netronome.com> Subject: [dpdk-dev] [PATCH v2 4/7] bus/pci: avoid call to DMA mask check X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Calling rte_mem_check_dma_mask when memory has not been initialized yet is wrong. This patch use rte_mem_set_dma_mask instead. Once memory initialization is done, the dma mask set will be used for checking memory mapped is within the specified mask. Fixes: fe822eb8c565 ("bus/pci: use IOVA DMA mask check when setting IOVA mode") Signed-off-by: Alejandro Lucero --- drivers/bus/pci/linux/pci.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c index 0a81e063b..d87384c72 100644 --- a/drivers/bus/pci/linux/pci.c +++ b/drivers/bus/pci/linux/pci.c @@ -590,7 +590,16 @@ pci_one_device_iommu_support_va(struct rte_pci_device *dev) mgaw = ((vtd_cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1; - return rte_mem_check_dma_mask(mgaw) == 0 ? true : false; + /* + * Assuming there is no limitation by now. We can not know at this point + * because the memory has not been initialized yet. Setting the dma mask + * will force a check once memory initialization is done. We can not do + * a fallback to IOVA PA now, but if the dma check fails, the error + * message should advice for using '--iova-mode pa' if IOVA VA is the + * current mode. + */ + rte_mem_set_dma_mask(mgaw); + return true; } #elif defined(RTE_ARCH_PPC_64) static bool From patchwork Thu Nov 1 19:53:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Lucero X-Patchwork-Id: 47693 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A61EE1B1F4; Thu, 1 Nov 2018 20:53:38 +0100 (CET) Received: from netronome.com (host-79-78-33-110.static.as9105.net [79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 45EFF1B13F for ; Thu, 1 Nov 2018 20:53:31 +0100 (CET) Received: from netronome.com (localhost [127.0.0.1]) by netronome.com (8.15.2/8.15.2/Debian-10) with ESMTP id wA1JrVNp019535 for ; Thu, 1 Nov 2018 19:53:31 GMT Received: (from root@localhost) by netronome.com (8.15.2/8.15.2/Submit) id wA1JrV3l019534 for dev@dpdk.org; Thu, 1 Nov 2018 19:53:31 GMT From: Alejandro Lucero To: dev@dpdk.org Date: Thu, 1 Nov 2018 19:53:28 +0000 Message-Id: <20181101195330.19464-6-alejandro.lucero@netronome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181101195330.19464-1-alejandro.lucero@netronome.com> References: <20181101195330.19464-1-alejandro.lucero@netronome.com> Subject: [dpdk-dev] [PATCH v2 5/7] mem: modify error message for DMA mask check X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" If DMA mask checks shows mapped memory out of the supported range specified by the DMA mask, nothing can be done but return an error an report the error. This can imply the app not being executed at all or precluding dynamic memory allocation once the app is running. In any case, we can advice the user to force IOVA as PA if currently IOVA being VA and user being root. Signed-off-by: Alejandro Lucero Signed-off-by: Alejandro Lucero Tested-by: Li, WenjieX A --- lib/librte_eal/common/malloc_heap.c | 41 +++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c index 4997c5ef5..c2c112aa6 100644 --- a/lib/librte_eal/common/malloc_heap.c +++ b/lib/librte_eal/common/malloc_heap.c @@ -321,13 +321,44 @@ alloc_pages_on_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size, goto fail; } - if (mcfg->dma_maskbits) { - if (rte_mem_check_dma_mask(mcfg->dma_maskbits)) { + /* + * Once we have all the memseg lists configured, if there is a dma mask + * set, check iova addresses are not out of range. Otherwise the device + * setting the dma mask could have problems with the mapped memory. + * + * There are two situations when this can happen: + * 1) memory initialization + * 2) dynamic memory allocation + * + * For 1), an error when checking dma mask implies app can not be + * executed. For 2) implies the new memory can not be added. + */ + if (mcfg->dma_maskbits && + rte_mem_check_dma_mask(mcfg->dma_maskbits)) { + /* + * Currently this can only happen if IOMMU is enabled + * and the address width supported by the IOMMU hw is + * not enough for using the memory mapped IOVAs. + * + * If IOVA is VA, advice to try with '--iova-mode pa' + * which could solve some situations when IOVA VA is not + * really needed. + */ + RTE_LOG(ERR, EAL, + "%s(): couldn't allocate memory due to IOVA exceeding limits of current DMA mask\n", + __func__); + + /* + * If IOVA is VA and it is possible to run with IOVA PA, + * because user is root, give and advice for solving the + * problem. + */ + if ((rte_eal_iova_mode() == RTE_IOVA_VA) && + rte_eal_using_phys_addrs()) RTE_LOG(ERR, EAL, - "%s(): couldn't allocate memory due to DMA mask\n", + "%s(): Please try initializing EAL with --iova-mode=pa parameter\n", __func__); - goto fail; - } + goto fail; } /* add newly minted memsegs to malloc heap */ From patchwork Thu Nov 1 19:53:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Lucero X-Patchwork-Id: 47695 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0DE131B206; Thu, 1 Nov 2018 20:53:41 +0100 (CET) Received: from netronome.com (host-79-78-33-110.static.as9105.net [79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 5CE541B142 for ; Thu, 1 Nov 2018 20:53:31 +0100 (CET) Received: from netronome.com (localhost [127.0.0.1]) by netronome.com (8.15.2/8.15.2/Debian-10) with ESMTP id wA1JrVot019539 for ; Thu, 1 Nov 2018 19:53:31 GMT Received: (from root@localhost) by netronome.com (8.15.2/8.15.2/Submit) id wA1JrV32019538 for dev@dpdk.org; Thu, 1 Nov 2018 19:53:31 GMT From: Alejandro Lucero To: dev@dpdk.org Date: Thu, 1 Nov 2018 19:53:29 +0000 Message-Id: <20181101195330.19464-7-alejandro.lucero@netronome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181101195330.19464-1-alejandro.lucero@netronome.com> References: <20181101195330.19464-1-alejandro.lucero@netronome.com> Subject: [dpdk-dev] [PATCH v2 6/7] eal/mem: use DMA mask check for legacy memory X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" If a device reports addressing limitations through a dma mask, the IOVAs for mapped memory needs to be checked out for ensuring correct functionality. Previous patches introduced this DMA check for main memory code currently being used but other options like legacy memory and the no hugepages option need to be also considered. This patch adds the DMA check for those cases. Signed-off-by: Alejandro Lucero --- lib/librte_eal/linuxapp/eal/eal_memory.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c index fce86fda6..c7935879a 100644 --- a/lib/librte_eal/linuxapp/eal/eal_memory.c +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c @@ -1393,6 +1393,18 @@ eal_legacy_hugepage_init(void) addr = RTE_PTR_ADD(addr, (size_t)page_sz); } + if (mcfg->dma_maskbits && + rte_mem_check_dma_mask(mcfg->dma_maskbits)) { + RTE_LOG(ERR, EAL, + "%s(): couldnt allocate memory due to IOVA exceeding limits of current DMA mask.\n", + __func__); + if (rte_eal_iova_mode() == RTE_IOVA_VA && + rte_eal_using_phys_addrs()) + RTE_LOG(ERR, EAL, + "%s(): Please try initializing EAL with --iova-mode=pa parameter.\n", + __func__); + goto fail; + } return 0; } @@ -1628,6 +1640,14 @@ eal_legacy_hugepage_init(void) rte_fbarray_destroy(&msl->memseg_arr); } + if (mcfg->dma_maskbits && + rte_mem_check_dma_mask(mcfg->dma_maskbits)) { + RTE_LOG(ERR, EAL, + "%s(): couldn't allocate memory due to IOVA exceeding limits of current DMA mask.\n", + __func__); + goto fail; + } + return 0; fail: From patchwork Thu Nov 1 19:53:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Lucero X-Patchwork-Id: 47696 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 6598F1B275; Thu, 1 Nov 2018 20:53:42 +0100 (CET) Received: from netronome.com (host-79-78-33-110.static.as9105.net [79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 75D921B101 for ; Thu, 1 Nov 2018 20:53:31 +0100 (CET) Received: from netronome.com (localhost [127.0.0.1]) by netronome.com (8.15.2/8.15.2/Debian-10) with ESMTP id wA1JrVJ5019543 for ; Thu, 1 Nov 2018 19:53:31 GMT Received: (from root@localhost) by netronome.com (8.15.2/8.15.2/Submit) id wA1JrV9L019542 for dev@dpdk.org; Thu, 1 Nov 2018 19:53:31 GMT From: Alejandro Lucero To: dev@dpdk.org Date: Thu, 1 Nov 2018 19:53:30 +0000 Message-Id: <20181101195330.19464-8-alejandro.lucero@netronome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181101195330.19464-1-alejandro.lucero@netronome.com> References: <20181101195330.19464-1-alejandro.lucero@netronome.com> Subject: [dpdk-dev] [PATCH v2 7/7] mem: add thread unsafe version for checking DMA mask X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" During memory initialization calling rte_mem_check_dma_mask leads to a deadlock because memory_hotplug_lock is locked by a writer, the current code in execution, and rte_memseg_walk tries to lock as a reader. This patch adds a thread_unsafe version which will call the final function specifying the memory_hotplug_lock does not need to be acquired. The patch also modified rte_mem_check_dma_mask as a intermediate step which will call the final function as before, implying memory_hotplug_lock will be acquired. PMDs should always use the version acquiring the lock with the thread_unsafe one being just for internal EAL memory code. Fixes: 223b7f1d5ef6 ("mem: add function for checking memseg IOVA") Signed-off-by: Alejandro Lucero --- lib/librte_eal/common/eal_common_memory.c | 24 +++++++++++++-- lib/librte_eal/common/include/rte_memory.h | 35 +++++++++++++++++++--- lib/librte_eal/common/malloc_heap.c | 2 +- lib/librte_eal/linuxapp/eal/eal_memory.c | 4 +-- lib/librte_eal/rte_eal_version.map | 1 + 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c index cc4f1d80f..87fd9921f 100644 --- a/lib/librte_eal/common/eal_common_memory.c +++ b/lib/librte_eal/common/eal_common_memory.c @@ -446,11 +446,12 @@ check_iova(const struct rte_memseg_list *msl __rte_unused, #endif /* check memseg iovas are within the required range based on dma mask */ -int __rte_experimental -rte_mem_check_dma_mask(uint8_t maskbits) +static int __rte_experimental +check_dma_mask(uint8_t maskbits, bool thread_unsafe) { struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; uint64_t mask; + int ret; /* sanity check */ if (maskbits > MAX_DMA_MASK_BITS) { @@ -462,7 +463,12 @@ rte_mem_check_dma_mask(uint8_t maskbits) /* create dma mask */ mask = ~((1ULL << maskbits) - 1); - if (rte_memseg_walk(check_iova, &mask)) + if (thread_unsafe) + ret = rte_memseg_walk_thread_unsafe(check_iova, &mask); + else + ret = rte_memseg_walk(check_iova, &mask); + + if (ret) /* * Dma mask precludes hugepage usage. * This device can not be used and we do not need to keep @@ -480,6 +486,18 @@ rte_mem_check_dma_mask(uint8_t maskbits) return 0; } +int __rte_experimental +rte_mem_check_dma_mask(uint8_t maskbits) +{ + return check_dma_mask(maskbits, false); +} + +int __rte_experimental +rte_mem_check_dma_mask_thread_unsafe(uint8_t maskbits) +{ + return check_dma_mask(maskbits, true); +} + /* * Set dma mask to use when memory initialization is done. * diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h index abbfe2364..d970825df 100644 --- a/lib/librte_eal/common/include/rte_memory.h +++ b/lib/librte_eal/common/include/rte_memory.h @@ -463,16 +463,43 @@ unsigned rte_memory_get_nchannel(void); */ unsigned rte_memory_get_nrank(void); -/* check memsegs iovas are within a range based on dma mask */ +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Check if all currently allocated memory segments are compliant with + * supplied DMA address width. + * + * @param maskbits + * Address width to check against. + */ int __rte_experimental rte_mem_check_dma_mask(uint8_t maskbits); /** * @warning * @b EXPERIMENTAL: this API may change without prior notice * - * Set dma mask to use once memory initialization is done. - * Previous function rte_mem_check_dma_mask can not be used - * safely until memory has been initialized. + * Check if all currently allocated memory segments are compliant with + * supplied DMA address width. This function will use + * rte_memseg_walk_thread_unsafe instead of rte_memseg_walk implying + * memory_hotplug_lock will not be acquired avoiding deadlock during + * memory initialization. + * + * This function is just for EAL core memory internal use. Drivers should + * use the previous rte_mem_check_dma_mask. + * + * @param maskbits + * Address width to check against. + */ +int __rte_experimental rte_mem_check_dma_mask_thread_unsafe(uint8_t maskbits); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Set dma mask to use once memory initialization is done. Previous functions + * rte_mem_check_dma_mask and rte_mem_check_dma_mask_thread_unsafe can not be + * used safely until memory has been initialized. */ void __rte_experimental rte_mem_set_dma_mask(uint8_t maskbits); diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c index c2c112aa6..c6a6d4f6b 100644 --- a/lib/librte_eal/common/malloc_heap.c +++ b/lib/librte_eal/common/malloc_heap.c @@ -334,7 +334,7 @@ alloc_pages_on_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size, * executed. For 2) implies the new memory can not be added. */ if (mcfg->dma_maskbits && - rte_mem_check_dma_mask(mcfg->dma_maskbits)) { + rte_mem_check_dma_mask_thread_unsafe(mcfg->dma_maskbits)) { /* * Currently this can only happen if IOMMU is enabled * and the address width supported by the IOMMU hw is diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c index c7935879a..c1b5e0791 100644 --- a/lib/librte_eal/linuxapp/eal/eal_memory.c +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c @@ -1394,7 +1394,7 @@ eal_legacy_hugepage_init(void) addr = RTE_PTR_ADD(addr, (size_t)page_sz); } if (mcfg->dma_maskbits && - rte_mem_check_dma_mask(mcfg->dma_maskbits)) { + rte_mem_check_dma_mask_thread_unsafe(mcfg->dma_maskbits)) { RTE_LOG(ERR, EAL, "%s(): couldnt allocate memory due to IOVA exceeding limits of current DMA mask.\n", __func__); @@ -1641,7 +1641,7 @@ eal_legacy_hugepage_init(void) } if (mcfg->dma_maskbits && - rte_mem_check_dma_mask(mcfg->dma_maskbits)) { + rte_mem_check_dma_mask_thread_unsafe(mcfg->dma_maskbits)) { RTE_LOG(ERR, EAL, "%s(): couldn't allocate memory due to IOVA exceeding limits of current DMA mask.\n", __func__); diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 51ee948ba..61bc5ca05 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -331,6 +331,7 @@ EXPERIMENTAL { rte_mem_alloc_validator_register; rte_mem_alloc_validator_unregister; rte_mem_check_dma_mask; + rte_mem_check_dma_mask_thread_unsafe; rte_mem_event_callback_register; rte_mem_event_callback_unregister; rte_mem_iova2virt;