This is an automatic generated email to let you know that the following patch 
were queued:

Subject: media: videobuf2-core: attach once if multiple planes share the same 
dbuf
Author:  Yunke Cao <yun...@chromium.org>
Date:    Wed Aug 14 11:06:43 2024 +0900

When multiple planes use the same dma buf, each plane will have its own dma
buf attachment and mapping. It is a waste of IOVA space.

This patch adds a dbuf_duplicated boolean in vb2_plane. If a plane's dbuf
is the same as an existing plane, do not create another attachment and
mapping.

Signed-off-by: Yunke Cao <yun...@chromium.org>
Acked-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>

 drivers/media/common/videobuf2/videobuf2-core.c | 30 +++++++++++++++++++++----
 include/media/videobuf2-core.h                  |  3 +++
 2 files changed, 29 insertions(+), 4 deletions(-)

---

diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
b/drivers/media/common/videobuf2/videobuf2-core.c
index e6af963307e3..500a4e0c84ab 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -303,10 +303,13 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, 
struct vb2_plane *p)
        if (!p->mem_priv)
                return;
 
-       if (p->dbuf_mapped)
-               call_void_memop(vb, unmap_dmabuf, p->mem_priv);
+       if (!p->dbuf_duplicated) {
+               if (p->dbuf_mapped)
+                       call_void_memop(vb, unmap_dmabuf, p->mem_priv);
+
+               call_void_memop(vb, detach_dmabuf, p->mem_priv);
+       }
 
-       call_void_memop(vb, detach_dmabuf, p->mem_priv);
        dma_buf_put(p->dbuf);
        p->mem_priv = NULL;
        p->dbuf = NULL;
@@ -315,6 +318,7 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, 
struct vb2_plane *p)
        p->length = 0;
        p->m.fd = 0;
        p->data_offset = 0;
+       p->dbuf_duplicated = false;
 }
 
 /*
@@ -1379,7 +1383,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb)
        struct vb2_plane planes[VB2_MAX_PLANES];
        struct vb2_queue *q = vb->vb2_queue;
        void *mem_priv;
-       unsigned int plane;
+       unsigned int plane, i;
        int ret = 0;
        bool reacquired = vb->planes[0].mem_priv == NULL;
 
@@ -1432,6 +1436,24 @@ static int __prepare_dmabuf(struct vb2_buffer *vb)
                }
 
                for (plane = 0; plane < vb->num_planes; ++plane) {
+                       /*
+                        * This is an optimization to reduce dma_buf 
attachment/mapping.
+                        * When the same dma_buf is used for multiple planes, 
there is no need
+                        * to create duplicated attachments.
+                        */
+                       for (i = 0; i < plane; ++i) {
+                               if (planes[plane].dbuf == vb->planes[i].dbuf &&
+                                   q->alloc_devs[plane] == q->alloc_devs[i]) {
+                                       vb->planes[plane].dbuf_duplicated = 
true;
+                                       vb->planes[plane].dbuf = 
vb->planes[i].dbuf;
+                                       vb->planes[plane].mem_priv = 
vb->planes[i].mem_priv;
+                                       break;
+                               }
+                       }
+
+                       if (vb->planes[plane].dbuf_duplicated)
+                               continue;
+
                        /* Acquire each plane's memory */
                        mem_priv = call_ptr_memop(attach_dmabuf,
                                                  vb,
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 955237ac503d..9b02aeba4108 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -154,6 +154,8 @@ struct vb2_mem_ops {
  * @mem_priv:  private data with this plane.
  * @dbuf:      dma_buf - shared buffer object.
  * @dbuf_mapped:       flag to show whether dbuf is mapped or not
+ * @dbuf_duplicated:   boolean to show whether dbuf is duplicated with a
+ *             previous plane of the buffer.
  * @bytesused: number of bytes occupied by data in the plane (payload).
  * @length:    size of this plane (NOT the payload) in bytes. The maximum
  *             valid size is MAX_UINT - PAGE_SIZE.
@@ -179,6 +181,7 @@ struct vb2_plane {
        void                    *mem_priv;
        struct dma_buf          *dbuf;
        unsigned int            dbuf_mapped;
+       bool                    dbuf_duplicated;
        unsigned int            bytesused;
        unsigned int            length;
        unsigned int            min_length;

Reply via email to