[PATCH v3 02/11] media: videobuf2: Use Xarray instead of static buffers array

Benjamin Gaignard
2023-06-22T13:14:03Z

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@collabora.com>
---
.../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