diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-08-19 21:39:36 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-11-21 19:12:20 +0900 |
commit | 80ce1d4b77d71a101f252ac24c5a6682cb74c15f (patch) | |
tree | d6497ea22d33750451f752fc6830f822b5efb598 /Documentation | |
parent | 15a9e0467a7ee6a9e8ecfbf4e851ea768010ab5e (diff) | |
download | linux-3.10-80ce1d4b77d71a101f252ac24c5a6682cb74c15f.tar.gz linux-3.10-80ce1d4b77d71a101f252ac24c5a6682cb74c15f.tar.bz2 linux-3.10-80ce1d4b77d71a101f252ac24c5a6682cb74c15f.zip |
Revert "dmabuf-sync: update it to patch v8"
This reverts commit cf7e07ce2d9843105d2ed8f9d30ee66c06d83bb0.
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/dma-buf-sync.txt | 100 |
1 files changed, 52 insertions, 48 deletions
diff --git a/Documentation/dma-buf-sync.txt b/Documentation/dma-buf-sync.txt index 5945c8aed8f..442775995ee 100644 --- a/Documentation/dma-buf-sync.txt +++ b/Documentation/dma-buf-sync.txt @@ -53,6 +53,50 @@ What is the best way to solve these buffer synchronization issues? Now we have already been using the dma-buf to share one buffer with other drivers. +How we can utilize multi threads for more performance? + DMA and CPU works individually. So CPU could perform other works while + DMA are performing some works, and vise versa. + However, in the conventional way, that is not easy to do so because + DMA operation is depend on CPU operation, and vice versa. + + Conventional way: + User Kernel + --------------------------------------------------------------------- + CPU writes something to src + send the src to driver-------------------------> + update DMA register + request DMA start(1)---------------------------> + DMA start + <---------completion signal(2)---------- + CPU accesses dst + + (1) Request DMA start after the CPU access to src buffer is completed. + (2) Access dst buffer after DMA access to the dst buffer is completed. + +On the other hand, if there is something to control buffer access between CPU +and DMA? The below shows that: + + User(thread a) User(thread b) Kernel + --------------------------------------------------------------------- + send a src to driver----------------------------------> + update DMA register + lock the src + request DMA start(1)----------> + CPU acccess to src + unlock the src lock src and dst + DMA start + <-------------completion signal(2)------------- + lock dst DMA completion + CPU access to dst unlock src and dst + unlock DST + + (1) Try to start DMA operation while CPU is accessing the src buffer. + (2) Try CPU access to dst buffer while DMA is accessing the dst buffer. + + In the same way, we could reduce hand shaking overhead between + two processes when those processes need to share a shared buffer. + There may be other cases that we could reduce overhead as well. + Basic concept ------------- @@ -128,12 +172,10 @@ DMA_BUF_ACCESS_DMA_W - DMA will access a buffer for read or write. Generic user interfaces ----------------------- -And this framework includes fcntl[3] and select system calls as interfaces -exported to user. As you know, user sees a buffer object as a dma-buf file -descriptor. fcntl() call with the file descriptor means to lock some buffer -region being managed by the dma-buf object. And select call with the file -descriptor means to poll the completion event of CPU or DMA access to -the dma-buf. +And this framework includes fcntl system call[3] as interfaces exported +to user. As you know, user sees a buffer object as a dma-buf file descriptor. +So fcntl() call with the file descriptor means to lock some buffer region being +managed by the dma-buf object. API set @@ -142,14 +184,10 @@ API set bool is_dmabuf_sync_supported(void) - Check if dmabuf sync is supported or not. -struct dmabuf_sync *dmabuf_sync_init(const char *name, - struct dmabuf_sync_priv_ops *ops, - void priv*) +struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name) - Allocate and initialize a new sync object. The caller can get a new - sync object for buffer synchronization. ops is used for device driver - to clean up its own sync object. For this, each device driver should - implement a free callback. priv is used for device driver to get its - device context when free callback is called. + sync object for buffer synchronization. priv is used to set caller's + private data and name is the name of sync object. void dmabuf_sync_fini(struct dmabuf_sync *sync) - Release all resources to the sync object. @@ -197,25 +235,9 @@ Tutorial for device driver -------------------------- 1. Allocate and Initialize a sync object: - static void xxx_dmabuf_sync_free(void *priv) - { - struct xxx_context *ctx = priv; - - if (!ctx) - return; - - ctx->sync = NULL; - } - ... - - static struct dmabuf_sync_priv_ops driver_specific_ops = { - .free = xxx_dmabuf_sync_free, - }; - ... - struct dmabuf_sync *sync; - sync = dmabuf_sync_init("test sync", &driver_specific_ops, ctx); + sync = dmabuf_sync_init(NULL, "test sync"); ... 2. Add a dmabuf to the sync object when setting up dma buffer relevant registers: @@ -239,8 +261,6 @@ Tutorial for device driver Tutorial for user application ----------------------------- -fcntl system call: - struct flock filelock; 1. Lock a dma buf: @@ -264,22 +284,6 @@ fcntl system call: detail, please refer to [3] -select system call: - - fd_set wdfs or rdfs; - - FD_ZERO(&wdfs or &rdfs); - FD_SET(fd, &wdfs or &rdfs); - - select(fd + 1, &rdfs, NULL, NULL, NULL); - or - select(fd + 1, NULL, &wdfs, NULL, NULL); - - Every time select system call is called, a caller will wait for - the completion of DMA or CPU access to a shared buffer if there - is someone accessing the shared buffer. If no anyone then select - system call will be returned at once. - References: [1] http://lwn.net/Articles/470339/ [2] https://patchwork.kernel.org/patch/2625361/ |