mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-06 22:05:22 +02:00
media: videobuf2-core: release all planes first in __prepare_dmabuf()
In the existing implementation, validating planes, checking if the planes changed, releasing previous planes and reaquiring new planes all happens in the same for loop. Split the for loop into 3 parts 1. In the first for loop, validate planes and check if planes changed. 2. Call __vb2_buf_dmabuf_put() to release all planes. 3. In the second for loop, reaquire new planes. 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
6a9c97ab6b
commit
95af7c00f3
|
@ -1387,11 +1387,13 @@ static int __prepare_dmabuf(struct vb2_buffer *vb)
|
|||
for (plane = 0; plane < vb->num_planes; ++plane) {
|
||||
struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);
|
||||
|
||||
planes[plane].dbuf = dbuf;
|
||||
|
||||
if (IS_ERR_OR_NULL(dbuf)) {
|
||||
dprintk(q, 1, "invalid dmabuf fd for plane %d\n",
|
||||
plane);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
goto err_put_planes;
|
||||
}
|
||||
|
||||
/* use DMABUF size if length is not provided */
|
||||
|
@ -1402,76 +1404,68 @@ static int __prepare_dmabuf(struct vb2_buffer *vb)
|
|||
dprintk(q, 1, "invalid dmabuf length %u for plane %d, minimum length %u\n",
|
||||
planes[plane].length, plane,
|
||||
vb->planes[plane].min_length);
|
||||
dma_buf_put(dbuf);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
goto err_put_planes;
|
||||
}
|
||||
|
||||
/* Skip the plane if already verified */
|
||||
if (dbuf == vb->planes[plane].dbuf &&
|
||||
vb->planes[plane].length == planes[plane].length) {
|
||||
dma_buf_put(dbuf);
|
||||
vb->planes[plane].length == planes[plane].length)
|
||||
continue;
|
||||
}
|
||||
|
||||
dprintk(q, 3, "buffer for plane %d changed\n", plane);
|
||||
|
||||
if (!reacquired) {
|
||||
reacquired = true;
|
||||
vb->copied_timestamp = 0;
|
||||
call_void_vb_qop(vb, buf_cleanup, vb);
|
||||
}
|
||||
|
||||
/* Release previously acquired memory if present */
|
||||
__vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
|
||||
|
||||
/* Acquire each plane's memory */
|
||||
mem_priv = call_ptr_memop(attach_dmabuf,
|
||||
vb,
|
||||
q->alloc_devs[plane] ? : q->dev,
|
||||
dbuf,
|
||||
planes[plane].length);
|
||||
if (IS_ERR(mem_priv)) {
|
||||
dprintk(q, 1, "failed to attach dmabuf\n");
|
||||
ret = PTR_ERR(mem_priv);
|
||||
dma_buf_put(dbuf);
|
||||
goto err;
|
||||
}
|
||||
|
||||
vb->planes[plane].dbuf = dbuf;
|
||||
vb->planes[plane].mem_priv = mem_priv;
|
||||
}
|
||||
|
||||
/*
|
||||
* This pins the buffer(s) with dma_buf_map_attachment()). It's done
|
||||
* here instead just before the DMA, while queueing the buffer(s) so
|
||||
* userspace knows sooner rather than later if the dma-buf map fails.
|
||||
*/
|
||||
for (plane = 0; plane < vb->num_planes; ++plane) {
|
||||
if (vb->planes[plane].dbuf_mapped)
|
||||
continue;
|
||||
|
||||
ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);
|
||||
if (ret) {
|
||||
dprintk(q, 1, "failed to map dmabuf for plane %d\n",
|
||||
plane);
|
||||
goto err;
|
||||
}
|
||||
vb->planes[plane].dbuf_mapped = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that everything is in order, copy relevant information
|
||||
* provided by userspace.
|
||||
*/
|
||||
for (plane = 0; plane < vb->num_planes; ++plane) {
|
||||
vb->planes[plane].bytesused = planes[plane].bytesused;
|
||||
vb->planes[plane].length = planes[plane].length;
|
||||
vb->planes[plane].m.fd = planes[plane].m.fd;
|
||||
vb->planes[plane].data_offset = planes[plane].data_offset;
|
||||
reacquired = true;
|
||||
}
|
||||
|
||||
if (reacquired) {
|
||||
if (vb->planes[0].mem_priv) {
|
||||
vb->copied_timestamp = 0;
|
||||
call_void_vb_qop(vb, buf_cleanup, vb);
|
||||
__vb2_buf_dmabuf_put(vb);
|
||||
}
|
||||
|
||||
for (plane = 0; plane < vb->num_planes; ++plane) {
|
||||
/* Acquire each plane's memory */
|
||||
mem_priv = call_ptr_memop(attach_dmabuf,
|
||||
vb,
|
||||
q->alloc_devs[plane] ? : q->dev,
|
||||
planes[plane].dbuf,
|
||||
planes[plane].length);
|
||||
if (IS_ERR(mem_priv)) {
|
||||
dprintk(q, 1, "failed to attach dmabuf\n");
|
||||
ret = PTR_ERR(mem_priv);
|
||||
goto err_put_vb2_buf;
|
||||
}
|
||||
|
||||
vb->planes[plane].dbuf = planes[plane].dbuf;
|
||||
vb->planes[plane].mem_priv = mem_priv;
|
||||
|
||||
/*
|
||||
* This pins the buffer(s) with dma_buf_map_attachment()). It's done
|
||||
* here instead just before the DMA, while queueing the buffer(s) so
|
||||
* userspace knows sooner rather than later if the dma-buf map fails.
|
||||
*/
|
||||
ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);
|
||||
if (ret) {
|
||||
dprintk(q, 1, "failed to map dmabuf for plane %d\n",
|
||||
plane);
|
||||
goto err_put_vb2_buf;
|
||||
}
|
||||
vb->planes[plane].dbuf_mapped = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that everything is in order, copy relevant information
|
||||
* provided by userspace.
|
||||
*/
|
||||
for (plane = 0; plane < vb->num_planes; ++plane) {
|
||||
vb->planes[plane].bytesused = planes[plane].bytesused;
|
||||
vb->planes[plane].length = planes[plane].length;
|
||||
vb->planes[plane].m.fd = planes[plane].m.fd;
|
||||
vb->planes[plane].data_offset = planes[plane].data_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call driver-specific initialization on the newly acquired buffer,
|
||||
* if provided.
|
||||
|
@ -1479,19 +1473,28 @@ static int __prepare_dmabuf(struct vb2_buffer *vb)
|
|||
ret = call_vb_qop(vb, buf_init, vb);
|
||||
if (ret) {
|
||||
dprintk(q, 1, "buffer initialization failed\n");
|
||||
goto err;
|
||||
goto err_put_vb2_buf;
|
||||
}
|
||||
} else {
|
||||
for (plane = 0; plane < vb->num_planes; ++plane)
|
||||
dma_buf_put(planes[plane].dbuf);
|
||||
}
|
||||
|
||||
ret = call_vb_qop(vb, buf_prepare, vb);
|
||||
if (ret) {
|
||||
dprintk(q, 1, "buffer preparation failed\n");
|
||||
call_void_vb_qop(vb, buf_cleanup, vb);
|
||||
goto err;
|
||||
goto err_put_vb2_buf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
|
||||
err_put_planes:
|
||||
for (plane = 0; plane < vb->num_planes; ++plane) {
|
||||
if (!IS_ERR_OR_NULL(planes[plane].dbuf))
|
||||
dma_buf_put(planes[plane].dbuf);
|
||||
}
|
||||
err_put_vb2_buf:
|
||||
/* In case of errors, release planes that were already acquired */
|
||||
__vb2_buf_dmabuf_put(vb);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user