On 24/08/2023 11:21, Benjamin Gaignard wrote: > Add 'max_allowed_buffers' field in vb2_queue struct to let drivers decide > how many buffers could be stored in a queue. > This request '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@xxxxxxxxxxxxx> > --- > .../media/common/videobuf2/videobuf2-core.c | 25 +++++++++++++------ > include/media/videobuf2-core.h | 4 ++- > 2 files changed, 20 insertions(+), 9 deletions(-) > > diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c > index 8aa13591b782..70e36389b704 100644 > --- a/drivers/media/common/videobuf2/videobuf2-core.c > +++ b/drivers/media/common/videobuf2/videobuf2-core.c > @@ -411,7 +411,7 @@ static void init_buffer_cache_hints(struct vb2_queue *q, struct vb2_buffer *vb) > */ > static bool vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *vb, int index) Let's use 'unsigned int index' to avoid signedness issues. > { > - if (index < VB2_MAX_FRAME && !q->bufs[index]) { > + if (index < q->max_allowed_buffers && !q->bufs[index]) { > q->bufs[index] = vb; > vb->index = index; > vb->vb2_queue = q; > @@ -428,7 +428,7 @@ static bool vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *vb, int > */ > static void vb2_queue_remove_buffer(struct vb2_queue *q, struct vb2_buffer *vb) > { > - if (vb->index < VB2_MAX_FRAME) { > + if (vb->index < q->max_allowed_buffers) { > q->bufs[vb->index] = NULL; > vb->vb2_queue = NULL; > } > @@ -449,9 +449,9 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, > struct vb2_buffer *vb; > int ret; > > - /* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */ > + /* Ensure that q->num_buffers+num_buffers is below q->max_allowed_buffers */ > num_buffers = min_t(unsigned int, num_buffers, > - VB2_MAX_FRAME - q->num_buffers); > + q->max_allowed_buffers - q->num_buffers); > > for (buffer = 0; buffer < num_buffers; ++buffer) { > /* Allocate vb2 buffer structures */ > @@ -852,9 +852,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, > /* > * Make sure the requested values and current defaults are sane. > */ > - WARN_ON(q->min_buffers_needed > VB2_MAX_FRAME); > + WARN_ON(q->min_buffers_needed > q->max_allowed_buffers); > num_buffers = max_t(unsigned int, *count, q->min_buffers_needed); > - num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME); > + num_buffers = min_t(unsigned int, num_buffers, q->max_allowed_buffers); > memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); > /* > * Set this now to ensure that drivers see the correct q->memory value > @@ -970,7 +970,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, > bool no_previous_buffers = !q->num_buffers; > int ret; > > - if (q->num_buffers == VB2_MAX_FRAME) { > + if (q->num_buffers == q->max_allowed_buffers) { > dprintk(q, 1, "maximum number of buffers already allocated\n"); > return -ENOBUFS; > } > @@ -999,7 +999,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, > return -EINVAL; > } > > - num_buffers = min(*count, VB2_MAX_FRAME - q->num_buffers); > + num_buffers = min(*count, q->max_allowed_buffers - q->num_buffers); > > if (requested_planes && requested_sizes) { > num_planes = requested_planes; > @@ -2541,6 +2541,14 @@ int vb2_core_queue_init(struct vb2_queue *q) > > q->memory = VB2_MEMORY_UNKNOWN; > > + if (!q->max_allowed_buffers) > + q->max_allowed_buffers = VB2_MAX_FRAME; > + > + /* The maximum is limited by offset cookie encoding pattern */ > + q->max_allowed_buffers = min_t(unsigned int, q->max_allowed_buffers, MAX_BUFFERS); With the new MAX_BUFFERS define this probably will need to be adjusted. > + > + q->bufs = kcalloc(q->max_allowed_buffers, sizeof(*q->bufs), GFP_KERNEL); > + > if (q->buf_struct_size == 0) > q->buf_struct_size = sizeof(struct vb2_buffer); > > @@ -2565,6 +2573,7 @@ void vb2_core_queue_release(struct vb2_queue *q) > __vb2_queue_cancel(q); > mutex_lock(&q->mmap_lock); > __vb2_queue_free(q, q->num_buffers); > + kfree(q->bufs); > mutex_unlock(&q->mmap_lock); > } > EXPORT_SYMBOL_GPL(vb2_core_queue_release); > diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h > index 4b6a9d2ea372..ee9161b9fd64 100644 > --- a/include/media/videobuf2-core.h > +++ b/include/media/videobuf2-core.h > @@ -558,6 +558,7 @@ struct vb2_buf_ops { > * @dma_dir: DMA mapping direction. > * @bufs: videobuf2 buffer structures > * @num_buffers: number of allocated/used buffers > + * @max_allowed_buffers: upper limit of number of allocated/used buffers > * @queued_list: list of buffers currently queued from userspace > * @queued_count: number of buffers queued and ready for streaming. > * @owned_by_drv_count: number of buffers owned by the driver > @@ -619,8 +620,9 @@ struct vb2_queue { > struct mutex mmap_lock; > unsigned int memory; > enum dma_data_direction dma_dir; > - struct vb2_buffer *bufs[VB2_MAX_FRAME]; > + struct vb2_buffer **bufs; > unsigned int num_buffers; > + unsigned int max_allowed_buffers; > > struct list_head queued_list; > unsigned int queued_count; Regards, Hans