Re: [PATCH v7 46/49] media: core: Free range of buffers

From: Hans Verkuil
Date: Tue Sep 19 2023 - 11:09:52 EST


On 14/09/2023 15:33, Benjamin Gaignard wrote:
> Improve __vb2_queue_free() and __vb2_free_mem() to free
> range of buffers and not only the last few buffers.
> Intoduce starting index to be flexible on range and change the loops
> according to this parameters.
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxxxxx>
> ---
> .../media/common/videobuf2/videobuf2-core.c | 30 +++++++++----------
> 1 file changed, 14 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
> index c5d4a388331b..88cdf4dcb07c 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -527,13 +527,12 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
> /*
> * __vb2_free_mem() - release all video buffer memory for a given queue
> */
> -static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
> +static void __vb2_free_mem(struct vb2_queue *q, unsigned int start, unsigned int count)
> {
> - unsigned int buffer = 0;
> - long i = q->max_allowed_buffers;
> + unsigned int i, buffer = 0;
> struct vb2_buffer *vb;
>
> - for (i = q->max_allowed_buffers; i >= 0 && buffer < buffers; i--) {
> + for (i = start; i < q->max_allowed_buffers && buffer < count; i++) {
> vb = vb2_get_buffer(q, i);
> if (!vb)
> continue;

Isn't there a 'buffer++' missing here?

> @@ -550,19 +549,18 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
> }
>
> /*
> - * __vb2_queue_free() - free buffers at the end of the queue - video memory and
> + * __vb2_queue_free() - free count buffers from start index of the queue - video memory and
> * related information, if no buffers are left return the queue to an
> * uninitialized state. Might be called even if the queue has already been freed.
> */
> -static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
> +static void __vb2_queue_free(struct vb2_queue *q, unsigned int start, unsigned int count)
> {
> - unsigned int buffer;
> - long i = q->max_allowed_buffers;
> + unsigned int i, buffer;
>
> lockdep_assert_held(&q->mmap_lock);
>
> /* Call driver-provided cleanup function for each buffer, if provided */
> - for (i = q->max_allowed_buffers, buffer = 0; i >= 0 && buffer < buffers; i--) {
> + for (i = start, buffer = 0; i < q->max_allowed_buffers && buffer < count; i++) {
> struct vb2_buffer *vb = vb2_get_buffer(q, i);
>
> if (!vb)

Same issue, 'buffer' is never incremented.

> @@ -574,7 +572,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
> }
>
> /* Release video buffer memory */
> - __vb2_free_mem(q, buffers);
> + __vb2_free_mem(q, start, count);
>
> #ifdef CONFIG_VIDEO_ADV_DEBUG
> /*
> @@ -659,8 +657,8 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
> #endif
>
> /* Free vb2 buffers */
> - for (i = q->max_allowed_buffers, buffer = 0; i > 0 && buffer < buffers; i--) {
> - struct vb2_buffer *vb = vb2_get_buffer(q, buffer);
> + for (i = start, buffer = 0; i < q->max_allowed_buffers && buffer < count; i++) {
> + struct vb2_buffer *vb = vb2_get_buffer(q, i);
>
> if (!vb)
> continue;

Ditto.

> @@ -884,7 +882,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
> * queued without ever calling STREAMON.
> */
> __vb2_queue_cancel(q);
> - __vb2_queue_free(q, q_num_bufs);
> + __vb2_queue_free(q, 0, q_num_bufs);
> mutex_unlock(&q->mmap_lock);
>
> /*
> @@ -995,7 +993,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
> * from already queued buffers and it will reset q->memory to
> * VB2_MEMORY_UNKNOWN.
> */
> - __vb2_queue_free(q, allocated_buffers);
> + __vb2_queue_free(q, 0, allocated_buffers);

Shouldn't we use 'first_index' here instead of '0'?

> mutex_unlock(&q->mmap_lock);
> return ret;
> }
> @@ -1135,7 +1133,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
> * from already queued buffers and it will reset q->memory to
> * VB2_MEMORY_UNKNOWN.
> */
> - __vb2_queue_free(q, allocated_buffers);
> + __vb2_queue_free(q, 0, allocated_buffers);

Ditto.

> mutex_unlock(&q->mmap_lock);
> return -ENOMEM;
> }
> @@ -2617,7 +2615,7 @@ void vb2_core_queue_release(struct vb2_queue *q)
> __vb2_cleanup_fileio(q);
> __vb2_queue_cancel(q);
> mutex_lock(&q->mmap_lock);
> - __vb2_queue_free(q, q->max_allowed_buffers);
> + __vb2_queue_free(q, 0, q->max_allowed_buffers);
> kfree(q->bufs);
> q->bufs = NULL;
> bitmap_free(q->bufs_map);

Regards,

Hans