From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from wes1-so2.wedos.net (wes1-so2.wedos.net [46.28.106.16]) by dpdk.org (Postfix) with ESMTP id 3E3A45A13 for ; Fri, 6 May 2016 15:50:11 +0200 (CEST) Received: from pcviktorin.fit.vutbr.cz (pcviktorin.fit.vutbr.cz [147.229.13.147]) by wes1-so2.wedos.net (Postfix) with ESMTPSA id 3r1Y7Q73qYz7HG; Fri, 6 May 2016 15:50:10 +0200 (CEST) From: Jan Viktorin To: dev@dpdk.org Cc: Jan Viktorin , David Marchand , Thomas Monjalon , Bruce Richardson , Declan Doherty , jianbo.liu@linaro.org, jerin.jacob@caviumnetworks.com, Keith Wiles , Stephen Hemminger Date: Fri, 6 May 2016 15:48:04 +0200 Message-Id: <1462542490-15556-23-git-send-email-viktorin@rehivetech.com> X-Mailer: git-send-email 2.8.0 In-Reply-To: <1462542490-15556-1-git-send-email-viktorin@rehivetech.com> References: <1462542490-15556-1-git-send-email-viktorin@rehivetech.com> In-Reply-To: <1451682326-5834-1-git-send-email-viktorin@rehivetech.com> References: <1451682326-5834-1-git-send-email-viktorin@rehivetech.com> Subject: [dpdk-dev] [PATCH v1 22/28] eal/soc: detect DMA non-coherent devices 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: , X-List-Received-Date: Fri, 06 May 2016 13:50:11 -0000 The SoC devices can be sometimes DMA non-coherent. This means that we need to take care of memory allocation for those. Generally, drivers assume that every device is DMA coherent. If a driver supports a DMA non-coherent device, it sets the RTE_SOC_DRV_ACCEPT_NONCC flag. Note that the is_dma_coherent flag have in fact the following semantics: * if true the device is DMA coherent * otherwise we don't know... Notes: The current dma-coherent detection is not perfect as the property may be placed in parent nodes of FDT as well. It is a question whether this detection is important here because the kernel drivers might help transparently. However, at the moment, there is no standard kernel driver that provides the proper memory (dma_alloc_coherent) to us. So we can either create one or patch the uio_dmem_genirq to be more generic (this is a way to go). Anyway, a custom mempool should be used here. Signed-off-by: Jan Viktorin --- lib/librte_eal/common/eal_common_soc.c | 8 ++++++++ lib/librte_eal/common/include/rte_soc.h | 3 +++ lib/librte_eal/linuxapp/eal/eal_soc.c | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c index 49dbcb8..4d32826 100644 --- a/lib/librte_eal/common/eal_common_soc.c +++ b/lib/librte_eal/common/eal_common_soc.c @@ -120,6 +120,14 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr, return 1; } + if (!dev->is_dma_coherent) { + if (!(dr->drv_flags & RTE_SOC_DRV_ACCEPT_NONCC)) { + RTE_LOG(DEBUG, EAL, + " device is not DMA coherent, skipping\n"); + return 1; + } + } + if (dr->drv_flags & RTE_SOC_DRV_NEED_MAPPING) { /* map resources */ ret = rte_eal_soc_map_device(dev); diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h index 50a3b35..2225a63 100644 --- a/lib/librte_eal/common/include/rte_soc.h +++ b/lib/librte_eal/common/include/rte_soc.h @@ -100,6 +100,7 @@ struct rte_soc_device { struct rte_intr_handle intr_handle; /**< Interrupt handle */ struct rte_soc_driver *driver; /**< Associated driver */ int numa_node; /**< NUMA node connection */ + int is_dma_coherent; /**< DMA coherent device */ struct rte_devargs *devargs; /**< Device user arguments */ enum rte_kernel_driver kdrv; /**< Kernel driver */ }; @@ -136,6 +137,8 @@ struct rte_soc_driver { #define RTE_SOC_DRV_INTR_LSC 0x0008 /** Device driver supports detaching capability */ #define RTE_SOC_DRV_DETACHABLE 0x0010 +/** Device driver accepts DMA non-coherent devices */ +#define RTE_SOC_DRV_ACCEPT_NONCC 0x0020 /** * A structure describing a SoC mapping. diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c index 6e9e242..5277fb7 100644 --- a/lib/librte_eal/linuxapp/eal/eal_soc.c +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c @@ -328,6 +328,25 @@ dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname) return ret; } +static int +dev_detect_is_coherent(struct rte_soc_device *dev) +{ + char filename[PATH_MAX]; + FILE *f; + + if (dev->addr.fdt_path == NULL) + return 0; /* no way to detect */ + + snprintf(filename, sizeof(filename), "%s%s/dma-coherent", + "/proc/device-tree", dev->addr.fdt_path); + if ((f = fopen(filename, "r")) == NULL) { + return 0; + } + + fclose(f); + return 1; +} + /** * Scan one SoC sysfs entry, and fill the devices list from it. * We require to have the uevent file with records: OF_FULLNAME and @@ -372,6 +391,10 @@ soc_scan_one(const char *dirname, const char *name) if ((ret = dev_setup_numa_node(dev, dirname)) < 0) goto fail; + dev->is_dma_coherent = dev_detect_is_coherent(dev); + RTE_LOG(DEBUG, EAL, " DMA %s\n", + dev->is_dma_coherent? "coherent" : "non-coherent"); + /* device is valid, add in list (sorted) */ if (TAILQ_EMPTY(&soc_device_list)) { TAILQ_INSERT_TAIL(&soc_device_list, dev, next); @@ -387,6 +410,7 @@ soc_scan_one(const char *dirname, const char *name) TAILQ_INSERT_BEFORE(dev2, dev, next); } else { /* already registered */ dev2->kdrv = dev->kdrv; + dev2->is_dma_coherent = dev->is_dma_coherent; memmove(dev2->mem_resource, dev->mem_resource, sizeof(dev->mem_resource)); -- 2.8.0