[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240129063025.29251-7-yunfei.dong@mediatek.com>
Date: Mon, 29 Jan 2024 14:30:09 +0800
From: Yunfei Dong <yunfei.dong@...iatek.com>
To: Jeffrey Kardatzke <jkardatzke@...gle.com>,
Nícolas F . R . A . Prado
<nfraprado@...labora.com>, Nicolas Dufresne <nicolas.dufresne@...labora.com>,
Hans Verkuil <hverkuil-cisco@...all.nl>, AngeloGioacchino Del Regno
<angelogioacchino.delregno@...labora.com>, Benjamin Gaignard
<benjamin.gaignard@...labora.com>, Nathan Hebert <nhebert@...omium.org>
CC: Chen-Yu Tsai <wenst@...omium.org>, Yong Wu <yong.wu@...iatek.com>, Hsin-Yi
Wang <hsinyi@...omium.org>, Fritz Koenig <frkoenig@...omium.org>, Daniel
Vetter <daniel@...ll.ch>, Steve Cho <stevecho@...omium.org>, Yunfei Dong
<yunfei.dong@...iatek.com>, Sumit Semwal <sumit.semwal@...aro.org>, Brian
Starkey <Brian.Starkey@....com>, John Stultz <jstultz@...gle.com>, "T . J .
Mercier" <tjmercier@...gle.com>, Christian König
<christian.koenig@....com>, Matthias Brugger <matthias.bgg@...il.com>,
<dri-devel@...ts.freedesktop.org>, <linaro-mm-sig@...ts.linaro.org>,
<devicetree@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
<linux-arm-kernel@...ts.infradead.org>, <linux-mediatek@...ts.infradead.org>,
<Project_Global_Chrome_Upstream_Group@...iatek.com>
Subject: [PATCH v4,06/22] dma-heap: Add proper kref handling on dma-buf heaps
From: John Stultz <jstultz@...gle.com>
Add proper refcounting on the dma_heap structure.
While existing heaps are built-in, we may eventually
have heaps loaded from modules, and we'll need to be
able to properly handle the references to the heaps
Signed-off-by: John Stultz <jstultz@...gle.com>
Signed-off-by: T.J. Mercier <tjmercier@...gle.com>
Signed-off-by: Yong Wu <yong.wu@...iatek.com>
[Yong: Just add comment for "minor" and "refcount"]
Signed-off-by: Yunfei Dong <yunfei.dong@...iatek.com>
---
drivers/dma-buf/dma-heap.c | 29 +++++++++++++++++++++++++++++
include/linux/dma-heap.h | 2 ++
2 files changed, 31 insertions(+)
diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 22f6c193db0d..97025ee8500f 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -11,6 +11,7 @@
#include <linux/dma-buf.h>
#include <linux/dma-heap.h>
#include <linux/err.h>
+#include <linux/kref.h>
#include <linux/list.h>
#include <linux/nospec.h>
#include <linux/syscalls.h>
@@ -30,6 +31,7 @@
* @heap_devt: heap device node
* @list: list head connecting to list of heaps
* @heap_cdev: heap char device
+ * @refcount: reference counter for this heap device
*
* Represents a heap of memory from which buffers can be made.
*/
@@ -40,6 +42,7 @@ struct dma_heap {
dev_t heap_devt;
struct list_head list;
struct cdev heap_cdev;
+ struct kref refcount;
};
static LIST_HEAD(heap_list);
@@ -240,6 +243,7 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
if (!heap)
return ERR_PTR(-ENOMEM);
+ kref_init(&heap->refcount);
heap->name = exp_info->name;
heap->ops = exp_info->ops;
heap->priv = exp_info->priv;
@@ -304,6 +308,31 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
return err_ret;
}
+static void dma_heap_release(struct kref *ref)
+{
+ struct dma_heap *heap = container_of(ref, struct dma_heap, refcount);
+ unsigned int minor = MINOR(heap->heap_devt);
+
+ mutex_lock(&heap_list_lock);
+ list_del(&heap->list);
+ mutex_unlock(&heap_list_lock);
+
+ device_destroy(dma_heap_class, heap->heap_devt);
+ cdev_del(&heap->heap_cdev);
+ xa_erase(&dma_heap_minors, minor);
+
+ kfree(heap);
+}
+
+/**
+ * dma_heap_put - drops a reference to a dmabuf heap, potentially freeing it
+ * @heap: DMA-Heap whose reference count to decrement
+ */
+void dma_heap_put(struct dma_heap *heap)
+{
+ kref_put(&heap->refcount, dma_heap_release);
+}
+
static char *dma_heap_devnode(const struct device *dev, umode_t *mode)
{
return kasprintf(GFP_KERNEL, "dma_heap/%s", dev_name(dev));
diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h
index fbe86ec889a8..d57593f8a1bc 100644
--- a/include/linux/dma-heap.h
+++ b/include/linux/dma-heap.h
@@ -46,4 +46,6 @@ const char *dma_heap_get_name(struct dma_heap *heap);
struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info);
+void dma_heap_put(struct dma_heap *heap);
+
#endif /* _DMA_HEAPS_H */
--
2.18.0
Powered by blists - more mailing lists