aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2014-01-29 11:36:53 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-11 05:56:40 -0400
commit256f3162c17595b3fde1c4f18389719e8a2952f5 (patch)
tree41fd2769da937f83ceb4df8a736236b4ac519e42
parent3f12e6b0d91a68f977f803ed03757a2fa9ba6b9f (diff)
[media] vb2: fix buf_init/buf_cleanup call sequences
Ensure that these ops are properly balanced. There are two scenarios: 1) for MMAP buf_init is called when the buffers are created and buf_cleanup must be called when the queue is finally freed. This scenario was always working. 2) for USERPTR and DMABUF it is more complicated. When a buffer is queued the code checks if all planes of this buffer have been acquired before. If that's the case, then only buf_prepare has to be called. Otherwise buf_cleanup needs to be called if the buffer was acquired before, then, once all changed planes have been (re)acquired, buf_init has to be called followed by buf_prepare. Should buf_prepare fail, then buf_cleanup must be called on the newly acquired planes to release them in. Finally, in __vb2_queue_free we have to check if the buffer was actually acquired before calling buf_cleanup. While that it always true for MMAP mode, it is not necessarily true for the other modes. E.g. if you just call REQBUFS and close the file handle, then buffers were never queued and so no buf_init was ever called. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c100
1 files changed, 67 insertions, 33 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 16ae66f5584f..6c33b788ecd7 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -377,8 +377,10 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
377 /* Call driver-provided cleanup function for each buffer, if provided */ 377 /* Call driver-provided cleanup function for each buffer, if provided */
378 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; 378 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
379 ++buffer) { 379 ++buffer) {
380 if (q->bufs[buffer]) 380 struct vb2_buffer *vb = q->bufs[buffer];
381 call_vb_qop(q->bufs[buffer], buf_cleanup, q->bufs[buffer]); 381
382 if (vb && vb->planes[0].mem_priv)
383 call_vb_qop(vb, buf_cleanup, vb);
382 } 384 }
383 385
384 /* Release video buffer memory */ 386 /* Release video buffer memory */
@@ -1196,6 +1198,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1196 unsigned int plane; 1198 unsigned int plane;
1197 int ret; 1199 int ret;
1198 int write = !V4L2_TYPE_IS_OUTPUT(q->type); 1200 int write = !V4L2_TYPE_IS_OUTPUT(q->type);
1201 bool reacquired = vb->planes[0].mem_priv == NULL;
1199 1202
1200 /* Copy relevant information provided by the userspace */ 1203 /* Copy relevant information provided by the userspace */
1201 __fill_vb2_buffer(vb, b, planes); 1204 __fill_vb2_buffer(vb, b, planes);
@@ -1221,12 +1224,16 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1221 } 1224 }
1222 1225
1223 /* Release previously acquired memory if present */ 1226 /* Release previously acquired memory if present */
1224 if (vb->planes[plane].mem_priv) 1227 if (vb->planes[plane].mem_priv) {
1228 if (!reacquired) {
1229 reacquired = true;
1230 call_vb_qop(vb, buf_cleanup, vb);
1231 }
1225 call_memop(vb, put_userptr, vb->planes[plane].mem_priv); 1232 call_memop(vb, put_userptr, vb->planes[plane].mem_priv);
1233 }
1226 1234
1227 vb->planes[plane].mem_priv = NULL; 1235 vb->planes[plane].mem_priv = NULL;
1228 vb->v4l2_planes[plane].m.userptr = 0; 1236 memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
1229 vb->v4l2_planes[plane].length = 0;
1230 1237
1231 /* Acquire each plane's memory */ 1238 /* Acquire each plane's memory */
1232 mem_priv = call_memop(vb, get_userptr, q->alloc_ctx[plane], 1239 mem_priv = call_memop(vb, get_userptr, q->alloc_ctx[plane],
@@ -1243,23 +1250,34 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1243 } 1250 }
1244 1251
1245 /* 1252 /*
1246 * Call driver-specific initialization on the newly acquired buffer,
1247 * if provided.
1248 */
1249 ret = call_vb_qop(vb, buf_init, vb);
1250 if (ret) {
1251 dprintk(1, "qbuf: buffer initialization failed\n");
1252 fail_vb_qop(vb, buf_init);
1253 goto err;
1254 }
1255
1256 /*
1257 * Now that everything is in order, copy relevant information 1253 * Now that everything is in order, copy relevant information
1258 * provided by userspace. 1254 * provided by userspace.
1259 */ 1255 */
1260 for (plane = 0; plane < vb->num_planes; ++plane) 1256 for (plane = 0; plane < vb->num_planes; ++plane)
1261 vb->v4l2_planes[plane] = planes[plane]; 1257 vb->v4l2_planes[plane] = planes[plane];
1262 1258
1259 if (reacquired) {
1260 /*
1261 * One or more planes changed, so we must call buf_init to do
1262 * the driver-specific initialization on the newly acquired
1263 * buffer, if provided.
1264 */
1265 ret = call_vb_qop(vb, buf_init, vb);
1266 if (ret) {
1267 dprintk(1, "qbuf: buffer initialization failed\n");
1268 fail_vb_qop(vb, buf_init);
1269 goto err;
1270 }
1271 }
1272
1273 ret = call_vb_qop(vb, buf_prepare, vb);
1274 if (ret) {
1275 dprintk(1, "qbuf: buffer preparation failed\n");
1276 fail_vb_qop(vb, buf_prepare);
1277 call_vb_qop(vb, buf_cleanup, vb);
1278 goto err;
1279 }
1280
1263 return 0; 1281 return 0;
1264err: 1282err:
1265 /* In case of errors, release planes that were already acquired */ 1283 /* In case of errors, release planes that were already acquired */
@@ -1279,8 +1297,13 @@ err:
1279 */ 1297 */
1280static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b) 1298static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1281{ 1299{
1300 int ret;
1301
1282 __fill_vb2_buffer(vb, b, vb->v4l2_planes); 1302 __fill_vb2_buffer(vb, b, vb->v4l2_planes);
1283 return 0; 1303 ret = call_vb_qop(vb, buf_prepare, vb);
1304 if (ret)
1305 fail_vb_qop(vb, buf_prepare);
1306 return ret;
1284} 1307}
1285 1308
1286/** 1309/**
@@ -1294,6 +1317,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1294 unsigned int plane; 1317 unsigned int plane;
1295 int ret; 1318 int ret;
1296 int write = !V4L2_TYPE_IS_OUTPUT(q->type); 1319 int write = !V4L2_TYPE_IS_OUTPUT(q->type);
1320 bool reacquired = vb->planes[0].mem_priv == NULL;
1297 1321
1298 /* Copy relevant information provided by the userspace */ 1322 /* Copy relevant information provided by the userspace */
1299 __fill_vb2_buffer(vb, b, planes); 1323 __fill_vb2_buffer(vb, b, planes);
@@ -1329,6 +1353,11 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1329 1353
1330 dprintk(1, "qbuf: buffer for plane %d changed\n", plane); 1354 dprintk(1, "qbuf: buffer for plane %d changed\n", plane);
1331 1355
1356 if (!reacquired) {
1357 reacquired = true;
1358 call_vb_qop(vb, buf_cleanup, vb);
1359 }
1360
1332 /* Release previously acquired memory if present */ 1361 /* Release previously acquired memory if present */
1333 __vb2_plane_dmabuf_put(vb, &vb->planes[plane]); 1362 __vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
1334 memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane)); 1363 memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
@@ -1364,23 +1393,33 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1364 } 1393 }
1365 1394
1366 /* 1395 /*
1367 * Call driver-specific initialization on the newly acquired buffer,
1368 * if provided.
1369 */
1370 ret = call_vb_qop(vb, buf_init, vb);
1371 if (ret) {
1372 dprintk(1, "qbuf: buffer initialization failed\n");
1373 fail_vb_qop(vb, buf_init);
1374 goto err;
1375 }
1376
1377 /*
1378 * Now that everything is in order, copy relevant information 1396 * Now that everything is in order, copy relevant information
1379 * provided by userspace. 1397 * provided by userspace.
1380 */ 1398 */
1381 for (plane = 0; plane < vb->num_planes; ++plane) 1399 for (plane = 0; plane < vb->num_planes; ++plane)
1382 vb->v4l2_planes[plane] = planes[plane]; 1400 vb->v4l2_planes[plane] = planes[plane];
1383 1401
1402 if (reacquired) {
1403 /*
1404 * Call driver-specific initialization on the newly acquired buffer,
1405 * if provided.
1406 */
1407 ret = call_vb_qop(vb, buf_init, vb);
1408 if (ret) {
1409 dprintk(1, "qbuf: buffer initialization failed\n");
1410 fail_vb_qop(vb, buf_init);
1411 goto err;
1412 }
1413 }
1414
1415 ret = call_vb_qop(vb, buf_prepare, vb);
1416 if (ret) {
1417 dprintk(1, "qbuf: buffer preparation failed\n");
1418 fail_vb_qop(vb, buf_prepare);
1419 call_vb_qop(vb, buf_cleanup, vb);
1420 goto err;
1421 }
1422
1384 return 0; 1423 return 0;
1385err: 1424err:
1386 /* In case of errors, release planes that were already acquired */ 1425 /* In case of errors, release planes that were already acquired */
@@ -1459,11 +1498,6 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1459 ret = -EINVAL; 1498 ret = -EINVAL;
1460 } 1499 }
1461 1500
1462 if (!ret) {
1463 ret = call_vb_qop(vb, buf_prepare, vb);
1464 if (ret)
1465 fail_vb_qop(vb, buf_prepare);
1466 }
1467 if (ret) 1501 if (ret)
1468 dprintk(1, "qbuf: buffer preparation failed: %d\n", ret); 1502 dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
1469 vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED; 1503 vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED;