Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: media videobuf2: Be more flexible on the number of queue stored buffers

Add 'max_num_buffers' field in vb2_queue struct to let drivers decide
how many buffers could be stored in a queue.
This require 'bufs' array to be allocated at queue init time and freed
when releasing the queue.
By default VB2_MAX_FRAME remains the limit.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Benjamin Gaignard and committed by
Mauro Carvalho Chehab
c838530d 4545ca51

+52 -12
+38 -8
drivers/media/common/videobuf2/videobuf2-core.c
··· 421 421 */ 422 422 static void vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *vb, unsigned int index) 423 423 { 424 - WARN_ON(index >= VB2_MAX_FRAME || q->bufs[index] || vb->vb2_queue); 424 + WARN_ON(index >= q->max_num_buffers || q->bufs[index] || vb->vb2_queue); 425 425 426 426 q->bufs[index] = vb; 427 427 vb->index = index; ··· 454 454 struct vb2_buffer *vb; 455 455 int ret; 456 456 457 - /* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */ 457 + /* 458 + * Ensure that the number of already queue + the number of buffers already 459 + * in the queue is below q->max_num_buffers 460 + */ 458 461 num_buffers = min_t(unsigned int, num_buffers, 459 - VB2_MAX_FRAME - q_num_buffers); 462 + q->max_num_buffers - q_num_buffers); 460 463 461 464 for (buffer = 0; buffer < num_buffers; ++buffer) { 462 465 /* Allocate vb2 buffer structures */ ··· 821 818 unsigned plane_sizes[VB2_MAX_PLANES] = { }; 822 819 bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT; 823 820 unsigned int i; 824 - int ret; 821 + int ret = 0; 825 822 826 823 if (q->streaming) { 827 824 dprintk(q, 1, "streaming active\n"); ··· 865 862 /* 866 863 * Make sure the requested values and current defaults are sane. 867 864 */ 868 - WARN_ON(q->min_buffers_needed > VB2_MAX_FRAME); 869 865 num_buffers = max_t(unsigned int, *count, q->min_buffers_needed); 870 - num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME); 866 + num_buffers = min_t(unsigned int, num_buffers, q->max_num_buffers); 871 867 memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); 872 868 /* 873 869 * Set this now to ensure that drivers see the correct q->memory value 874 870 * in the queue_setup op. 875 871 */ 876 872 mutex_lock(&q->mmap_lock); 873 + if (!q->bufs) 874 + q->bufs = kcalloc(q->max_num_buffers, sizeof(*q->bufs), GFP_KERNEL); 875 + if (!q->bufs) 876 + ret = -ENOMEM; 877 877 q->memory = memory; 878 878 mutex_unlock(&q->mmap_lock); 879 + if (ret) 880 + return ret; 879 881 set_queue_coherency(q, non_coherent_mem); 880 882 881 883 /* ··· 989 981 bool no_previous_buffers = !q_num_bufs; 990 982 int ret = 0; 991 983 992 - if (q_num_bufs == VB2_MAX_FRAME) { 984 + if (q->num_buffers == q->max_num_buffers) { 993 985 dprintk(q, 1, "maximum number of buffers already allocated\n"); 994 986 return -ENOBUFS; 995 987 } ··· 1006 998 */ 1007 999 mutex_lock(&q->mmap_lock); 1008 1000 q->memory = memory; 1001 + if (!q->bufs) 1002 + q->bufs = kcalloc(q->max_num_buffers, sizeof(*q->bufs), GFP_KERNEL); 1003 + if (!q->bufs) 1004 + ret = -ENOMEM; 1009 1005 mutex_unlock(&q->mmap_lock); 1006 + if (ret) 1007 + return ret; 1010 1008 q->waiting_for_buffers = !q->is_output; 1011 1009 set_queue_coherency(q, non_coherent_mem); 1012 1010 } else { ··· 1024 1010 return -EINVAL; 1025 1011 } 1026 1012 1027 - num_buffers = min(*count, VB2_MAX_FRAME - q_num_bufs); 1013 + num_buffers = min(*count, q->max_num_buffers - q_num_bufs); 1028 1014 1029 1015 if (requested_planes && requested_sizes) { 1030 1016 num_planes = requested_planes; ··· 2484 2470 /* 2485 2471 * Sanity check 2486 2472 */ 2473 + /* 2474 + * For drivers who don't support max_num_buffers ensure 2475 + * a backward compatibility. 2476 + */ 2477 + if (!q->max_num_buffers) 2478 + q->max_num_buffers = VB2_MAX_FRAME; 2479 + 2480 + /* The maximum is limited by offset cookie encoding pattern */ 2481 + q->max_num_buffers = min_t(unsigned int, q->max_num_buffers, MAX_BUFFER_INDEX); 2482 + 2487 2483 if (WARN_ON(!q) || 2488 2484 WARN_ON(!q->ops) || 2489 2485 WARN_ON(!q->mem_ops) || ··· 2501 2477 WARN_ON(!q->io_modes) || 2502 2478 WARN_ON(!q->ops->queue_setup) || 2503 2479 WARN_ON(!q->ops->buf_queue)) 2480 + return -EINVAL; 2481 + 2482 + if (WARN_ON(q->max_num_buffers > MAX_BUFFER_INDEX) || 2483 + WARN_ON(q->min_buffers_needed > q->max_num_buffers)) 2504 2484 return -EINVAL; 2505 2485 2506 2486 if (WARN_ON(q->requires_requests && !q->supports_requests)) ··· 2553 2525 __vb2_queue_cancel(q); 2554 2526 mutex_lock(&q->mmap_lock); 2555 2527 __vb2_queue_free(q, vb2_get_num_buffers(q)); 2528 + kfree(q->bufs); 2529 + q->bufs = NULL; 2556 2530 mutex_unlock(&q->mmap_lock); 2557 2531 } 2558 2532 EXPORT_SYMBOL_GPL(vb2_core_queue_release);
+3 -3
drivers/media/common/videobuf2/videobuf2-v4l2.c
··· 621 621 * This loop doesn't scale if there is a really large number of buffers. 622 622 * Maybe something more efficient will be needed in this case. 623 623 */ 624 - for (i = 0; i < vb2_get_num_buffers(q); i++) { 624 + for (i = 0; i < q->max_num_buffers; i++) { 625 625 vb2 = vb2_get_buffer(q, i); 626 626 627 627 if (!vb2) ··· 1136 1136 1137 1137 if (lock) 1138 1138 mutex_lock(lock); 1139 - if (file->private_data == vdev->queue->owner) { 1139 + if (!vdev->queue->owner || file->private_data == vdev->queue->owner) { 1140 1140 vb2_queue_release(vdev->queue); 1141 1141 vdev->queue->owner = NULL; 1142 1142 } ··· 1264 1264 */ 1265 1265 get_device(&vdev->dev); 1266 1266 video_unregister_device(vdev); 1267 - if (vdev->queue && vdev->queue->owner) { 1267 + if (vdev->queue) { 1268 1268 struct mutex *lock = vdev->queue->lock ? 1269 1269 vdev->queue->lock : vdev->lock; 1270 1270
+11 -1
include/media/videobuf2-core.h
··· 558 558 * @dma_dir: DMA mapping direction. 559 559 * @bufs: videobuf2 buffer structures 560 560 * @num_buffers: number of allocated/used buffers 561 + * @max_num_buffers: upper limit of number of allocated/used buffers. 562 + * If set to 0 v4l2 core will change it VB2_MAX_FRAME 563 + * for backward compatibility. 561 564 * @queued_list: list of buffers currently queued from userspace 562 565 * @queued_count: number of buffers queued and ready for streaming. 563 566 * @owned_by_drv_count: number of buffers owned by the driver ··· 622 619 struct mutex mmap_lock; 623 620 unsigned int memory; 624 621 enum dma_data_direction dma_dir; 625 - struct vb2_buffer *bufs[VB2_MAX_FRAME]; 622 + struct vb2_buffer **bufs; 626 623 unsigned int num_buffers; 624 + unsigned int max_num_buffers; 627 625 628 626 struct list_head queued_list; 629 627 unsigned int queued_count; ··· 1252 1248 static inline struct vb2_buffer *vb2_get_buffer(struct vb2_queue *q, 1253 1249 unsigned int index) 1254 1250 { 1251 + if (!q->bufs) 1252 + return NULL; 1253 + 1254 + if (index >= q->max_num_buffers) 1255 + return NULL; 1256 + 1255 1257 if (index < q->num_buffers) 1256 1258 return q->bufs[index]; 1257 1259 return NULL;