aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-12-13 11:13:40 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 04:08:47 -0500
commit63faabfd89f4db9862ae2a663193e511419c67eb (patch)
treedaf06328aa1e9e234cbb481e9a5f5c12a1818ac1
parent4138111a27859dcc56a5592c804dd16bb12a23d1 (diff)
[media] vb2: fix race condition between REQBUFS and QBUF/PREPARE_BUF
When preparing a buffer the queue lock is released for a short while if the memory mode is USERPTR (see __buf_prepare for the details), which would allow a race with a REQBUFS which can free the buffers. 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. If this happens, then the application does something really strange. The REQBUFS call can be retried safely, since this situation is transient. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index ca255da65108..a9a9c6a1c158 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -298,10 +298,28 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
298 * related information, if no buffers are left return the queue to an 298 * related information, if no buffers are left return the queue to an
299 * uninitialized state. Might be called even if the queue has already been freed. 299 * uninitialized state. Might be called even if the queue has already been freed.
300 */ 300 */
301static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) 301static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
302{ 302{
303 unsigned int buffer; 303 unsigned int buffer;
304 304
305 /*
306 * Sanity check: when preparing a buffer the queue lock is released for
307 * a short while (see __buf_prepare for the details), which would allow
308 * a race with a reqbufs which can call this function. Removing the
309 * buffers from underneath __buf_prepare is obviously a bad idea, so we
310 * check if any of the buffers is in the state PREPARING, and if so we
311 * just return -EAGAIN.
312 */
313 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
314 ++buffer) {
315 if (q->bufs[buffer] == NULL)
316 continue;
317 if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) {
318 dprintk(1, "reqbufs: preparing buffers, cannot free\n");
319 return -EAGAIN;
320 }
321 }
322
305 /* Call driver-provided cleanup function for each buffer, if provided */ 323 /* Call driver-provided cleanup function for each buffer, if provided */
306 if (q->ops->buf_cleanup) { 324 if (q->ops->buf_cleanup) {
307 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; 325 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
@@ -326,6 +344,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
326 if (!q->num_buffers) 344 if (!q->num_buffers)
327 q->memory = 0; 345 q->memory = 0;
328 INIT_LIST_HEAD(&q->queued_list); 346 INIT_LIST_HEAD(&q->queued_list);
347 return 0;
329} 348}
330 349
331/** 350/**
@@ -658,7 +677,9 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
658 return -EBUSY; 677 return -EBUSY;
659 } 678 }
660 679
661 __vb2_queue_free(q, q->num_buffers); 680 ret = __vb2_queue_free(q, q->num_buffers);
681 if (ret)
682 return ret;
662 683
663 /* 684 /*
664 * In case of REQBUFS(0) return immediately without calling 685 * In case of REQBUFS(0) return immediately without calling