From: Chanho Park Date: Thu, 7 Aug 2014 06:30:49 +0000 (+0900) Subject: Revert "vb2: fix buf_init/buf_cleanup call sequences" X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d1d8449fb19a3e7f7b3bca01ff0dafacc45d8b67;p=platform%2Fkernel%2Flinux-3.10.git Revert "vb2: fix buf_init/buf_cleanup call sequences" This reverts commit d872ce298fe725f050c3bbaa652a01a9b18e7a74. --- diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 6d34bb9..349e659 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; }