Instead of a static array change bufs to a dynamically allocated array. This will allow to store more video buffers if needed. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxxxxx> --- .../media/common/videobuf2/videobuf2-core.c | 38 +++++++++++-------- include/media/videobuf2-core.h | 6 +-- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 42fd3984c2bc..f1ff7af34a9f 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -409,18 +409,24 @@ static void init_buffer_cache_hints(struct vb2_queue *q, struct vb2_buffer *vb) * vb2_queue_add_buffer() - add a buffer to a queue * @q: pointer to &struct vb2_queue with videobuf2 queue. * @vb: pointer to &struct vb2_buffer to be added to the queue. - * @index: index where add vb2_buffer in the queue */ -static bool vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *vb, int index) +static bool vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *vb) { - if (index < VB2_MAX_FRAME && !q->bufs[index]) { - q->bufs[index] = vb; - vb->index = index; - vb->vb2_queue = q; - return true; - } + struct xa_limit range = { + .max = UINT_MAX, + .min = q->num_buffers, + }; + u32 index; + int ret; - return false; + ret = xa_alloc(&q->bufs, &index, vb, range, GFP_KERNEL); + if (ret) + return false; + + vb->index = index; + vb->vb2_queue = q; + + return true; } /** @@ -430,10 +436,8 @@ 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) { - q->bufs[vb->index] = NULL; - vb->vb2_queue = NULL; - } + xa_erase(&q->bufs, vb->index); + vb->vb2_queue = NULL; } /* @@ -474,7 +478,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, } call_void_bufop(q, init_buffer, vb); - if (!vb2_queue_add_buffer(q, vb, q->num_buffers + buffer)) { + if (!vb2_queue_add_buffer(q, vb)) { dprintk(q, 1, "failed adding buffer %d to queue\n", buffer); kfree(vb); break; @@ -930,7 +934,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, } mutex_lock(&q->mmap_lock); - q->num_buffers = allocated_buffers; + q->num_buffers += allocated_buffers; if (ret < 0) { /* @@ -2547,6 +2551,9 @@ int vb2_core_queue_init(struct vb2_queue *q) mutex_init(&q->mmap_lock); init_waitqueue_head(&q->done_wq); + xa_init_flags(&q->bufs, XA_FLAGS_ALLOC); + q->num_buffers = 0; + q->memory = VB2_MEMORY_UNKNOWN; if (q->buf_struct_size == 0) @@ -2574,6 +2581,7 @@ void vb2_core_queue_release(struct vb2_queue *q) mutex_lock(&q->mmap_lock); __vb2_queue_free(q, q->num_buffers); mutex_unlock(&q->mmap_lock); + xa_destroy(&q->bufs); } EXPORT_SYMBOL_GPL(vb2_core_queue_release); diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 4b6a9d2ea372..77921cf894ef 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -619,7 +619,7 @@ struct vb2_queue { struct mutex mmap_lock; unsigned int memory; enum dma_data_direction dma_dir; - struct vb2_buffer *bufs[VB2_MAX_FRAME]; + struct xarray bufs; unsigned int num_buffers; struct list_head queued_list; @@ -1239,9 +1239,7 @@ static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q) static inline struct vb2_buffer *vb2_get_buffer(struct vb2_queue *q, unsigned int index) { - if (index < q->num_buffers) - return q->bufs[index]; - return NULL; + return xa_load(&q->bufs, index); } /* -- 2.39.2