summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2014-08-07 15:30:49 +0900
committerChanho Park <chanho61.park@samsung.com>2014-08-08 15:25:50 +0900
commitc51ee458af0272eeca244b058b08c3b806ff5987 (patch)
tree87f54b7cdfbeb90ab27c7e1b7809712f70630fb6
parenteba30f0a0ee2ddf12a97309f3859347440853494 (diff)
downloadlinux-3.10-c51ee458af0272eeca244b058b08c3b806ff5987.tar.gz
linux-3.10-c51ee458af0272eeca244b058b08c3b806ff5987.tar.bz2
linux-3.10-c51ee458af0272eeca244b058b08c3b806ff5987.zip
Revert "vb2: fix buf_init/buf_cleanup call sequences"
This reverts commit d872ce298fe725f050c3bbaa652a01a9b18e7a74.
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c65
1 files changed, 27 insertions, 38 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 6d34bb9df55..349e659d75f 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -437,14 +437,21 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
{
unsigned int buffer;
- /* Call driver-provided cleanup function for each buffer, if provided */
- if (q->ops->buf_cleanup) {
- for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
- ++buffer) {
- struct vb2_buffer *vb = q->bufs[buffer];
-
- if (vb && vb->planes[0].mem_priv)
- q->ops->buf_cleanup(vb);
+ /*
+ * Sanity check: when preparing a buffer the queue lock is released for
+ * a short while (see __buf_prepare for the details), which would allow
+ * a race with a reqbufs which can call this function. Removing the
+ * buffers from underneath __buf_prepare is obviously a bad idea, so we
+ * check if any of the buffers is in the state PREPARING, and if so we
+ * just return -EAGAIN.
+ */
+ for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+ ++buffer) {
+ if (q->bufs[buffer] == NULL)
+ continue;
+ if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) {
+ dprintk(1, "preparing buffers, cannot free\n");
+ return -EAGAIN;
}
}
@@ -1352,9 +1359,9 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
if (vb->planes[plane].mem_priv) {
if (!reacquired) {
reacquired = true;
- q->ops->buf_cleanup(vb);
+ call_void_vb_qop(vb, buf_cleanup, vb);
}
- call_memop(q, put_userptr, vb->planes[plane].mem_priv);
+ call_void_memop(vb, put_userptr, vb->planes[plane].mem_priv);
}
vb->planes[plane].mem_priv = NULL;
@@ -1386,17 +1393,17 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
* the driver-specific initialization on the newly acquired
* buffer, if provided.
*/
- ret = call_qop(q, buf_init, vb);
+ ret = call_vb_qop(vb, buf_init, vb);
if (ret) {
- dprintk(1, "qbuf: buffer initialization failed\n");
+ dprintk(1, "buffer initialization failed\n");
goto err;
}
}
- ret = call_qop(q, buf_prepare, vb);
+ ret = call_vb_qop(vb, buf_prepare, vb);
if (ret) {
- dprintk(1, "qbuf: buffer preparation failed\n");
- call_qop(q, buf_cleanup, vb);
+ dprintk(1, "buffer preparation failed\n");
+ call_void_vb_qop(vb, buf_cleanup, vb);
goto err;
}
@@ -1415,19 +1422,6 @@ err:
}
/**
- * __qbuf_mmap() - handle qbuf of an MMAP buffer
- */
-static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
-{
- int ret;
- struct vb2_queue *q = vb->vb2_queue;
-
- __fill_vb2_buffer(vb, b, vb->v4l2_planes);
- ret = call_qop(q, buf_prepare, vb);
- return ret;
-}
-
-/**
* __qbuf_dmabuf() - handle qbuf of a DMABUF buffer
*/
static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
@@ -1479,11 +1473,6 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
call_void_vb_qop(vb, buf_cleanup, vb);
}
- if (!reacquired) {
- reacquired = true;
- call_qop(q, buf_cleanup, vb);
- }
-
/* Release previously acquired memory if present */
__vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
@@ -1528,17 +1517,17 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
* Call driver-specific initialization on the newly acquired buffer,
* if provided.
*/
- ret = call_qop(q, buf_init, vb);
+ ret = call_vb_qop(vb, buf_init, vb);
if (ret) {
- dprintk(1, "qbuf: buffer initialization failed\n");
+ dprintk(1, "buffer initialization failed\n");
goto err;
}
}
- ret = call_qop(q, buf_prepare, vb);
+ ret = call_vb_qop(vb, buf_prepare, vb);
if (ret) {
- dprintk(1, "qbuf: buffer preparation failed\n");
- call_qop(q, buf_cleanup, vb);
+ dprintk(1, "buffer preparation failed\n");
+ call_void_vb_qop(vb, buf_cleanup, vb);
goto err;
}