Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework

2013-06-26 Thread Inki Dae
2013/6/25 Jerome Glisse j.gli...@gmail.com:
 On Tue, Jun 25, 2013 at 10:17 AM, Inki Dae daei...@gmail.com wrote:
 2013/6/25 Rob Clark robdcl...@gmail.com:
 On Tue, Jun 25, 2013 at 5:09 AM, Inki Dae daei...@gmail.com wrote:
 that
 should be the role of kernel memory management which of course needs
 synchronization btw A and B. But in no case this should be done using
 dma-buf. dma-buf is for sharing content btw different devices not
 sharing resources.


 hmm, is that true? And are you sure? Then how do you think about
 reservation? the reservation also uses dma-buf with same reason as long
 as I
 know: actually, we use reservation to use dma-buf. As you may know, a
 reservation object is allocated and initialized when a buffer object is
 exported to a dma buf.

 no, this is why the reservation object can be passed in when you
 construction the dmabuf.

 Right, that way, we could use dma buf for buffer synchronization. I
 just wanted to ask for why Jerome said that dma-buf is for sharing
 content btw different devices not sharing resources.

 From memory, the motivation of dma-buf was to done for few use case,
 among them webcam capturing frame into a buffer and having gpu using
 it directly without memcpy, or one big gpu rendering a scene into a
 buffer that is then use by low power gpu for display ie it was done to
 allow different device to operate on same data using same backing
 memory.

 AFAICT you seem to want to use dma-buf to create scratch buffer, ie a
 process needs to use X amount of memory for an operation, it can
 release|free this memory once its done
 and a process B can the use
 this X memory for its own operation discarding content of process A.
 presume that next frame would have the sequence repeat, process A do
 something, then process B does its thing.
 So to me it sounds like you
 want to implement global scratch buffer using the dmabuf API and that
 sounds bad to me.

 I know most closed driver have several pool of memory, long lived
 object, short lived object and scratch space, then user space allocate
 from one of this pool and there is synchronization done by driver
 using driver specific API to reclaim memory.
 Of course this work
 nicely if you only talking about one logic block or at very least hw
 that have one memory controller.

 Now if you are thinking of doing scratch buffer for several different
 device and share the memory among then you need to be aware of
 security implication, most obvious being that you don't want process B
 being able to read process A scratch memory.
 I know the argument about
 it being graphic but one day this might become gpu code and it might
 be able to insert jump to malicious gpu code.


If you think so, it seems like that there is *definitely* your
misunderstanding. My approach is similar to dma fence: it guarantees
that a DMA cannot access a buffer while other DMA is accessing the
buffer. I guess now some gpu drivers in mainline have been using
specific mechanism for it. And when it comes to the portion you
commented, please know that I just introduced user side mechanism for
buffer sychronization between CPU and CPU, and CPU and DMA in
addition; not implemented but just planned.

Thanks,
Inki Dae

 Cheers,
 Jerome
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework

2013-06-25 Thread Rob Clark
On Tue, Jun 25, 2013 at 5:09 AM, Inki Dae daei...@gmail.com wrote:
 that
 should be the role of kernel memory management which of course needs
 synchronization btw A and B. But in no case this should be done using
 dma-buf. dma-buf is for sharing content btw different devices not
 sharing resources.


 hmm, is that true? And are you sure? Then how do you think about
 reservation? the reservation also uses dma-buf with same reason as long as I
 know: actually, we use reservation to use dma-buf. As you may know, a
 reservation object is allocated and initialized when a buffer object is
 exported to a dma buf.

no, this is why the reservation object can be passed in when you
construction the dmabuf.  The fallback is for dmabuf to create it's
own, for compatibility and to make life easier for simple devices with
few buffers... but I think pretty much all drm drivers would embed the
reservation object in the gem buffer and pass it in when the dmabuf is
created.

It is pretty much imperative that synchronization works independently
of dmabuf, you really don't want to have two different cases to deal
with in your driver, one for synchronizing non-exported objects, and
one for synchronizing dmabuf objects.

BR,
-R
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework

2013-06-25 Thread Inki Dae
2013/6/25 Rob Clark robdcl...@gmail.com:
 On Tue, Jun 25, 2013 at 5:09 AM, Inki Dae daei...@gmail.com wrote:
 that
 should be the role of kernel memory management which of course needs
 synchronization btw A and B. But in no case this should be done using
 dma-buf. dma-buf is for sharing content btw different devices not
 sharing resources.


 hmm, is that true? And are you sure? Then how do you think about
 reservation? the reservation also uses dma-buf with same reason as long as I
 know: actually, we use reservation to use dma-buf. As you may know, a
 reservation object is allocated and initialized when a buffer object is
 exported to a dma buf.

 no, this is why the reservation object can be passed in when you
 construction the dmabuf.

Right, that way, we could use dma buf for buffer synchronization. I
just wanted to ask for why Jerome said that dma-buf is for sharing
content btw different devices not sharing resources.

 The fallback is for dmabuf to create it's
 own, for compatibility and to make life easier for simple devices with
 few buffers... but I think pretty much all drm drivers would embed the
 reservation object in the gem buffer and pass it in when the dmabuf is
 created.

 It is pretty much imperative that synchronization works independently
 of dmabuf, you really don't want to have two different cases to deal
 with in your driver, one for synchronizing non-exported objects, and
 one for synchronizing dmabuf objects.


Now my approach is concentrating on the most basic implementation,
buffer synchronization mechanism between CPU and CPU, CPU and DMA, and
DMA and DMA.  But I think reserveration could be used for other
purposes such as pipe line synchronization independently of dmabuf as
you said. Actually, I had already implemented pipe line
synchronization mechanism using the reservation: in case of MALI-400
DDK, there was pipe line issue between gp and pp jobs, and we had
solved the issue using the pipe line synchronization mechanism with
the reservation. So, we could add more features anytime; those two
different cases, dmabuf objects and non-exported objects, if needed
because we are using the reservation object.

Thanks,
Inki Dae

 BR,
 -R
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework

2013-06-25 Thread Jerome Glisse
On Tue, Jun 25, 2013 at 10:17 AM, Inki Dae daei...@gmail.com wrote:
 2013/6/25 Rob Clark robdcl...@gmail.com:
 On Tue, Jun 25, 2013 at 5:09 AM, Inki Dae daei...@gmail.com wrote:
 that
 should be the role of kernel memory management which of course needs
 synchronization btw A and B. But in no case this should be done using
 dma-buf. dma-buf is for sharing content btw different devices not
 sharing resources.


 hmm, is that true? And are you sure? Then how do you think about
 reservation? the reservation also uses dma-buf with same reason as long as I
 know: actually, we use reservation to use dma-buf. As you may know, a
 reservation object is allocated and initialized when a buffer object is
 exported to a dma buf.

 no, this is why the reservation object can be passed in when you
 construction the dmabuf.

 Right, that way, we could use dma buf for buffer synchronization. I
 just wanted to ask for why Jerome said that dma-buf is for sharing
 content btw different devices not sharing resources.

From memory, the motivation of dma-buf was to done for few use case,
among them webcam capturing frame into a buffer and having gpu using
it directly without memcpy, or one big gpu rendering a scene into a
buffer that is then use by low power gpu for display ie it was done to
allow different device to operate on same data using same backing
memory.

AFAICT you seem to want to use dma-buf to create scratch buffer, ie a
process needs to use X amount of memory for an operation, it can
release|free this memory once its done and a process B can the use
this X memory for its own operation discarding content of process A. I
presume that next frame would have the sequence repeat, process A do
something, then process B does its thing. So to me it sounds like you
want to implement global scratch buffer using the dmabuf API and that
sounds bad to me.

I know most closed driver have several pool of memory, long lived
object, short lived object and scratch space, then user space allocate
from one of this pool and there is synchronization done by driver
using driver specific API to reclaim memory. Of course this work
nicely if you only talking about one logic block or at very least hw
that have one memory controller.

Now if you are thinking of doing scratch buffer for several different
device and share the memory among then you need to be aware of
security implication, most obvious being that you don't want process B
being able to read process A scratch memory. I know the argument about
it being graphic but one day this might become gpu code and it might
be able to insert jump to malicious gpu code.

Cheers,
Jerome
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework

2013-06-13 Thread Inki Dae
This patch adds a buffer synchronization framework based on DMA BUF[1]
and reservation[2] to use dma-buf resource, and based on ww-mutexes[3]
for lock mechanism.

The purpose of this framework is not only to couple cache operations,
and buffer access control to CPU and DMA but also to provide easy-to-use
interfaces for device drivers and potentially user application
(not implemented for user applications, yet). And this framework can be
used for all dma devices using system memory as dma buffer, especially
for most ARM based SoCs.

The mechanism of this framework has the following steps,
1. Register dmabufs to a sync object - A task gets a new sync object and
can add one or more dmabufs that the task wants to access.
This registering should be performed when a device context or an event
context such as a page flip event is created or before CPU accesses a shared
buffer.

dma_buf_sync_get(a sync object, a dmabuf);

2. Lock a sync object - A task tries to lock all dmabufs added in its own
sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid dead
lock issue and for race condition between CPU and CPU, CPU and DMA, and DMA
and DMA. Taking a lock means that others cannot access all locked dmabufs
until the task that locked the corresponding dmabufs, unlocks all the locked
dmabufs.
This locking should be performed before DMA or CPU accesses these dmabufs.

dma_buf_sync_lock(a sync object);

3. Unlock a sync object - The task unlocks all dmabufs added in its own sync
object. The unlock means that the DMA or CPU accesses to the dmabufs have
been completed so that others may access them.
This unlocking should be performed after DMA or CPU has completed accesses
to the dmabufs.

dma_buf_sync_unlock(a sync object);

4. Unregister one or all dmabufs from a sync object - A task unregisters
the given dmabufs from the sync object. This means that the task dosen't
want to lock the dmabufs.
The unregistering should be performed after DMA or CPU has completed
accesses to the dmabufs or when dma_buf_sync_lock() is failed.

dma_buf_sync_put(a sync object, a dmabuf);
dma_buf_sync_put_all(a sync object);

The described steps may be summarized as:
get - lock - CPU or DMA access to a buffer/s - unlock - put

This framework includes the following two features.
1. read (shared) and write (exclusive) locks - A task is required to declare
the access type when the task tries to register a dmabuf;
READ, WRITE, READ DMA, or WRITE DMA.

The below is example codes,
struct dmabuf_sync *sync;

sync = dmabuf_sync_init(NULL, test sync);

dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
...

And the below can be used as access types:
DMA_BUF_ACCESS_READ,
- CPU will access a buffer for read.
DMA_BUF_ACCESS_WRITE,
- CPU will access a buffer for read or write.
DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA,
- DMA will access a buffer for read
DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA,
- DMA will access a buffer for read or write.

2. Mandatory resource releasing - a task cannot hold a lock indefinitely.
A task may never try to unlock a buffer after taking a lock to the buffer.
In this case, a timer handler to the corresponding sync object is called
in five (default) seconds and then the timed-out buffer is unlocked by work
queue handler to avoid lockups and to enforce resources of the buffer.

The below is how to use:
1. Allocate and Initialize a sync object:
struct dmabuf_sync *sync;

sync = dmabuf_sync_init(NULL, test sync);
...

2. Add a dmabuf to the sync object when setting up dma buffer relevant
   registers:
dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
...

3. Lock all dmabufs of the sync object before DMA or CPU accesses
   the dmabufs:
dmabuf_sync_lock(sync);
...

4. Now CPU or DMA can access all dmabufs locked in step 3.

5. Unlock all dmabufs added in a sync object after DMA or CPU access
   to these dmabufs is completed:
dmabuf_sync_unlock(sync);

   And call the following functions to release all resources,
dmabuf_sync_put_all(sync);
dmabuf_sync_fini(sync);

You can refer to actual example codes:

https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-exynos.git/

commit/?h=dmabuf-syncid=4030bdee9bab5841ad32faade528d04cc0c5fc94


https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-exynos.git/

commit/?h=dmabuf-syncid=6ca548e9ea9e865592719ef6b1cde58366af9f5c

The framework 

RE: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework

2013-06-13 Thread Inki Dae

 +static void dmabuf_sync_timeout_worker(struct work_struct *work)
 +{
 + struct dmabuf_sync *sync = container_of(work, struct dmabuf_sync,
 work);
 + struct dmabuf_sync_object *sobj;
 +
 + mutex_lock(sync-lock);
 +
 + list_for_each_entry(sobj, sync-syncs, head) {
 + if (WARN_ON(!sobj-robj))
 + continue;
 +
 + printk(KERN_WARNING %s: timeout = 0x%x [type = %d,  \
 + refcnt = %d, locked = %d]\n,
 + sync-name, (u32)sobj-dmabuf,
 + sobj-access_type,
 +
atomic_read(sobj-robj-shared_cnt),
 + sobj-robj-locked);
 +
 + /* unlock only valid sync object. */
 + if (!sobj-robj-locked)
 + continue;
 +
 + if (sobj-robj-shared 
 + atomic_read(sobj-robj-shared_cnt)  1) {
 + atomic_dec(sobj-robj-shared_cnt);
 + continue;
 + }
 +
 + ww_mutex_unlock(sobj-robj-lock);
 +
 + if (sobj-access_type  DMA_BUF_ACCESS_READ)
 + printk(KERN_WARNING %s: r-unlocked = 0x%x\n,
 + sync-name, (u32)sobj-dmabuf);
 + else
 + printk(KERN_WARNING %s: w-unlocked = 0x%x\n,
 + sync-name, (u32)sobj-dmabuf);
 +
 +#if defined(CONFIG_DEBUG_FS)
 + sync_debugfs_timeout_cnt++;
 +#endif

Oops, unnecessary codes. will remove them.

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework

2013-06-13 Thread Russell King - ARM Linux
On Thu, Jun 13, 2013 at 05:28:08PM +0900, Inki Dae wrote:
 This patch adds a buffer synchronization framework based on DMA BUF[1]
 and reservation[2] to use dma-buf resource, and based on ww-mutexes[3]
 for lock mechanism.
 
 The purpose of this framework is not only to couple cache operations,
 and buffer access control to CPU and DMA but also to provide easy-to-use
 interfaces for device drivers and potentially user application
 (not implemented for user applications, yet). And this framework can be
 used for all dma devices using system memory as dma buffer, especially
 for most ARM based SoCs.
 
 The mechanism of this framework has the following steps,
 1. Register dmabufs to a sync object - A task gets a new sync object and
 can add one or more dmabufs that the task wants to access.
 This registering should be performed when a device context or an event
 context such as a page flip event is created or before CPU accesses a 
 shared
 buffer.
 
   dma_buf_sync_get(a sync object, a dmabuf);
 
 2. Lock a sync object - A task tries to lock all dmabufs added in its own
 sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid dead
 lock issue and for race condition between CPU and CPU, CPU and DMA, and 
 DMA
 and DMA. Taking a lock means that others cannot access all locked dmabufs
 until the task that locked the corresponding dmabufs, unlocks all the 
 locked
 dmabufs.
 This locking should be performed before DMA or CPU accesses these dmabufs.
 
   dma_buf_sync_lock(a sync object);
 
 3. Unlock a sync object - The task unlocks all dmabufs added in its own 
 sync
 object. The unlock means that the DMA or CPU accesses to the dmabufs have
 been completed so that others may access them.
 This unlocking should be performed after DMA or CPU has completed accesses
 to the dmabufs.
 
   dma_buf_sync_unlock(a sync object);
 
 4. Unregister one or all dmabufs from a sync object - A task unregisters
 the given dmabufs from the sync object. This means that the task dosen't
 want to lock the dmabufs.
 The unregistering should be performed after DMA or CPU has completed
 accesses to the dmabufs or when dma_buf_sync_lock() is failed.
 
   dma_buf_sync_put(a sync object, a dmabuf);
   dma_buf_sync_put_all(a sync object);
 
 The described steps may be summarized as:
   get - lock - CPU or DMA access to a buffer/s - unlock - put
 
 This framework includes the following two features.
 1. read (shared) and write (exclusive) locks - A task is required to 
 declare
 the access type when the task tries to register a dmabuf;
 READ, WRITE, READ DMA, or WRITE DMA.
 
 The below is example codes,
   struct dmabuf_sync *sync;
 
   sync = dmabuf_sync_init(NULL, test sync);
 
   dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
   ...
 
   And the below can be used as access types:
   DMA_BUF_ACCESS_READ,
   - CPU will access a buffer for read.
   DMA_BUF_ACCESS_WRITE,
   - CPU will access a buffer for read or write.
   DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA,
   - DMA will access a buffer for read
   DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA,
   - DMA will access a buffer for read or write.
 
 2. Mandatory resource releasing - a task cannot hold a lock indefinitely.
 A task may never try to unlock a buffer after taking a lock to the buffer.
 In this case, a timer handler to the corresponding sync object is called
 in five (default) seconds and then the timed-out buffer is unlocked by 
 work
 queue handler to avoid lockups and to enforce resources of the buffer.
 
 The below is how to use:
   1. Allocate and Initialize a sync object:
   struct dmabuf_sync *sync;
 
   sync = dmabuf_sync_init(NULL, test sync);
   ...
 
   2. Add a dmabuf to the sync object when setting up dma buffer relevant
  registers:
   dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
   ...
 
   3. Lock all dmabufs of the sync object before DMA or CPU accesses
  the dmabufs:
   dmabuf_sync_lock(sync);
   ...
 
   4. Now CPU or DMA can access all dmabufs locked in step 3.
 
   5. Unlock all dmabufs added in a sync object after DMA or CPU access
  to these dmabufs is completed:
   dmabuf_sync_unlock(sync);
 
  And call the following functions to release all resources,
   dmabuf_sync_put_all(sync);
   dmabuf_sync_fini(sync);
 
   You can refer to actual example codes:
   
 https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-exynos.git/
   
 commit/?h=dmabuf-syncid=4030bdee9bab5841ad32faade528d04cc0c5fc94
 
   
 

RE: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework

2013-06-13 Thread Inki Dae
Hi Russell,

 -Original Message-
 From: Russell King - ARM Linux [mailto:li...@arm.linux.org.uk]
 Sent: Friday, June 14, 2013 2:26 AM
 To: Inki Dae
 Cc: maarten.lankho...@canonical.com; dan...@ffwll.ch; robdcl...@gmail.com;
 linux-fb...@vger.kernel.org; dri-de...@lists.freedesktop.org;
 kyungmin.p...@samsung.com; myungjoo@samsung.com; yj44@samsung.com;
 linux-arm-ker...@lists.infradead.org; linux-media@vger.kernel.org
 Subject: Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization
 framework
 
 On Thu, Jun 13, 2013 at 05:28:08PM +0900, Inki Dae wrote:
  This patch adds a buffer synchronization framework based on DMA BUF[1]
  and reservation[2] to use dma-buf resource, and based on ww-mutexes[3]
  for lock mechanism.
 
  The purpose of this framework is not only to couple cache operations,
  and buffer access control to CPU and DMA but also to provide easy-to-use
  interfaces for device drivers and potentially user application
  (not implemented for user applications, yet). And this framework can be
  used for all dma devices using system memory as dma buffer, especially
  for most ARM based SoCs.
 
  The mechanism of this framework has the following steps,
  1. Register dmabufs to a sync object - A task gets a new sync object
 and
  can add one or more dmabufs that the task wants to access.
  This registering should be performed when a device context or an
 event
  context such as a page flip event is created or before CPU accesses
a
 shared
  buffer.
 
  dma_buf_sync_get(a sync object, a dmabuf);
 
  2. Lock a sync object - A task tries to lock all dmabufs added in
its
 own
  sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid
 dead
  lock issue and for race condition between CPU and CPU, CPU and DMA,
 and DMA
  and DMA. Taking a lock means that others cannot access all locked
 dmabufs
  until the task that locked the corresponding dmabufs, unlocks all
the
 locked
  dmabufs.
  This locking should be performed before DMA or CPU accesses these
 dmabufs.
 
  dma_buf_sync_lock(a sync object);
 
  3. Unlock a sync object - The task unlocks all dmabufs added in its
 own sync
  object. The unlock means that the DMA or CPU accesses to the dmabufs
 have
  been completed so that others may access them.
  This unlocking should be performed after DMA or CPU has completed
 accesses
  to the dmabufs.
 
  dma_buf_sync_unlock(a sync object);
 
  4. Unregister one or all dmabufs from a sync object - A task
 unregisters
  the given dmabufs from the sync object. This means that the task
 dosen't
  want to lock the dmabufs.
  The unregistering should be performed after DMA or CPU has completed
  accesses to the dmabufs or when dma_buf_sync_lock() is failed.
 
  dma_buf_sync_put(a sync object, a dmabuf);
  dma_buf_sync_put_all(a sync object);
 
  The described steps may be summarized as:
  get - lock - CPU or DMA access to a buffer/s - unlock - put
 
  This framework includes the following two features.
  1. read (shared) and write (exclusive) locks - A task is required to
 declare
  the access type when the task tries to register a dmabuf;
  READ, WRITE, READ DMA, or WRITE DMA.
 
  The below is example codes,
  struct dmabuf_sync *sync;
 
  sync = dmabuf_sync_init(NULL, test sync);
 
  dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
  ...
 
  And the below can be used as access types:
  DMA_BUF_ACCESS_READ,
  - CPU will access a buffer for read.
  DMA_BUF_ACCESS_WRITE,
  - CPU will access a buffer for read or write.
  DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA,
  - DMA will access a buffer for read
  DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA,
  - DMA will access a buffer for read or write.
 
  2. Mandatory resource releasing - a task cannot hold a lock
 indefinitely.
  A task may never try to unlock a buffer after taking a lock to the
 buffer.
  In this case, a timer handler to the corresponding sync object is
 called
  in five (default) seconds and then the timed-out buffer is unlocked
 by work
  queue handler to avoid lockups and to enforce resources of the
buffer.
 
  The below is how to use:
  1. Allocate and Initialize a sync object:
  struct dmabuf_sync *sync;
 
  sync = dmabuf_sync_init(NULL, test sync);
  ...
 
  2. Add a dmabuf to the sync object when setting up dma buffer
 relevant
 registers:
  dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
  ...
 
  3. Lock all dmabufs of the sync object before DMA or CPU accesses
 the dmabufs:
  dmabuf_sync_lock(sync);
  ...
 
  4. Now CPU or DMA can access all dmabufs locked in step 3.
 
  5. Unlock all dmabufs added in a sync object after DMA