Re: [PATCH v7 20/49] media: core: Rework how create_buf index returned value is computed

From: Hans Verkuil
Date: Tue Sep 19 2023 - 08:34:53 EST


This patch is too early, it should be moved to after 44/49.

Up to 44/49 (and excluding this patch), it is all internal rework that can
fairly easily be merged. This patch + 45-49 is where the actual delete_buf
implementation happens.

I would like to get all the prep work merged fairly soon (ideally for 6.7).
At that point we support more than 32 buffers, but not yet deleting buffers.

That last step can be worked on separately. But we're dealing with a much
shorter patch series at that point.

I'll get back to this patch later for a proper review.

Regards,

Hans

On 14/09/2023 15:32, Benjamin Gaignard wrote:
> When DELETE_BUFS will be introduced holes could created in bufs array.
> To be able to reuse these unused indices reworking how create->index
> is set is mandatory.
> Let __vb2_queue_alloc() decide which first index is correct and
> forward this to the caller.
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxxxxx>
> ---
> .../media/common/videobuf2/videobuf2-core.c | 24 +++++++++++++------
> .../media/common/videobuf2/videobuf2-v4l2.c | 17 +++++++------
> include/media/videobuf2-core.h | 4 +++-
> 3 files changed, 30 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
> index 70b6b8f8c390..a4c2fae8705d 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -443,15 +443,24 @@ static void vb2_queue_remove_buffer(struct vb2_queue *q, struct vb2_buffer *vb)
> */
> static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
> unsigned int num_buffers, unsigned int num_planes,
> - const unsigned plane_sizes[VB2_MAX_PLANES])
> + const unsigned plane_sizes[VB2_MAX_PLANES],
> + unsigned int *first)
> {
> unsigned int buffer, plane;
> struct vb2_buffer *vb;
> + unsigned long first_index;
> int ret;
>
> /* Ensure that q->num_buffers+num_buffers is below q->max_allowed_buffers */
> num_buffers = min_t(unsigned int, num_buffers,
> - q->max_allowed_buffers - q->num_buffers);
> + q->max_allowed_buffers - vb2_get_num_buffers(q));
> +
> + first_index = vb2_get_num_buffers(q);
> +
> + if (first_index >= q->max_allowed_buffers)
> + return 0;
> +
> + *first = first_index;
>
> for (buffer = 0; buffer < num_buffers; ++buffer) {
> /* Allocate vb2 buffer structures */
> @@ -472,7 +481,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, first_index++)) {
> dprintk(q, 1, "failed adding buffer %d to queue\n", buffer);
> kfree(vb);
> break;
> @@ -832,7 +841,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
> unsigned int q_num_bufs = vb2_get_num_buffers(q);
> unsigned plane_sizes[VB2_MAX_PLANES] = { };
> bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
> - unsigned int i;
> + unsigned int i, first;
> int ret = 0;
>
> if (q->streaming) {
> @@ -919,7 +928,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>
> /* Finally, allocate buffers and video memory */
> allocated_buffers =
> - __vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes);
> + __vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes, &first);
> if (allocated_buffers == 0) {
> dprintk(q, 1, "memory allocation failed\n");
> ret = -ENOMEM;
> @@ -993,7 +1002,8 @@ EXPORT_SYMBOL_GPL(vb2_core_reqbufs);
> int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
> unsigned int flags, unsigned int *count,
> unsigned int requested_planes,
> - const unsigned int requested_sizes[])
> + const unsigned int requested_sizes[],
> + unsigned int *first)
> {
> unsigned int num_planes = 0, num_buffers, allocated_buffers;
> unsigned plane_sizes[VB2_MAX_PLANES] = { };
> @@ -1055,7 +1065,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
>
> /* Finally, allocate buffers and video memory */
> allocated_buffers = __vb2_queue_alloc(q, memory, num_buffers,
> - num_planes, plane_sizes);
> + num_planes, plane_sizes, first);
> if (allocated_buffers == 0) {
> dprintk(q, 1, "memory allocation failed\n");
> ret = -ENOMEM;
> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 3eb707abc26b..a88abcea2921 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -762,7 +762,6 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
>
> fill_buf_caps(q, &create->capabilities);
> validate_memory_flags(q, create->memory, &create->flags);
> - create->index = q->num_buffers;
> if (create->count == 0)
> return ret != -EBUSY ? ret : 0;
>
> @@ -804,11 +803,16 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
> for (i = 0; i < requested_planes; i++)
> if (requested_sizes[i] == 0)
> return -EINVAL;
> - return ret ? ret : vb2_core_create_bufs(q, create->memory,
> - create->flags,
> - &create->count,
> - requested_planes,
> - requested_sizes);
> + if (ret)
> + return ret;
> +
> + ret = vb2_core_create_bufs(q, create->memory,
> + create->flags,
> + &create->count,
> + requested_planes,
> + requested_sizes,
> + &create->index);
> + return ret;
> }
> EXPORT_SYMBOL_GPL(vb2_create_bufs);
>
> @@ -1036,7 +1040,6 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv,
> int res = vb2_verify_memory_type(vdev->queue, p->memory,
> p->format.type);
>
> - p->index = vdev->queue->num_buffers;
> fill_buf_caps(vdev->queue, &p->capabilities);
> validate_memory_flags(vdev->queue, p->memory, &p->flags);
> /*
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index 1ecaf4b5a76f..19c93d8eb7c8 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -803,6 +803,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
> * @count: requested buffer count.
> * @requested_planes: number of planes requested.
> * @requested_sizes: array with the size of the planes.
> + * @first: index of the first created buffer
> *
> * Videobuf2 core helper to implement VIDIOC_CREATE_BUFS() operation. It is
> * called internally by VB2 by an API-specific handler, like
> @@ -819,7 +820,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
> int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
> unsigned int flags, unsigned int *count,
> unsigned int requested_planes,
> - const unsigned int requested_sizes[]);
> + const unsigned int requested_sizes[],
> + unsigned int *first);
>
> /**
> * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace