mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
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>
This commit is contained in:
parent
1da4e16130
commit
03a979b74d
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user