Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2021-01-28 Thread Daniel Mentz
On Fri, Oct 16, 2020 at 12:04 PM John Stultz  wrote:
>
> On Thu, Oct 8, 2020 at 4:51 AM Brian Starkey  wrote:
> > On Sat, Oct 03, 2020 at 04:02:57AM +, John Stultz wrote:
> > > @@ -393,6 +424,16 @@ static int system_heap_allocate(struct dma_heap 
> > > *heap,
> > >   /* just return, as put will call release and that will free 
> > > */
> > >   return ret;
> > >   }
> > > +
> > > + /*
> > > +  * For uncached buffers, we need to initially flush cpu cache, since
> > > +  * the __GFP_ZERO on the allocation means the zeroing was done by 
> > > the
> > > +  * cpu and thus it is likely cached. Map (and implicitly flush) it 
> > > out
> > > +  * now so we don't get corruption later on.
> > > +  */
> > > + if (buffer->uncached)
> > > + dma_map_sgtable(dma_heap_get_dev(heap), table, 
> > > DMA_BIDIRECTIONAL, 0);
> >
> > Do we have to keep this mapping around for the entire lifetime of the
> > buffer?
>
> Yea, I guess we can just map and unmap it right there.  It will look a
> little absurd, but that sort of aligns with your next point.
>
> > Also, this problem (and solution) keeps lingering around. It really
> > feels like there should be a better way to solve "clean the linear
> > mapping all the way to DRAM", but I don't know what that should be.
>
> Yea, something better here would be nice...

In ION, we had a little helper function named
ion_buffer_prep_noncached that called arch_dma_prep_coherent() on all
sg entries like so

for_each_sg(table->sgl, sg, table->orig_nents, i)
arch_dma_prep_coherent(sg_page(sg), sg->length);

Would that help?


Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-16 Thread John Stultz
On Fri, Oct 16, 2020 at 12:03 PM John Stultz  wrote:
> On Thu, Oct 8, 2020 at 4:51 AM Brian Starkey  wrote:
> > On Sat, Oct 03, 2020 at 04:02:57AM +, John Stultz wrote:
> > > @@ -426,6 +487,16 @@ static int system_heap_create(void)
> > >   if (IS_ERR(sys_heap))
> > >   return PTR_ERR(sys_heap);
> > >
> > > + exp_info.name = "system-uncached";
> > > + exp_info.ops = _uncached_heap_ops;
> > > + exp_info.priv = NULL;
> > > +
> > > + sys_uncached_heap = dma_heap_add(_info);
> > > + if (IS_ERR(sys_uncached_heap))
> > > + return PTR_ERR(sys_heap);
> > > +
> >
> > In principle, there's a race here between the heap getting registered
> > to sysfs and the dma_mask getting updated.
> >
> > I don't think it would cause a problem in practice, but with the API
> > as it is, there's no way to avoid it - so I wonder if the
> > dma_heap_get_dev() accessor isn't the right API design.
>
> Hrm.  I guess to address your concern we would need split
> dma_heap_add() into something like:
>   dma_heap_create()
>   dma_heap_add()
>
> Which breaks the creation of the heap with the registering it to the
> subsystem, so some attributes can be tweaked inbetween?

Looking at this some more, this approach isn't going to work. We
create the device and then we call dma_coerce_mask_and_coherent() on
it, but as soon as the device is created it seems possible for
userland to directly access it. Again, though, as you mentioned this
isn't terribly likely in practice.

The best thing I can think of for now is to have the uncached heap's
allocate pointer initially point to a dummy function that returns
EBUSY and then after we update the dma mask then we can set it to the
real alloc.  I'll go with that for now, but let me know if you have
other suggestions.

thanks
-john


Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-16 Thread John Stultz
On Thu, Oct 8, 2020 at 4:51 AM Brian Starkey  wrote:
> On Sat, Oct 03, 2020 at 04:02:57AM +, John Stultz wrote:
> > @@ -215,8 +236,12 @@ static void *system_heap_do_vmap(struct 
> > system_heap_buffer *buffer)
> >   struct page **pages = vmalloc(sizeof(struct page *) * npages);
> >   struct page **tmp = pages;
> >   struct sg_page_iter piter;
> > + pgprot_t pgprot = PAGE_KERNEL;
> >   void *vaddr;
> >
> > + if (buffer->uncached)
> > + pgprot = pgprot_writecombine(PAGE_KERNEL);
>
> I think this should go after the 'if (!pages)' check. Best to get the
> allocation failure check as close to the allocation as possible IMO.

Sounds good. Changed in my tree.

> > @@ -393,6 +424,16 @@ static int system_heap_allocate(struct dma_heap *heap,
> >   /* just return, as put will call release and that will free */
> >   return ret;
> >   }
> > +
> > + /*
> > +  * For uncached buffers, we need to initially flush cpu cache, since
> > +  * the __GFP_ZERO on the allocation means the zeroing was done by the
> > +  * cpu and thus it is likely cached. Map (and implicitly flush) it out
> > +  * now so we don't get corruption later on.
> > +  */
> > + if (buffer->uncached)
> > + dma_map_sgtable(dma_heap_get_dev(heap), table, 
> > DMA_BIDIRECTIONAL, 0);
>
> Do we have to keep this mapping around for the entire lifetime of the
> buffer?

Yea, I guess we can just map and unmap it right there.  It will look a
little absurd, but that sort of aligns with your next point.

> Also, this problem (and solution) keeps lingering around. It really
> feels like there should be a better way to solve "clean the linear
> mapping all the way to DRAM", but I don't know what that should be.

Yea, something better here would be nice...


> > @@ -426,6 +487,16 @@ static int system_heap_create(void)
> >   if (IS_ERR(sys_heap))
> >   return PTR_ERR(sys_heap);
> >
> > + exp_info.name = "system-uncached";
> > + exp_info.ops = _uncached_heap_ops;
> > + exp_info.priv = NULL;
> > +
> > + sys_uncached_heap = dma_heap_add(_info);
> > + if (IS_ERR(sys_uncached_heap))
> > + return PTR_ERR(sys_heap);
> > +
>
> In principle, there's a race here between the heap getting registered
> to sysfs and the dma_mask getting updated.
>
> I don't think it would cause a problem in practice, but with the API
> as it is, there's no way to avoid it - so I wonder if the
> dma_heap_get_dev() accessor isn't the right API design.

Hrm.  I guess to address your concern we would need split
dma_heap_add() into something like:
  dma_heap_create()
  dma_heap_add()

Which breaks the creation of the heap with the registering it to the
subsystem, so some attributes can be tweaked inbetween?

I'll see about taking a stab at this, but I'll probably submit my
updated series sooner with this un-addressed so I can get some further
review.

thanks
-john


Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-08 Thread Brian Starkey
On Sat, Oct 03, 2020 at 04:02:57AM +, John Stultz wrote:
> This adds a heap that allocates non-contiguous buffers that are
> marked as writecombined, so they are not cached by the CPU.
> 
> This is useful, as most graphics buffers are usually not touched
> by the CPU or only written into once by the CPU. So when mapping
> the buffer over and over between devices, we can skip the CPU
> syncing, which saves a lot of cache management overhead, greatly
> improving performance.
> 
> For folk using ION, there was a ION_FLAG_CACHED flag, which
> signaled if the returned buffer should be CPU cacheable or not.
> With DMA-BUF heaps, we do not yet have such a flag, and by default
> the current heaps (system and cma) produce CPU cachable buffers.
> So for folks transitioning from ION to DMA-BUF Heaps, this fills
> in some of that missing functionality.
> 
> There has been a suggestion to make this functionality a flag
> (DMAHEAP_FLAG_UNCACHED?) on the system heap, similar to how
> ION used the ION_FLAG_CACHED. But I want to make sure an
> _UNCACHED flag would truely be a generic attribute across all
> heaps. So far that has been unclear, so having it as a separate
> heap seemes better for now. (But I'm open to discussion on this
> point!)
> 
> This is a rework of earlier efforts to add a uncached system heap,
> done utilizing the exisitng system heap, adding just a bit of
> logic to handle the uncached case.
> 
> Feedback would be very welcome!
> 
> Many thanks to Liam Mark for his help to get this working.
> 
> Pending opensource users of this code include:
> * AOSP HiKey960 gralloc:
>   - https://android-review.googlesource.com/c/device/linaro/hikey/+/1399519
>   - Visibly improves performance over the system heap
> * AOSP Codec2 (possibly, needs more review):
>   - 
> https://android-review.googlesource.com/c/platform/frameworks/av/+/1360640/17/media/codec2/vndk/C2DmaBufAllocator.cpp#325
> 
> Cc: Sumit Semwal 
> Cc: Liam Mark 
> Cc: Laura Abbott 
> Cc: Brian Starkey 
> Cc: Hridya Valsaraju 
> Cc: Suren Baghdasaryan 
> Cc: Sandeep Patil 
> Cc: Daniel Mentz 
> Cc: Chris Goldsworthy 
> Cc: �rjan Eide 
> Cc: Robin Murphy 
> Cc: Ezequiel Garcia 
> Cc: Simon Ser 
> Cc: James Jones 
> Cc: linux-me...@vger.kernel.org
> Cc: dri-de...@lists.freedesktop.org
> Signed-off-by: John Stultz 
> ---
>  drivers/dma-buf/heaps/system_heap.c | 87 ++---
>  1 file changed, 79 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/dma-buf/heaps/system_heap.c 
> b/drivers/dma-buf/heaps/system_heap.c
> index 2b8d4b6abacb..952f1fd9dacf 100644
> --- a/drivers/dma-buf/heaps/system_heap.c
> +++ b/drivers/dma-buf/heaps/system_heap.c
> @@ -22,6 +22,7 @@
>  #include 
>  
>  struct dma_heap *sys_heap;
> +struct dma_heap *sys_uncached_heap;
>  
>  struct system_heap_buffer {
>   struct dma_heap *heap;
> @@ -31,6 +32,8 @@ struct system_heap_buffer {
>   struct sg_table sg_table;
>   int vmap_cnt;
>   void *vaddr;
> +
> + bool uncached;
>  };
>  
>  struct dma_heap_attachment {
> @@ -38,6 +41,8 @@ struct dma_heap_attachment {
>   struct sg_table *table;
>   struct list_head list;
>   bool mapped;
> +
> + bool uncached;
>  };
>  
>  #define HIGH_ORDER_GFP  (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \
> @@ -94,7 +99,7 @@ static int system_heap_attach(struct dma_buf *dmabuf,
>   a->dev = attachment->dev;
>   INIT_LIST_HEAD(>list);
>   a->mapped = false;
> -
> + a->uncached = buffer->uncached;
>   attachment->priv = a;
>  
>   mutex_lock(>lock);
> @@ -124,9 +129,13 @@ static struct sg_table *system_heap_map_dma_buf(struct 
> dma_buf_attachment *attac
>  {
>   struct dma_heap_attachment *a = attachment->priv;
>   struct sg_table *table = a->table;
> + int attr = 0;
>   int ret;
>  
> - ret = dma_map_sgtable(attachment->dev, table, direction, 0);
> + if (a->uncached)
> + attr = DMA_ATTR_SKIP_CPU_SYNC;
> +
> + ret = dma_map_sgtable(attachment->dev, table, direction, attr);
>   if (ret)
>   return ERR_PTR(ret);
>  
> @@ -139,9 +148,12 @@ static void system_heap_unmap_dma_buf(struct 
> dma_buf_attachment *attachment,
> enum dma_data_direction direction)
>  {
>   struct dma_heap_attachment *a = attachment->priv;
> + int attr = 0;
>  
> + if (a->uncached)
> + attr = DMA_ATTR_SKIP_CPU_SYNC;
>   a->mapped = false;
> - dma_unmap_sgtable(attachment->dev, table, direction, 0);
> + dma_unmap_sgtable(attachment->dev, table, direction, attr);
>  }
>  
>  static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
> @@ -150,6 +162,9 @@ static int system_heap_dma_buf_begin_cpu_access(struct 
> dma_buf *dmabuf,
>   struct system_heap_buffer *buffer = dmabuf->priv;
>   struct dma_heap_attachment *a;
>  
> + if (buffer->uncached)
> + return 0;
> +
>   mutex_lock(>lock);
>  
>   if (buffer->vmap_cnt)
> @@ -171,6 

Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-07 Thread John Stultz
On Wed, Oct 7, 2020 at 12:44 AM Dan Carpenter  wrote:
>
> Hi John,
>
> url:
> https://github.com/0day-ci/linux/commits/John-Stultz/dma-buf-Performance-improvements-for-system-heap-a-system-uncached-implementation/20201003-120520
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
> bcf876870b95592b52519ed4aafcf9d95999bc9c
> config: i386-randconfig-m021-20201002 (attached as .config)
> compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot 
> Reported-by: Dan Carpenter 
>
> smatch warnings:
> drivers/dma-buf/heaps/system_heap.c:496 system_heap_create() warn: passing 
> zero to 'PTR_ERR'
>
> vim +/PTR_ERR +496 drivers/dma-buf/heaps/system_heap.c
>
> efa04fefebbd724 John Stultz 2019-12-03  478  static int 
> system_heap_create(void)
> efa04fefebbd724 John Stultz 2019-12-03  479  {
> efa04fefebbd724 John Stultz 2019-12-03  480 struct 
> dma_heap_export_info exp_info;
> efa04fefebbd724 John Stultz 2019-12-03  481
> 263e38f82cbb35b Andrew F. Davis 2019-12-16  482 exp_info.name = 
> "system";
> efa04fefebbd724 John Stultz 2019-12-03  483 exp_info.ops = 
> _heap_ops;
> efa04fefebbd724 John Stultz 2019-12-03  484 exp_info.priv = NULL;
> efa04fefebbd724 John Stultz 2019-12-03  485
> efa04fefebbd724 John Stultz 2019-12-03  486 sys_heap = 
> dma_heap_add(_info);
> efa04fefebbd724 John Stultz 2019-12-03  487 if (IS_ERR(sys_heap))
> a2e10cdd2e4d12a John Stultz 2020-10-03  488 return 
> PTR_ERR(sys_heap);
> efa04fefebbd724 John Stultz 2019-12-03  489
> 553f4e0fafc5b3b John Stultz 2020-10-03  490 exp_info.name = 
> "system-uncached";
> 553f4e0fafc5b3b John Stultz 2020-10-03  491 exp_info.ops = 
> _uncached_heap_ops;
> 553f4e0fafc5b3b John Stultz 2020-10-03  492 exp_info.priv = NULL;
> 553f4e0fafc5b3b John Stultz 2020-10-03  493
> 553f4e0fafc5b3b John Stultz 2020-10-03  494 sys_uncached_heap = 
> dma_heap_add(_info);
> 553f4e0fafc5b3b John Stultz 2020-10-03  495 if 
> (IS_ERR(sys_uncached_heap))
> 553f4e0fafc5b3b John Stultz 2020-10-03 @496 return 
> PTR_ERR(sys_heap);
>
> ^
> This should be return PTR_ERR(sys_uncached_heap);

Oh nice! Very impressed that the tool caught that!
Thanks so much for the report! I'll fix it up here shortly.
-john


Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-07 Thread John Stultz
On Mon, Oct 5, 2020 at 6:45 AM Christoph Hellwig  wrote:
>
> How is this going to deal with VIVT caches?

Hrm. That's a good question.   I'm not sure I totally have my head
around it but, I guess we could make sure to call
invalidate_kernel_vmap_range() in begin_cpu_access()  and
flush_kernel_vmap_range() in end_cpu_access() rather then exiting out
early as we do now?

Unless you have better guidance?

Worse case we could check CONFIG_CPU_CACHE_VIVT and not register the
system-uncached heap.

thanks
-john


Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-07 Thread Dan Carpenter
Hi John,

url:
https://github.com/0day-ci/linux/commits/John-Stultz/dma-buf-Performance-improvements-for-system-heap-a-system-uncached-implementation/20201003-120520
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
bcf876870b95592b52519ed4aafcf9d95999bc9c
config: i386-randconfig-m021-20201002 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 
Reported-by: Dan Carpenter 

smatch warnings:
drivers/dma-buf/heaps/system_heap.c:496 system_heap_create() warn: passing zero 
to 'PTR_ERR'

vim +/PTR_ERR +496 drivers/dma-buf/heaps/system_heap.c

efa04fefebbd724 John Stultz 2019-12-03  478  static int 
system_heap_create(void)
efa04fefebbd724 John Stultz 2019-12-03  479  {
efa04fefebbd724 John Stultz 2019-12-03  480 struct 
dma_heap_export_info exp_info;
efa04fefebbd724 John Stultz 2019-12-03  481  
263e38f82cbb35b Andrew F. Davis 2019-12-16  482 exp_info.name = 
"system";
efa04fefebbd724 John Stultz 2019-12-03  483 exp_info.ops = 
_heap_ops;
efa04fefebbd724 John Stultz 2019-12-03  484 exp_info.priv = NULL;
efa04fefebbd724 John Stultz 2019-12-03  485  
efa04fefebbd724 John Stultz 2019-12-03  486 sys_heap = 
dma_heap_add(_info);
efa04fefebbd724 John Stultz 2019-12-03  487 if (IS_ERR(sys_heap))
a2e10cdd2e4d12a John Stultz 2020-10-03  488 return 
PTR_ERR(sys_heap);
efa04fefebbd724 John Stultz 2019-12-03  489  
553f4e0fafc5b3b John Stultz 2020-10-03  490 exp_info.name = 
"system-uncached";
553f4e0fafc5b3b John Stultz 2020-10-03  491 exp_info.ops = 
_uncached_heap_ops;
553f4e0fafc5b3b John Stultz 2020-10-03  492 exp_info.priv = NULL;
553f4e0fafc5b3b John Stultz 2020-10-03  493  
553f4e0fafc5b3b John Stultz 2020-10-03  494 sys_uncached_heap = 
dma_heap_add(_info);
553f4e0fafc5b3b John Stultz 2020-10-03  495 if 
(IS_ERR(sys_uncached_heap))
553f4e0fafc5b3b John Stultz 2020-10-03 @496 return 
PTR_ERR(sys_heap);
   
^
This should be return PTR_ERR(sys_uncached_heap);


---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-05 Thread kernel test robot
Hi John,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linux/master]
[also build test WARNING on tegra-drm/drm/tegra/for-next linus/master v5.9-rc8]
[cannot apply to next-20201002]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/John-Stultz/dma-buf-Performance-improvements-for-system-heap-a-system-uncached-implementation/20201003-120520
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
bcf876870b95592b52519ed4aafcf9d95999bc9c
config: i386-randconfig-s032-20201005 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.2-201-g24bdaac6-dirty
# 
https://github.com/0day-ci/linux/commit/553f4e0fafc5b3b4542ea0c7bc21a70fce504c7f
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
John-Stultz/dma-buf-Performance-improvements-for-system-heap-a-system-uncached-implementation/20201003-120520
git checkout 553f4e0fafc5b3b4542ea0c7bc21a70fce504c7f
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

echo
echo "sparse warnings: (new ones prefixed by >>)"
echo
>> drivers/dma-buf/heaps/system_heap.c:25:17: sparse: sparse: symbol 
>> 'sys_uncached_heap' was not declared. Should it be static?

Please review and possibly fold the followup patch.

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-05 Thread Christoph Hellwig
How is this going to deal with VIVT caches?


[PATCH v3 7/7] dma-buf: system_heap: Add a system-uncached heap re-using the system heap

2020-10-02 Thread John Stultz
This adds a heap that allocates non-contiguous buffers that are
marked as writecombined, so they are not cached by the CPU.

This is useful, as most graphics buffers are usually not touched
by the CPU or only written into once by the CPU. So when mapping
the buffer over and over between devices, we can skip the CPU
syncing, which saves a lot of cache management overhead, greatly
improving performance.

For folk using ION, there was a ION_FLAG_CACHED flag, which
signaled if the returned buffer should be CPU cacheable or not.
With DMA-BUF heaps, we do not yet have such a flag, and by default
the current heaps (system and cma) produce CPU cachable buffers.
So for folks transitioning from ION to DMA-BUF Heaps, this fills
in some of that missing functionality.

There has been a suggestion to make this functionality a flag
(DMAHEAP_FLAG_UNCACHED?) on the system heap, similar to how
ION used the ION_FLAG_CACHED. But I want to make sure an
_UNCACHED flag would truely be a generic attribute across all
heaps. So far that has been unclear, so having it as a separate
heap seemes better for now. (But I'm open to discussion on this
point!)

This is a rework of earlier efforts to add a uncached system heap,
done utilizing the exisitng system heap, adding just a bit of
logic to handle the uncached case.

Feedback would be very welcome!

Many thanks to Liam Mark for his help to get this working.

Pending opensource users of this code include:
* AOSP HiKey960 gralloc:
  - https://android-review.googlesource.com/c/device/linaro/hikey/+/1399519
  - Visibly improves performance over the system heap
* AOSP Codec2 (possibly, needs more review):
  - 
https://android-review.googlesource.com/c/platform/frameworks/av/+/1360640/17/media/codec2/vndk/C2DmaBufAllocator.cpp#325

Cc: Sumit Semwal 
Cc: Liam Mark 
Cc: Laura Abbott 
Cc: Brian Starkey 
Cc: Hridya Valsaraju 
Cc: Suren Baghdasaryan 
Cc: Sandeep Patil 
Cc: Daniel Mentz 
Cc: Chris Goldsworthy 
Cc: Ørjan Eide 
Cc: Robin Murphy 
Cc: Ezequiel Garcia 
Cc: Simon Ser 
Cc: James Jones 
Cc: linux-me...@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: John Stultz 
---
 drivers/dma-buf/heaps/system_heap.c | 87 ++---
 1 file changed, 79 insertions(+), 8 deletions(-)

diff --git a/drivers/dma-buf/heaps/system_heap.c 
b/drivers/dma-buf/heaps/system_heap.c
index 2b8d4b6abacb..952f1fd9dacf 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -22,6 +22,7 @@
 #include 
 
 struct dma_heap *sys_heap;
+struct dma_heap *sys_uncached_heap;
 
 struct system_heap_buffer {
struct dma_heap *heap;
@@ -31,6 +32,8 @@ struct system_heap_buffer {
struct sg_table sg_table;
int vmap_cnt;
void *vaddr;
+
+   bool uncached;
 };
 
 struct dma_heap_attachment {
@@ -38,6 +41,8 @@ struct dma_heap_attachment {
struct sg_table *table;
struct list_head list;
bool mapped;
+
+   bool uncached;
 };
 
 #define HIGH_ORDER_GFP  (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \
@@ -94,7 +99,7 @@ static int system_heap_attach(struct dma_buf *dmabuf,
a->dev = attachment->dev;
INIT_LIST_HEAD(>list);
a->mapped = false;
-
+   a->uncached = buffer->uncached;
attachment->priv = a;
 
mutex_lock(>lock);
@@ -124,9 +129,13 @@ static struct sg_table *system_heap_map_dma_buf(struct 
dma_buf_attachment *attac
 {
struct dma_heap_attachment *a = attachment->priv;
struct sg_table *table = a->table;
+   int attr = 0;
int ret;
 
-   ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+   if (a->uncached)
+   attr = DMA_ATTR_SKIP_CPU_SYNC;
+
+   ret = dma_map_sgtable(attachment->dev, table, direction, attr);
if (ret)
return ERR_PTR(ret);
 
@@ -139,9 +148,12 @@ static void system_heap_unmap_dma_buf(struct 
dma_buf_attachment *attachment,
  enum dma_data_direction direction)
 {
struct dma_heap_attachment *a = attachment->priv;
+   int attr = 0;
 
+   if (a->uncached)
+   attr = DMA_ATTR_SKIP_CPU_SYNC;
a->mapped = false;
-   dma_unmap_sgtable(attachment->dev, table, direction, 0);
+   dma_unmap_sgtable(attachment->dev, table, direction, attr);
 }
 
 static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
@@ -150,6 +162,9 @@ static int system_heap_dma_buf_begin_cpu_access(struct 
dma_buf *dmabuf,
struct system_heap_buffer *buffer = dmabuf->priv;
struct dma_heap_attachment *a;
 
+   if (buffer->uncached)
+   return 0;
+
mutex_lock(>lock);
 
if (buffer->vmap_cnt)
@@ -171,6 +186,9 @@ static int system_heap_dma_buf_end_cpu_access(struct 
dma_buf *dmabuf,
struct system_heap_buffer *buffer = dmabuf->priv;
struct dma_heap_attachment *a;
 
+   if (buffer->uncached)
+   return 0;
+
mutex_lock(>lock);
 
if