[1/2] drivers: dma-coherent: Add support for default DMA coherent pool
diff mbox

Message ID 1499093475-29859-2-git-send-email-vitaly_kuzmichev@mentor.com
State Changes Requested, archived
Headers show

Commit Message

vitaly_kuzmichev@mentor.com July 3, 2017, 2:51 p.m. UTC
From: "George G. Davis" <george_davis@mentor.com>

Use concept similar to the default CMA region for DMA coherent pools.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: Mark Craske <Mark_Craske@mentor.com>
Signed-off-by: Vitaly Kuzmichev <Vitaly_Kuzmichev@mentor.com>
---
 .../bindings/reserved-memory/reserved-memory.txt   |  2 ++
 drivers/base/dma-coherent.c                        | 29 ++++++++++++++++------
 2 files changed, 24 insertions(+), 7 deletions(-)

Comments

kernel test robot July 4, 2017, 9:02 p.m. UTC | #1
Hi George,

[auto build test ERROR on staging/staging-testing]
[also build test ERROR on v4.12]
[cannot apply to next-20170704]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/vitaly_kuzmichev-mentor-com/drivers-dma-coherent-Add-support-for-default-DMA-coherent-pool/20170705-040238
config: i386-randconfig-x075-07041126 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/base/dma-coherent.c: In function 'dev_get_dma_area':
>> drivers/base/dma-coherent.c:28:16: error: 'struct device' has no member named 'cma_area'; did you mean 'dma_parms'?
     if (dev && dev->cma_area)
                   ^~

vim +28 drivers/base/dma-coherent.c

    22	
    23	static inline struct dma_coherent_mem *dev_get_dma_area(struct device *dev)
    24	{
    25		if (dev && dev->dma_mem)
    26			return dev->dma_mem;
    27	#ifdef CONFIG_CMA
  > 28		if (dev && dev->cma_area)
    29			return NULL;
    30	#endif
    31		return dma_coherent_default_area ? *dma_coherent_default_area : NULL;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot July 5, 2017, 5:55 a.m. UTC | #2
Hi George,

[auto build test ERROR on staging/staging-testing]
[also build test ERROR on v4.12]
[cannot apply to next-20170704]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/vitaly_kuzmichev-mentor-com/drivers-dma-coherent-Add-support-for-default-DMA-coherent-pool/20170705-040238
config: i386-randconfig-c0-07051154 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   In file included from include/uapi/linux/stddef.h:1:0,
                    from include/linux/stddef.h:4,
                    from include/uapi/linux/posix_types.h:4,
                    from include/uapi/linux/types.h:13,
                    from include/linux/types.h:5,
                    from include/linux/io.h:21,
                    from drivers//base/dma-coherent.c:5:
   drivers//base/dma-coherent.c: In function 'dev_get_dma_area':
>> drivers//base/dma-coherent.c:28:16: error: 'struct device' has no member named 'cma_area'
     if (dev && dev->cma_area)
                   ^
   include/linux/compiler.h:160:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^
>> drivers//base/dma-coherent.c:28:2: note: in expansion of macro 'if'
     if (dev && dev->cma_area)
     ^
>> drivers//base/dma-coherent.c:28:16: error: 'struct device' has no member named 'cma_area'
     if (dev && dev->cma_area)
                   ^
   include/linux/compiler.h:160:42: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                             ^
>> drivers//base/dma-coherent.c:28:2: note: in expansion of macro 'if'
     if (dev && dev->cma_area)
     ^
>> drivers//base/dma-coherent.c:28:16: error: 'struct device' has no member named 'cma_area'
     if (dev && dev->cma_area)
                   ^
   include/linux/compiler.h:171:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^
>> drivers//base/dma-coherent.c:28:2: note: in expansion of macro 'if'
     if (dev && dev->cma_area)
     ^

vim +28 drivers//base/dma-coherent.c

     1	/*
     2	 * Coherent per-device memory handling.
     3	 * Borrowed from i386
     4	 */
   > 5	#include <linux/io.h>
     6	#include <linux/slab.h>
     7	#include <linux/kernel.h>
     8	#include <linux/module.h>
     9	#include <linux/dma-mapping.h>
    10	
    11	struct dma_coherent_mem {
    12		void		*virt_base;
    13		dma_addr_t	device_base;
    14		unsigned long	pfn_base;
    15		int		size;
    16		int		flags;
    17		unsigned long	*bitmap;
    18		spinlock_t	spinlock;
    19	};
    20	
    21	static struct dma_coherent_mem **dma_coherent_default_area;
    22	
    23	static inline struct dma_coherent_mem *dev_get_dma_area(struct device *dev)
    24	{
    25		if (dev && dev->dma_mem)
    26			return dev->dma_mem;
    27	#ifdef CONFIG_CMA
  > 28		if (dev && dev->cma_area)
    29			return NULL;
    30	#endif
    31		return dma_coherent_default_area ? *dma_coherent_default_area : NULL;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Rob Herring July 10, 2017, 12:36 a.m. UTC | #3
On Mon, Jul 03, 2017 at 05:51:14PM +0300, vitaly_kuzmichev@mentor.com wrote:
> From: "George G. Davis" <george_davis@mentor.com>
> 
> Use concept similar to the default CMA region for DMA coherent pools.

Why do we need this in DT? CMA is a carveout and has to be reserved 
early, but DMA coherent memory is just different MMU attributes, right?

Also, does this still apply with DMA mapping changes in 4.13?

> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: George G. Davis <george_davis@mentor.com>
> Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
> Signed-off-by: Mark Craske <Mark_Craske@mentor.com>
> Signed-off-by: Vitaly Kuzmichev <Vitaly_Kuzmichev@mentor.com>
> ---
>  .../bindings/reserved-memory/reserved-memory.txt   |  2 ++
>  drivers/base/dma-coherent.c                        | 29 ++++++++++++++++------
>  2 files changed, 24 insertions(+), 7 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
index 3da0ebd..ed9a051 100644
--- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -67,6 +67,8 @@  reusable (optional) - empty property
 Linux implementation note:
 - If a "linux,cma-default" property is present, then Linux will use the
   region for the default pool of the contiguous memory allocator.
+- If a "linux,dma-default" property is present, then Linux will use the
+  region for the default pool of the DMA coherent memory allocator.
 
 Device node references to reserved memory
 -----------------------------------------
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 640a7e6..a0b0f2b 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -18,6 +18,19 @@  struct dma_coherent_mem {
 	spinlock_t	spinlock;
 };
 
+static struct dma_coherent_mem **dma_coherent_default_area;
+
+static inline struct dma_coherent_mem *dev_get_dma_area(struct device *dev)
+{
+	if (dev && dev->dma_mem)
+		return dev->dma_mem;
+#ifdef CONFIG_CMA
+	if (dev && dev->cma_area)
+		return NULL;
+#endif
+	return dma_coherent_default_area ? *dma_coherent_default_area : NULL;
+}
+
 static bool dma_init_coherent_memory(
 	phys_addr_t phys_addr, dma_addr_t device_addr, size_t size, int flags,
 	struct dma_coherent_mem **mem)
@@ -111,7 +124,7 @@  int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
 
 void dma_release_declared_memory(struct device *dev)
 {
-	struct dma_coherent_mem *mem = dev->dma_mem;
+	struct dma_coherent_mem *mem = dev_get_dma_area(dev);
 
 	if (!mem)
 		return;
@@ -123,7 +136,7 @@  void dma_release_declared_memory(struct device *dev)
 void *dma_mark_declared_memory_occupied(struct device *dev,
 					dma_addr_t device_addr, size_t size)
 {
-	struct dma_coherent_mem *mem = dev->dma_mem;
+	struct dma_coherent_mem *mem = dev_get_dma_area(dev);
 	unsigned long flags;
 	int pos, err;
 
@@ -167,9 +180,7 @@  int dma_alloc_from_coherent(struct device *dev, ssize_t size,
 	int pageno;
 	int dma_memory_map;
 
-	if (!dev)
-		return 0;
-	mem = dev->dma_mem;
+	mem = dev_get_dma_area(dev);
 	if (!mem)
 		return 0;
 
@@ -223,7 +234,7 @@  int dma_alloc_from_coherent(struct device *dev, ssize_t size,
  */
 int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
 {
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
+	struct dma_coherent_mem *mem = dev_get_dma_area(dev);
 
 	if (mem && vaddr >= mem->virt_base && vaddr <
 		   (mem->virt_base + (mem->size << PAGE_SHIFT))) {
@@ -257,7 +268,7 @@  int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
 int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
 			   void *vaddr, size_t size, int *ret)
 {
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
+	struct dma_coherent_mem *mem = dev_get_dma_area(dev);
 
 	if (mem && vaddr >= mem->virt_base && vaddr + size <=
 		   (mem->virt_base + (mem->size << PAGE_SHIFT))) {
@@ -329,6 +340,10 @@  static int __init rmem_dma_setup(struct reserved_mem *rmem)
 	}
 #endif
 
+	if (of_get_flat_dt_prop(node, "linux,dma-default", NULL))
+		dma_coherent_default_area =
+			(struct dma_coherent_mem **)&rmem->priv;
+
 	rmem->ops = &rmem_dma_ops;
 	pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n",
 		&rmem->base, (unsigned long)rmem->size / SZ_1M);