mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
ANDROID: GKI: dma-buf: Add support to set a destructor on a dma-buf
dma-buf destructor support is useful as it allows clients an opportunity to undo any attributes, such as security attributes, they have applied to the dma-buf's memory. The destructor is called when the dma-buf is freed, if the destructor returns an error the dma-buf's exporter release function is not called in order to ensure that memory which has not been properly cleaned up isn't returned to the system. Signed-off-by: Liam Mark <lmark@codeaurora.org> Signed-off-by: Swathi Sridhar <swatsrid@codeaurora.org> [surenb: cherry-picked from: 3af4db1543c9 "dma-buf: Add support to set a destructor on a dma-buf"] Bug: 150611569 Test: build Signed-off-by: Suren Baghdasaryan <surenb@google.com> Change-Id: I2d435b99fb9b1747bc1b32a4e0d484957614a5a3
This commit is contained in:
committed by
Suren Baghdasaryan
parent
cea23cb745
commit
253542f224
@@ -86,6 +86,7 @@ static struct file_system_type dma_buf_fs_type = {
|
||||
static int dma_buf_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dma_buf *dmabuf;
|
||||
int dtor_ret = 0;
|
||||
|
||||
if (!is_dma_buf_file(file))
|
||||
return -EINVAL;
|
||||
@@ -104,12 +105,19 @@ static int dma_buf_release(struct inode *inode, struct file *file)
|
||||
*/
|
||||
BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
|
||||
|
||||
dmabuf->ops->release(dmabuf);
|
||||
|
||||
mutex_lock(&db_list.lock);
|
||||
list_del(&dmabuf->list_node);
|
||||
mutex_unlock(&db_list.lock);
|
||||
|
||||
if (dmabuf->dtor)
|
||||
dtor_ret = dmabuf->dtor(dmabuf, dmabuf->dtor_data);
|
||||
|
||||
if (!dtor_ret)
|
||||
dmabuf->ops->release(dmabuf);
|
||||
else
|
||||
pr_warn_ratelimited("Leaking dmabuf %s because destructor failed error:%d\n",
|
||||
dmabuf->name, dtor_ret);
|
||||
|
||||
if (dmabuf->resv == (struct reservation_object *)&dmabuf[1])
|
||||
reservation_object_fini(dmabuf->resv);
|
||||
|
||||
|
||||
@@ -321,6 +321,18 @@ struct dma_buf_ops {
|
||||
int (*get_flags)(struct dma_buf *dmabuf, unsigned long *flags);
|
||||
};
|
||||
|
||||
/**
|
||||
* dma_buf_destructor - dma-buf destructor function
|
||||
* @dmabuf: [in] pointer to dma-buf
|
||||
* @dtor_data: [in] destructor data associated with this buffer
|
||||
*
|
||||
* The dma-buf destructor which is called when the dma-buf is freed.
|
||||
*
|
||||
* If the destructor returns an error the dma-buf's exporter release function
|
||||
* won't be called.
|
||||
*/
|
||||
typedef int (*dma_buf_destructor)(struct dma_buf *dmabuf, void *dtor_data);
|
||||
|
||||
/**
|
||||
* struct dma_buf - shared buffer object
|
||||
* @size: size of the buffer
|
||||
@@ -377,6 +389,8 @@ struct dma_buf {
|
||||
|
||||
__poll_t active;
|
||||
} cb_excl, cb_shared;
|
||||
dma_buf_destructor dtor;
|
||||
void *dtor_data;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -486,4 +500,18 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
|
||||
void *dma_buf_vmap(struct dma_buf *);
|
||||
void dma_buf_vunmap(struct dma_buf *, void *vaddr);
|
||||
int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags);
|
||||
|
||||
/**
|
||||
* dma_buf_set_destructor - set the dma-buf's destructor
|
||||
* @dmabuf: [in] pointer to dma-buf
|
||||
* @dma_buf_destructor [in] the destructor function
|
||||
* @dtor_data: [in] destructor data associated with this buffer
|
||||
*/
|
||||
static inline void dma_buf_set_destructor(struct dma_buf *dmabuf,
|
||||
dma_buf_destructor dtor,
|
||||
void *dtor_data)
|
||||
{
|
||||
dmabuf->dtor = dtor;
|
||||
dmabuf->dtor_data = dtor_data;
|
||||
}
|
||||
#endif /* __DMA_BUF_H__ */
|
||||
|
||||
Reference in New Issue
Block a user