Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework
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
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/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
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
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
+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
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
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