diff options
author | Yunke Cao <yunkec@chromium.org> | 2024-08-14 11:06:43 +0900 |
---|---|---|
committer | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2024-08-14 10:05:32 +0200 |
commit | 03a979b74dc1ad5aeed8026a84d8771842cb1631 (patch) | |
tree | 2b0b11358f539afb70f3f255c4a1cd8fedd5d9c7 /drivers/media/common | |
parent | 1da4e16130d36c712e00bf045f09f194aac964b8 (diff) |
media: videobuf2-core: attach once if multiple planes share the same dbuf
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 <yunkec@chromium.org>
Acked-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Diffstat (limited to 'drivers/media/common')
-rw-r--r-- | drivers/media/common/videobuf2/videobuf2-core.c | 30 |
1 files changed, 26 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, |